拓冰建站拓冰建站
首页 / 资讯中心 / 正文

51单片机蓝牙电子秤完整项目:从HX711到手机APP的硬件与软件方案

简介面向单片机学习者的基于51单片机蓝牙电子秤设计资料覆盖从硬件原理图、C语言源码到手机端APP的完整开发流程。资源内含原理图、源程序、手机APP、开题报告、元件清单及实物图适用于电子设计竞赛、课程设计或毕业设计。压缩包共47个文件约12.95MB主要包含C/H源程序、HEX烧录文件、Keil工程文件、PDF设计文档、图片和APK安装包其中PDF与DOC可用于查阅设计说明JPG及PNG提供实物接线参考XLS为元件清单TXT作为补充说明便于备料与调试。已有2514人学习浏览配套文档有助于快速理解整体设计思路手机APP配合蓝牙模块可实现称重数据的无线传输与实时显示便于后续二次开发与功能扩展。整体上这份资料为51单片机蓝牙应用提供了一套完整可落地的工程参考。1. 从源码到APP为什么蓝牙电子秤是最完整的51单片机项目拆了不少51单片机项目我的判断是蓝牙电子秤属于“看起来简单做起来最容易翻车”的那一类。手上这份资料把原理图、源程序、手机APP、开题报告、元件清单和实物图放在一起正好覆盖了模拟小信号采集、24位ADC、串口通信、经典蓝牙SPP和手机端解析这条完整链路。适合正在做课程设计、毕业设计的同学也适合想快速搞懂一只商业电子秤数据流的工程师。真正值得抠的细节并不在称重计算而是HX711的读取时序、HC-05的配对状态和APP对数据帧的切分这三个地方。2. 硬件链路拆解应变桥信号如何进 HX711 再走到 HC-052.1 电阻应变式称重传感器的信号特征大多数电子秤用悬臂梁式电阻应变传感器内部是四个应变片组成的惠斯通电桥。传感器供电电压常见5V灵敏度典型值2mV/V也就是说满量程时差分输出只有10mV。这个信号直接接51单片机处理是不现实的51单片机既没有片内ADC对这么小的电压也无法分辨。HX711的作用就是把差分信号放大并量化为24位数字量。在原理图里传感器四根线分别接HX711的E、E-、A、A-也就是激励电压和差分信号输入。接线极性如果画反程序里读出来的会是一组负数后面校准时重量怎么按都不对。我见过不少实物图里红黑线接反导致的问题所以拿到资料后第一件事并不是编译代码而是对照传感器外壳上的线序定义检查原理图。2.2 HX711 差分采样与读取时序HX711的A通道增益可设为128或64电子秤一般用128对应满量程差分输入大约是±20mV。芯片与51单片机之间只有两根连线DOUT和PD_SCK。DOUT为低表示一次转换完成PD_SCK每给一个脉冲就读出一位连续24个脉冲读完24位数据之后再多给一个脉冲切换下一次采样的增益。下面是资料源码里最常见的读取函数我按容易理解的写法重写了一遍sbit HX711_DOUT P1^0; sbit HX711_SCK P1^1; long HX711_Read(void) { unsigned long raw 0; unsigned char i; HX711_SCK 0; while(HX711_DOUT); // DOUT为低转换完成 for(i 0; i 24; i) { HX711_SCK 1; raw 1; if(HX711_DOUT) raw; HX711_SCK 0; } HX711_SCK 1; // 第25个脉冲A通道128倍增益 HX711_SCK 0; // HX711输出的是24位二进制补码这里扩展成32位有符号数 if(raw 0x800000) raw raw | 0xFF000000; return (long)raw; }这段时序逻辑本身不难难在两处。第一是while(HX711_DOUT)之前DOUT必须被释放为输入状态如果原理图上把DOUT接到了P1口而P1口被其他复用功能占用读取会一直卡住。第二是符号扩展HX711数据格式是二进制补码不做扩展就会出现“空载读出40多万加载后变成几万”这种明显不符合常理的结果。第25个脉冲后的SCK低电平持续时间需要注意脉冲太窄容易在PCB走线较长时出现误采样。对于STC89C52这种12个时钟周期一个机器周期的芯片直接用IO翻转就够了不需要额外延时。2.3 HC-05 蓝牙模块与 51 单片机的 UART 对接HC-05的经典蓝牙SPP配置在很多资料里都是直接用串口工具发AT指令但接入51单片机时要注意引脚定义。模块的TXD接单片机的RXD模块的RXD接单片机的TXD两条线必须交叉连接并共地。HC-05逻辑电平按3.3V设计而STC89C52的IO输出是5V TTL直接接模块RXD虽然大多数模块能工作但长时间运行有烧坏内部引脚的风险。稳妥做法是在TXD到HC-05的RXD之间串一个1kΩ电阻限流。模块上的状态引脚STATE平时输出低连接手机后输出高。资料里的实物图通常会把这个脚引到一颗LED上提示当前蓝牙是否配对。调试时这个灯比串口打印更直接因为手机一旦连接上蓝牙模块会立刻改变状态程序不需要为此写任何代码。模块引脚方向接到STC89C52 / 外设说明VCC电源3.6V~6V电源正极HC-05板载稳压直接接5VGND电源电源地必须与单片机共地TXD输出P3.0 (RXD)蓝牙发给单片机RXD输入P3.1 (TXD) 经1kΩ电阻单片机发给蓝牙STATE输出LED正极连接后高电平2.4 元件清单上容易被忽略的选型细节资料里的元件清单一般会列出传感器、HX711、HC-05、STC89C52、12MHz晶振、30pF瓷片电容、104去耦电容、按键、数码管或OLED屏、锂电池充电模块等。选元件除了数量还要看两个参数传感器量程和蓝牙模块版本。传感器量程决定后续标定区间5kg传感器和10kg传感器的满量程输出电压不同直接套用程序里的重量系数会差一倍。如果清单里写的是5kg桥式传感器程序里的满量程换算也需要对应改成5kg不要只看外形大小。供电部分建议按“模拟电源和数字电源分开”的方式布板。HX711的AVDD给传感器激励DVDD给数字电路两者之间用电感或磁珠隔开。蓝牙模块射频部分峰值电流大应在模块电源脚就近加100uF电解电容不然手机连接时单片机容易复位。原理图里如果这两个电容缺失实物焊接时可以自己补上。3. 源程序的骨架AD值换算、滤波和蓝牙报文怎么组织3.1 从 main 循环看程序状态机资料里的源程序通常会拆成几个文件主函数、HX711驱动、串口驱动、按键处理、显示驱动。有的版本会把全部代码堆在main.c里这也无所谓关键是main循环的执行顺序。标准流程是初始化定时器与串口读一次零点AD值然后在循环里执行“读取HX711 → 数字滤波 → 去皮偏置 → 重量换算 → 串口发送”同时扫描按键。这里容易出问题的是读取周期。HX711默认输出速率10Hz即100ms才能转换完一次主循环读得太频繁只会重复读到同一组数据。常见做法是在DOUT下降沿前等待DOUT还没拉低就继续做按键扫描不要用长阻塞延时。程序里一旦用delay(200)强行等待APP连接时的响应就会变得很迟钝。3.2 重量换算公式与参数来源换算公式没有玄学先保存空载稳定AD值为Zero_Value再放一个已知重量的标准砝码记录AD值Full_Value然后按线性关系把当前AD值映射到重量。资料源码里通常会留两个全局变量给标定程序用。下面的函数把读取结果转换成浮点重量long Zero_Value 0; long Full_Value 0; float Get_Weight(void) { long ad HX711_Read(); long delta ad - Zero_Value; float weight; weight (float)delta * 5000.0f / (float)(Full_Value - Zero_Value); if(weight 0.0f) weight 0.0f; return weight; }说明这里的5000.0f按5kg量程写的换成10kg要改成10000.0f。Full_Value和Zero_Value一旦确定程序的线性度就固定了。注意零点值不要上电时只读一次因为应变片通电后一段时间内还会发生微小形变零点会慢慢漂移。更稳妥的办法是上电后连续读30次取平均再作为Zero_Value。3.3 数字滤波滑动平均消除振动误差电子秤放在桌面上看起来不动但传感器对机械振动和工频干扰很敏感。HX711自身有数字滤波但输出码仍会在低位跳动。加一个5点滑动平均比每次输出原始码要稳定得多代码只需要一个环形缓冲区#define FILTER_N 5 unsigned long buf[FILTER_N]; unsigned char idx; unsigned long Smooth_Value(unsigned long value) { static unsigned long sum 0; sum - buf[idx]; buf[idx] value; sum value; idx (idx 1) % FILTER_N; return sum / FILTER_N; }滤波窗口越大显示越稳定但响应越慢。5个点大概对应0.5秒在普通电子秤上可以接受。如果滤波后重量仍跳±10g问题不在滤波而在于供电或传感器固定方式这一点务必先确认再调代码。3.4 蓝牙串口发送的数据帧与定时节奏给手机APP的数据帧不需要复杂协议用ASCII字符可读性最好常见格式是KG:1.25\r\n。KG:作为报文头数字部分保留两位小数\r\n作为帧结束。手机APP按行解析遇到\n就把缓存区里的内容当成一帧。发送节奏建议固定200ms一次太快会让蓝牙模块缓冲溢出太慢则手机端掉称重实时感。单片机串口一次发送只占几毫秒其余时间留给按键扫描和HX711读取。数据帧元素内容说明报文头KG:固定3字节用来识别重量帧重量数据1.25保留两位小数单位kg可显示在APP界面上帧结束符\r\nAPP按换行符切分数据流4. 手机APP的数据协议与经典蓝牙SPP联调4.1 APP端的功能与通信约定手机APP侧的核心不是UI而是蓝牙Socket的数据流。Android经典蓝牙使用RFCOMMUUID固定为SPP专用值。数据以字节流到达没有明确的帧边界因此需要自己按换行符切分。资料里的APP一般会处理三种事件设备连接、重量更新、低电量提醒最后一种往往由单片机检测电源电压后上报移动端只做显示。联调前先确认单片机的波特率和HC-05默认波特率一致很多“连不上”其实是模块被改成38400或115200而程序还在按9600发送。4.2 Android 蓝牙 SPP 连接关键 API获取远程设备的BluetoothSocket用createRfcommSocketToServiceRecord(SPP_UUID)创建连接。SPP_UUID就是00001101-0000-1000-8000-00805F9B34FB这是串口服务在蓝牙协议里的保留UUID。连接必须放在子线程不能占用主线程。完成连接后从socket.getInputStream()读取字节流private void startReadLoop(BluetoothSocket socket) { Thread t new Thread(() - { byte[] buffer new byte[256]; ByteArrayOutputStream line new ByteArrayOutputStream(); try { InputStream in socket.getInputStream(); int read; while ((read in.read(buffer)) ! -1) { for (int i 0; i read; i) { if (buffer[i] \n) { String text line.toString(UTF-8).trim(); if (text.startsWith(KG:)) { parseWeight(text); } line.reset(); } else { line.write(buffer[i]); } } } } catch (IOException e) { disconnect(); } }); t.start(); }这部分有几个隐藏问题。in.read(buffer)返回的是一次读到的字节数可能只读到半个数据帧所以不能把这次的字节直接当整条报文去解析必须用ByteArrayOutputStream把不完整的尾部暂存到遇到\n为止。parseWeight里做Float.parseFloat时需要try-catch因为蓝牙传输偶发干扰可能让字符串变成KG:1.2x解析异常会导致APP闪退。UUID写错则createRfcommSocket...连接会报service discovery failed。4.3 粘包、拆包和乱码的具体处理在10Hz采样率下数据帧每100ms来一次蓝牙串口可能把两帧数据连着送到APP这就是粘包也可能一帧内容被拆成两次读这是拆包。做法是只认换行符\n前面提到的ByteArrayOutputStream已经能满足大多数场景。乱码则是波特率不一致或ASCII与UTF-8解析冲突造成的HC-05默认只透传字节没必要发GBK字符集的中文报文重量帧全部用英文和数字最省事。如果APP界面同时要显示“去皮”按钮单片机侧要增加串口接收中断。常见格式是手机发送TARE\r\n单片机收到后把当前AD值写入Zero_Value。这个功能在资料源码里不一定预置可以自己加改动量不大。4.4 联调排查对照表现象可能原因处理方式手机搜不到HC-05模块处于AT模式按键退出AT或重新上电连接后立即断开供电电流不足蓝牙模块电源加电容换独立LDO手机收到乱码波特率不一致统一为9600或者重新烧写数据时断时续丢包或串口中断冲突缩短发送数据帧降低发送频率重量数值偏大或偏小标定系数不对重新用标准砝码标定5. 校秤流程、量程更换与压箱底的调试技巧5.1 五步完成硬件校准校准不需要特殊设备准备一个100g、500g或1kg的标准砝码即可原则是砝码重量接近电子秤的量程。五步流程第一步让电子秤通电预热20分钟完成热机第二步空载状态下连续读30次AD值取平均存到Zero_Value第三步把标准砝码放在秤盘中心等数据稳定后记录Full_Value第四步用公式scale (Full_Value - Zero_Value) / 砝码重量算出每克对应的AD增量第五步保存到单片机EEPROM或外部Flash中重新上电验证一次空载和砝码重量。注意不要把Full_Value写成固定常量。每个传感器即使同型号同批次机械装配位置都会导致零点不同所以程序里必须保留校准入口。资料里的源码若没有EEPROM保存参数可以用一个“长按按键进入标定”的状态机来实现标定完成后把参数写入AT24C02或STC片内EEPROM。5.2 零点漂移与去皮键的正确用法应变片的零点漂移是常态而不是故障。温度变化、弹性体疲劳、秤盘固定螺丝松动都会让零点每小时变化几个AD码。程序里应只保存通电时刻的初始零点同时保留一个去皮按键让用户随时把当前重量清零。去皮和校零是两回事校零会修改Zero_Value去皮只是在当前读到的AD值上做一个偏移不改变斜率。如果发现零点每天甚至每隔几小时漂移几十克优先检查传感器周围有没有热源或气流。放在窗边被太阳晒到的秤数据一定漂。这个机械问题用任何软件滤波都救不回来。5.3 数据抖动压不下去时的排查思路当重量数值在±5g以内抖动多数是正常现象如果超过±20g先断掉手机连接看本机显示是否同样抖动以区分是蓝牙报文错误还是传感器问题。然后用万用表量HX711的AVDD对地电压正常应在2.6V~3.3V之间波动超过50mV就需要加大电源电容。最后检查秤盘与传感器固定螺丝常见的秤盘悬空或只固定了一个角会让受力不在传感器中心导致称量误差很大。整套蓝牙电子秤做出来后建议用连续称量标准砝码10次的方式记录最大值与最小值只要误差在±5%以内就算及格。把这组测试数据连同复测截图放进课程设计报告里比任何文字都更有说服力。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门