本文主要介绍基于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)源程序代码
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/12if(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//计算BMIelse {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.0592MHzTL1 = 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