本文主要介绍基于51单片机实现的人体身高体重BMI指数检测健康秤称设计(程序、电路图、PCB以及文档说明书见文末链接)
一、简介
本系统由STC89C52单片机、LCD1602液晶显示、按键、超声波测距、HX711称重传感器模块(0-1000KG)以及模块电源组成。
主要功能介绍如下:
(1)称重传感器进行人体称重,测量范围0-1000kg,实时显示在液晶上。
(2)超声波测量的距离,测量范围0-5m,显示在液晶上。
(3)按键按下,进行BMI值进行计算。BMI值等于重量除以身高的平方。
如果BMI低于18.5,则显示"过轻"字样、如果BMI在18.5-23.9之间,则显示"正常"字样、如果BMI高于24,则显示"过重"字样。
注意:称重/压力传感器上电时,保持没有重物,去皮功能。
二、详细设计方案
(1)电路图设计
单片机最小系统选用STC89C52单片机;称重传感器选用YZC-516C-1T称重传感器模块,并通过HX711专用的24位精度AD转换模块转换后传给单片机系统;身高测量选用的是HC-SR04超声传感器,基于超声波测距功能实现身高测量;
此外还包括LCD1602液晶显示电路、电源供电电路等,具体如下图所示
(2)PCB设计
PCB设计方案如下图所示,使用的是Altium designer软件
(3)源程序代码
c
void main(void)
{
TMOD|=0x01; //设T0为方式1,GATE=1;
TH0=0;
TL0=0;
TIM2Inital(); //定时器初始化
UART_Init(); //初始化串口
// led_gl = 0;DelayMs(100);led_gl = 1;
LCD_Init();//初始化液晶显示
LCD_Clear();
LCD_Write_String(0,0,"Init.. ");
i = 5;startCheckWireLess=1;//启动检测无线
while(i-- && wirelessFlag == 0) //此时判断是无线类型
{UartSendString("ATE0\r\n"); DelayMs(100);}
startCheckWireLess=0;
if(wirelessFlag == 1)
{
i = 50;while(i--){DelayMs(100);}//wifi启动 必须延时一定时间
// UartSendString("AT+CWMODE_CUR=3\r\n");// 设置模式
// DelayMs(50);
// UartSendString("AT+CWSAP=\"AUAISOUT000\",\"\",1,0\r\n");//设置网络名字及密码
// DelayMs(50);
// UartSendString("AT+CIPAP_CUR=\"10.10.10.11\"\r\n");//设置本机ip
// DelayMs(50);
// UartSendString("AT+CIPMODE=0\r\n");//设置ip模式
// DelayMs(50);
UartSendString("AT+CIPMUX=1\r\n");//打开多连接
DelayMs(50);
UartSendString("AT+CIPSERVER=1,8080\r\n");//启动端口号
DelayMs(50); //以上作为服务端 局域网
}
Weight_Maopi = HX711_Read(); //读取去皮重量
DelayMs(10);
Weight_Maopi = HX711_Read();
while(1)
{
if(disFlag == 1) //更新显示
{
disFlag = 0;
csbDelater++; //声音处理计数
if(csbDelater>=4) //声音处理
{
csbDelater = 0;
Trip=1; //启动一次模块 //不可以使用其他终端 容易造成死循环
DelayUs2x(4);
Trip=0;
while(!Echo); //当RX为零时等待
TR0=1; //开启计数
while(Echo); //当RX为1计数并等待
TR0=0;
JlCoun=(long)(TH0*256+TL0); //计算数据
JuLi=(float)(JlCoun*17)/100.0*1.08/1000; //算出来是m 因为是11.0592M的晶振 11.0592/12
if(JuLi > 9.99) JuLi = 8.88;//数据超出测量范围
}
readWeightFlag++;//计数
if(readWeightFlag > 3)//达到一定时间 读取重量
{
readWeightFlag = 0;//清空标志
Weight_Shiwu = HX711_Read(); //读取实物重量
Weight_Shiwu = Weight_Maopi - Weight_Shiwu;// Weight_Shiwu - Weight_Maopi; //获取净重
if(Weight_Shiwu > 10) //过滤错误
{
Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/430); //kg计算实物的实际重量 该称重值 针对0-1000kg的传感器
}
else
{ Weight_Shiwu = 0;}
if(Weight_Shiwu < 50 ) Weight_Shiwu = 0; //体重过低清空
}
if(key == 0 || getBMIFlag ==1) //按键按下或者接收到获取命令
{
getBMIFlag =0;//清空标志
if(JuLi > 0)BMI = Weight_Shiwu/10/JuLi/JuLi; //防止出现除数为0//计算BMI
else {BMI = 0;}
}
sprintf(dis0,"H:%3.2fm G:%04.1fKg" ,JuLi,(float)Weight_Shiwu/10);//打印 显示
LCD_Write_String(0,0,dis0);//打印显
if(BMI <= 18.5)//体重过轻
{
sprintf(dis1,"BMI:%4.1f GQ " ,BMI);//打印
}
else if(BMI <= 23.9) //体重合适
{
sprintf(dis1,"BMI:%4.1f ZC " ,BMI);//打印
}
else //体重过重
{
sprintf(dis1,"BMI:%4.1f GZ " ,BMI);//打印
}
LCD_Write_String(0,1,dis1);//打印显
sendDataFlag++;
if(sendDataFlag >= 8)//发送数据计数 发送蓝牙数据
{
sendDataFlag = 0; //定时发送数据清空
sprintf(dis0,"身高:%3.2fm 体重:%04.1fKg \r\n" ,JuLi,(float)Weight_Shiwu/10);
sprintf(dis0,"%sBMI值:%4.1f\r\n" , dis0 , BMI);
if(BMI <= 18.5)//体重过轻
{
sprintf(dis0,"%s参考分析:体重过轻\r\n\r\n" , dis0 );
}
else if(BMI <= 23.9) //体重合适
{
sprintf(dis0,"%s参考分析:体重正常\r\n\r\n" , dis0 );
}
else //体重过重
{
sprintf(dis0,"%s参考分析:体重过重\r\n\r\n" , dis0 );
}
if(wirelessFlag == 0)UartSendString(dis0); //发送 对应的 数据
else My_ESP8266_SendStrStr(dis0); //发送 对应的 数据
}
}
if(uartTest == 1 && sendDataFlag >= 2)//接收到 测试命令
{
uartTest = 0;//取消标志
if(wirelessFlag == 0)UartSendString("Test Ok!\r\n\r\n"); //发送 对应的 数据
else My_ESP8266_SendStrStr("Test Ok!\r\n\r\n"); //发送 对应的 数据
}
}
}
void TIM2Inital(void)
{
RCAP2H = (65536-50000)/256;//晶振12M 60ms 16bit 自动重载
RCAP2L = (65536-50000)%256;
ET2=1; //打开定时器中断
EA=1; //打开总中断
TR2=1; //打开定时器开关
}
void TIM2(void) interrupt 5 using 1//定时器2中断
{
TF2=0;
time_50ms++;
if(time_50ms%2==0) //定时更新显示
{
disFlag = 1;//标志位置位
}
if(uartbusy>0) //串口数据采集处理
{
uartbusy--; //说明刚刚接收到数据
}
else//长时间没有接受数据 情况接收参数重新接收
{
firstin =0;//接收启示标志
Count=0;//接收计数
}
}
void UART_Init(void)
{
SCON = 0x05; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD = 0x02; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TL1 = TH1;
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void uartSendByte(unsigned char dat)
{
unsigned char time_out;
time_out=0x00;
SBUF = dat; //将数据放入SBUF中
while((!TI)) //检测是否发送出去
{
time_out++; //未发送出去 进行短暂延时//**All notes can be deleted and modified**//
}
}
void UartSendString(unsigned char *s)
{
while(*s!='\0')// \0 表示字符串结束标志,
//通过检测是否字符串末尾
{
uartSendByte(*s);//发送一个字节
s++;//指向下一个
}
}
void UART_SER (void) interrupt 4 //串行中断服务程序
{
unsigned char midVal=0;
unsigned char r_buf;
static char rec01 = 0;
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
r_buf = SBUF;
if(startCheckWireLess == 1 && wirelessFlag == 0)//启动检测无线
{
if(r_buf == 'O')rec01 = 1;
else if (rec01 == 1 && r_buf == 'K')
{
wirelessFlag = 1; //1表示wifi
}
}
uartbusy = 20;
if(r_buf=='*') //接收到起始标志
{
firstin = 1; //接收标志成功
Count = 0;
tab[Count++]=r_buf;
}
else if(firstin == 1) //接收到其实标志成功
{
tab[Count++]=r_buf;
if(tab[1] == '%')
{
uartTest = 1;//接收到串口命令
firstin =0;
Count=0;
}
if(Count>=3) //*SM0# //设置值
{
if(tab[4] == '#')//**All notes can be deleted and modified**//
{
if(tab[1] == 'B' && tab[2] == 'M')//检测到标志
{
getBMIFlag = 1;//获取BMI值
// setVal = (tab[3] - '0')*10 + (tab[4] - '0')*1; //提取数据
}
}
firstin =0;
Count=0;
}
}
}
if(TI) TI=0; //如果是发送标志位,清零
}
void My_ESP8266_SendStrStr( char *str)//发送数据
{
// u8 i;
unsigned char midLen=0; //数据长度变量
xdata unsigned char midTab[20]; //中间变量数组
while(str[midLen]!='\0') midLen++; //计算数据长度
// for(i=0;i<2;i++)
{
sprintf(midTab,"AT+CIPSEND = 0, %d \r \n",(unsigned int)midLen); //打印
UartSendString(midTab);//发送at命令
DelayMs(10);//延时一下发送 等待相应
UartSendString(str);//发送数据
// UartSendString("\r\n");//发送数据
DelayMs(6);//延时一下发送 等待相应
}
}
三、实物图示
如下图所示为HC-SR04超声波传感器、YZC-516C-1T称重传感器模块以及HX711 AD转换模块
四、附完整资源链接
百度网盘链接: https://pan.baidu.com/s/1yyXPn0CIwzz8rfwZcrZDmg?pwd=usvi
提取码: usvi