写点什么

基于 51 单片机的智能营养秤系统设计与实现

作者:DS小龙哥
  • 2023-06-18
    重庆
  • 本文字数:4760 字

    阅读完需:约 16 分钟

一、项目背景

随着人们生活水平和健康意识的提高,越来越多的人开始注重自己的饮食健康。在此背景下,智能营养秤系统应运而生,成为了一种非常实用的工具。本项目基于 51 单片机设计和实现一种智能营养秤系统,通过该系统可准确地测量食物的重量并计算其热量、蛋白质、脂肪、碳水化合物等营养成分含量。


当前系统采用了 STC89C52 单片机作为主控芯片,预置了多种食材的营养成分数据。用户只需要使用矩阵键盘输入食材编号,将需要称重的食材放置在重力传感器上进行依次称重,系统就可以自动计算出所有食材的各类营养含量总值,并通过液晶屏显示出来。同时,系统根据预设的营养指标,对不达标或超标的食材进行对应的声光提示,提醒用户注意饮食健康。


当前系统还配备了无线 WIFI 模块,可以将当前营养数据上传到手机端实时显示,并给出营养建议。这使得用户可以随时 1 了解自己的饮食情况,及时进行调整,从而达到更好的健康效果。


本项目的设计和实现是为了满足人们对于饮食健康的需求,帮助人们更好地控制自己的饮食,达到健康瘦身的目的。同时,由于采用了 51 单片机的设计方案,具有成本低、易于制作、易于维护等优点,具有广泛的应用前景。



二、系统设计过程

2.1 硬件组成

【1】STC89C52 单片机作为主控芯片。


【2】4x4 电容矩阵键盘用于输入食材编号。


【3】HX711 重力传感器用来进行多种食材的称重。


【4】1.44 寸 LCD 显示屏用来显示所有食材的各类营养含量总值。


【5】ESP8266 无线 WIFI 模块用于将当前营养数据上传到手机端实时显示。

2.2 系统框架组成

【1】输入:使用 4x4 电容矩阵键盘输入食材编号,触发称重功能。


【2】称重:根据输入的食材编号,通过 HX711 重力传感器对多种食材依次称重。


【3】计算:系统自动计算所有食材的各类营养含量总值,并在 1.44 寸 LCD 显示屏上显示。


【4】判断:根据系统预设的营养指标,判断当前营养数据是否达标或超标。


【5】提示:若不达标或超标,系统进行相应的声光提示。


【6】数据上传:通过 ESP8266 无线 WIFI 模块将当前营养数据上传到手机端实时显示,并给出营养建议。

2.3 系统模块设计

【1】系统硬件设计


采用了 51 单片机作为主控芯片,重力传感器用于称重,矩阵键盘用于输入食材编号,液晶屏用于显示数据。同时,为了实现无线上传功能,还需要添加 WIFI 模块。


【2】系统软件设计


系统的软件设计主要包括两个方面,即驱动程序和应用程序。其中,驱动程序负责与各个硬件模块进行通信,读取和处理相关数据;应用程序则负责实现具体的计算和控制逻辑。


【3】食材营养成分数据预置


预先测量并记录多种食材的重量和营养成分含量,并将这些数据存储在系统中供后续使用。


【4】食材识别和称重


当用户输入食材编号后,系统自动从预置的数据中查找对应的营养成分信息。然后,用户将需要称重的食材放置在重力传感器上,系统开始进行称重并输出重量数据。


【5】营养计算和指标判断


系统根据已知的食材重量和营养成分数据,计算出当前食物的各类营养含量总值。同时,根据预设的营养指标,判断当前食物是否达标或超标,并进行相应的声光提示。


【6】数据传输和显示


将当前的营养数据通过 WIFI 模块上传到手机端实时显示,并根据用户的身体数据和运动情况,推荐合适的饮食方案。


【7】整体测试和优化:对系统进行整体测试和优化,确保系统能够正常工作并满足设计要求。

2.4 程序设计思路

【1】定义多种食材的营养成分数据,存储在程序中。


【2】初始化电容矩阵键盘和 HX711 重力传感器。


【3】等待用户输入食材编号。一旦检测到有效输入,记录食材编号并触发称重功能。


【4】根据输入的食材编号,依次使用 HX711 重力传感器进行称重,并根据对应的营养成分数据进行计算,得出每种营养成分的总值。


【5】将所有食材的营养成分总值通过 1.44 寸 LCD 显示屏展示给用户。


【6】根据系统预设的营养指标,判断当前营养数据是否达标或超标。如果不达标或超标,则进行相应的声光提示。


【7】通过 ESP8266 无线 WIFI 模块将当前营养数据上传到手机端实时显示,并给出营养建议。

三、程序代码实现

3.1 HX711 称重传感器代码

下面是 STC89C52 单片机读取 HX711 称重传感器的值,得到最终的重量,打印到串口的完整代码:


#include <reg52.h>#include <intrins.h>
// HX711引脚定义sbit HX711_DOUT = P1^0; // 数据输出引脚sbit HX711_SCK = P1^1; // 时钟输入引脚
typedef unsigned char uchar;typedef unsigned int uint;
uchar WeiLai, OldData; // 定义两个变量,用于保存数据uchar Data[3]; // 存放读取的数据long result = 0; // 定义长整型变量,用于存放最终的重量值
void delay_us(uint us) // 延时函数(微秒级){ while(us--) { _nop_(); // 空操作语句,延时一微秒 _nop_(); _nop_(); _nop_(); }}
void Read_HX711() // 读HX711函数{ uchar i; HX711_DOUT = 1; // 先将DOUT置为高电平 delay_us(1); // 延时1微秒 HX711_SCK = 0; // 将SCK置为低电平 delay_us(1); // 延时1微秒
for(i=0;i<24;i++) // 循环24次,读取数据 { HX711_SCK = 1; // 将SCK置为高电平 delay_us(1); // 延时1微秒 WeiLai = HX711_DOUT; // 读取DOUT引脚上的数据 result <<= 1; // 左移一位 if(WeiLai == 1) // 如果DOUT为1,将result的最低位赋值为1 { result++; } HX711_SCK = 0; // 将SCK置为低电平 delay_us(1); // 延时1微秒 }
WeiLai = OldData; // 将OldData的值赋给WeiLai Data[2] = result; // 存储重量值的最高字节 Data[1] = result>>8; // 存储重量值的中间字节 Data[0] = result>>16; // 存储重量值的最低字节}
void main(){ TMOD = 0x20; // 定时器T1工作模式设置 TH1 = 0xfd; // 波特率9600 TL1 = 0xfd; // 波特率9600 TR1 = 1; // 启动定时器T1 SCON = 0x50; // 设置串口工作方式
while(1) { Read_HX711(); // 调用读HX711函数
// 将读取到的数据打印到串口 SBUF = Data[0]; while(TI == 0); TI = 0;
SBUF = Data[1]; while(TI == 0); TI = 0;
SBUF = Data[2]; while(TI == 0); TI = 0; }}
复制代码

3.2 ESP82660-WIFI 配置代码

以下是 STC89C52 单片机控制 ESP8266,配置成 AP 模式,开启 TCP 服务器,等待客户端连接上来的完整代码:


#include <reg52.h>#include <intrins.h>
#define RXD P3_0 // 串口接收引脚#define TXD P3_1 // 串口发送引脚
typedef unsigned char uchar;typedef unsigned int uint;
bit rcvflag; // 接收标志位uchar idata RcvBuf; // 存储接收到的数据uchar len; // 存储接收到的数据长度uchar AT_OK; // 存储AT指令执行结果
/* 延时函数 */void Delayms(uint ms){ uchar i, j; for(i=0;i<ms;i++) { for(j=0;j<110;j++); }}
/* 发送一个字节的数据 */void SendByte(uchar dat){ SBUF = dat; while(!TI); TI = 0;}
/* 发送字符串 */void SendString(char *str){ while(*str) { SendByte(*str++); }}
/* 发送AT指令 */void SendATCmd(char *str){ SendString(str); SendString("\r\n"); Delayms(20); // 延时20ms等待返回数据}
/* 接收一个字节的数据 */void Uart_Rcv() interrupt 4 using 1{ if(RI) // 判断是否接收到数据 { RI = 0; // 清除RI标志位 RcvBuf = SBUF; // 存储接收到的数据 rcvflag = 1; // 置接收标志位 }}
/* 检查AT指令执行结果 */void Check_AT_Cmd(){ uchar i;
if(rcvflag == 0) // 如果没有接收到数据 { AT_OK = 0xff; // 执行AT指令失败 return; }
len = 0; do // 接收完整的一行数据 { i = RcvBuf; RcvBuf = 0; if(i == '\r') break; // 遇到回车符则结束接收 if(i != '\n') // 跳过换行符 { len++; } }while(1);
if(len != 0) // 如果有接收到数据 { AT_OK = 0; // 执行AT指令成功 }
rcvflag = 0; // 清除接收标志位}
/* 配置ESP8266模块为AP模式 */void Set_AP_Mode(char *ssid, char *pwd){ SendATCmd("AT+RST"); // 复位ESP8266模块 Check_AT_Cmd();
SendATCmd("AT+CWMODE=2"); // 配置模块为AP模式 Check_AT_Cmd();
SendATCmd("AT+CWSAP=\""); SendString(ssid); // 设置SSID SendString("\",\""); SendString(pwd); // 设置密码 SendString("\",5,3"); // 设置加密方式为WPA2_PSK Check_AT_Cmd();}
/* 开启TCP服务器 */void TCP_Server_Open(){ SendATCmd("AT+CIPMUX=1"); // 开启多连接模式 Check_AT_Cmd();
SendATCmd("AT+CIPSERVER=1,8888"); // 开启TCP服务器,端口号为8888 Check_AT_Cmd();}
/* 等待客户端连接 */void Wait_For_Client_Connect(){ uchar i;
do { if(rcvflag == 0) continue; // 没有接收到数据则继续等待
len = 0; do { i = RcvBuf; RcvBuf = 0; if(i == '\r') break; if(i != '\n') { len++; } }while(1);
rcvflag = 0; // 清除接收标志位
if(len != 0 && RcvBuf == '+') { SendString("AT+CIPSEND=0,12"); // 发送数据,长度为12 SendString("\r\n"); Delayms(10);
if(rcvflag && RcvBuf == '>') // 等待">"符号 { SendString("Hello World!"); // 发送数据 SendByte(0x1a); // 发送结束符 }
while(!rcvflag); // 等待数据发送完成 len = 0;
do { i = RcvBuf; RcvBuf = 0; if(i == '\r') break; if(i != '\n') { len++; } }while(1);
rcvflag = 0; // 清除接收标志位
if(len != 0 && RcvBuf == 'S') // 如果接收到"SEND OK"说明数据发送成功 { SendString("Data send success!"); SendString("\r\n"); } }}while(1);}
/* 主函数 */ void main() { TMOD = 0x20; // 定时器T1工作模式设置 TH1 = 0xfd; // 波特率9600 TL1 = 0xfd; // 波特率9600 TR1 = 1; // 启动定时器T1 SCON = 0x50; // 设置串口工作方式 EA = 1; // 允许中断 ES = 1; // 允许串口中断 Set_AP_Mode("MyAP", "12345678"); // 配置模块为AP模式,设置SSID和密码 TCP_Server_Open(); // 开启TCP服务器 Wait_For_Client_Connect(); // 等待客户端连接}
复制代码


发布于: 2023-06-18阅读数: 19
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022-01-06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
基于51单片机的智能营养秤系统设计与实现_6 月优质更文活动_DS小龙哥_InfoQ写作社区