ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于STM32与HX711的5kg电子秤设计:从传感器选型到滤波标定

基于STM32与HX711的5kg电子秤设计:从传感器选型到滤波标定 1. 为什么我选择用STM32做一台电子秤电子秤这东西看起来简单做起来才知道坑有多深。市面上几十块钱的成品秤一抓一大把精度能到1克甚至0.1克但如果你自己动手从零搭一台就会发现从传感器选型、信号调理、ADC采样到滤波算法、标定校准每一步都有讲究。我这次做的这台基于STM32的电子秤量程5kg分辨率1g带OLED显示和串口输出成本控制在60块以内前后折腾了大概两周时间踩了不少坑也积累了一些书本上不会写的经验。先说清楚这个项目适合谁看。如果你正在做单片机课程设计、毕业设计或者单纯想搞明白电子秤到底是怎么把重量变成数字的那这篇内容应该能帮到你。需要的基础是会C语言、用过STM32的GPIO和定时器、能看懂简单的电路图。如果这些你还不熟也没关系我会把关键的地方拆开讲尽量说人话。核心关键词先摆出来STM32、单片机、电子秤、压力传感器、HX711。这五个词基本概括了整个项目的技术栈。STM32是主控压力传感器负责把重量变成电信号HX711负责把这个微弱的电信号放大并转成数字量给单片机单片机再算、滤波、显示。整条链路环环相扣任何一个环节出问题秤就不准。我选STM32而不是51单片机原因很直接STM32的定时器资源丰富、中断优先级灵活、浮点运算能力哪怕是软浮点也比51强不少做滤波和标定时不用抠抠搜搜地省CPU周期。而且HX711的驱动需要精确的时序控制STM32的GPIO翻转速度完全够用用51也能做但时序裕量小容易出玄学问题。至于具体型号我用的是STM32F103C8T6也就是常说的“蓝桥杯同款”或者“最小系统板标配”价格便宜、资料多、社区支持好出了问题搜一下基本都能找到答案。2. 系统整体方案与核心器件选型2.1 电子秤的完整信号链路一台电子秤的本质是把“重量”这个物理量经过一系列转换最终变成屏幕上的一串数字。这条链路是这样的物体压在秤台上秤台把力传递给压力传感器称重传感器传感器内部的应变片发生形变电阻值改变通过惠斯通电桥输出一个毫伏级的差分电压。这个电压非常小5kg量程的传感器满量程输出通常只有1mV/V左右激励电压5V的话满量程差分输出也就5mV。STM32自带的12位ADC分辨率是3.3V/4096≈0.8mV直接采的话根本分辨不出1g的变化所以必须加一级放大。HX711就是干这个的。它内部集成了低噪声可编程增益放大器PGA和24位Sigma-Delta ADC专门为称重传感器设计。增益可选32、64、128对应不同的输入范围。我用的是通道A增益128输入范围±20mV刚好覆盖传感器的输出。24位ADC的理论分辨率是2^2416777216但实际有效位数ENOB大概在20位左右即便如此对于5kg量程来说理论分辨率远优于1g余量充足。STM32和HX711之间通过两根线通信一根时钟线SCK一根数据线DOUT。HX711的时序很简单但有几个坑后面会细说。STM32拿到24位原始数据后做滤波、去皮、标定最后算出重量送到OLED显示同时可以通过串口输出到电脑。2.2 为什么选HX711而不是自己搭运放ADC有人可能会问既然STM32有ADC为什么不用仪表放大器比如INA128加STM32的ADC来做理论上可以但实际操作下来问题很多。首先称重传感器的输出是差分信号STM32的ADC是单端输入需要额外的差分转单端电路。其次传感器输出阻抗低但信号幅度小容易受电源噪声和地弹影响。第三STM32的12位ADC在5kg量程下1g对应约0.8mV/5000≈0.16μV这已经远低于ADC的噪声底了根本采不出来。HX711把PGA、ADC、时钟、稳压都集成在一颗芯片里外围只需要几个电容和电阻电路简洁抗干扰能力也强。它的采样率可选10Hz和80Hz10Hz时噪声更低适合静态称重80Hz响应快适合动态称重。我选的是10Hz因为电子秤不需要快速响应稳定性优先。2.3 压力传感器的选型要点称重传感器我选的是常见的铝合金悬臂梁式量程5kg输出灵敏度1.0mV/V精度等级C3。选它主要看三个参数量程、灵敏度、精度等级。量程要略大于你实际要称的最大重量留20%左右的余量防止过载损坏。灵敏度决定了输出信号的大小1mV/V是常见值也有2mV/V的灵敏度越高对放大器的要求越低。精度等级C3表示综合误差在0.02%左右对于5kg量程来说误差约1g刚好满足我的需求。传感器的接线是四线制红激励、黑激励-、绿信号、白信号-。有些传感器还有屏蔽线要接到地。接线顺序不能搞错否则输出反向或者无输出。我第一次接的时候把绿白接反了结果重量越大读数越小排查了半天才反应过来。3. 硬件电路设计与关键细节3.1 HX711的典型应用电路HX711的电路不复杂但有几个地方必须注意。先看电源HX711的AVDD和DVDD都是2.7V到5.5V我直接用5V供电和STM32的3.3V分开。为什么不用3.3V因为传感器的激励电压也来自HX711的AVDD5V激励下满量程输出5mV3.3V激励下只有3.3mV信号更小对噪声更敏感。而且HX711的模拟部分在5V下性能更好。模拟电源和数字电源之间要加磁珠或者0欧电阻隔离AVDD和DVDD各加一个0.1μF和一个10μF的电容去耦。传感器的激励正负端要各加一个0.1μF的电容到地滤掉高频噪声。信号正负端之间加一个0.1μF的电容但不要加太大否则会影响响应速度。HX711的SCK和DOUT引脚直接接STM32的GPIO。SCK是输入DOUT是输出。注意DOUT是开漏输出需要上拉电阻但HX711内部已经有上拉了外部可以不接。如果通信不稳定可以在DOUT上加一个4.7kΩ的上拉电阻到DVDD。还有一个容易忽略的地方HX711的VFB引脚。这个引脚是内部稳压器的反馈端如果不用内部稳压器要接到AVDD。我一开始没接结果芯片不工作查了数据手册才发现。3.2 STM32最小系统与外围接口STM32F103C8T6最小系统板自带8MHz晶振和32.768kHz晶振供电3.3V。我用的是SWD下载方式只需要SWDIO、SWCLK、GND、3.3V四根线。串口用USART1PA9和PA10接CH340模块到电脑方便调试输出。OLED我用的是0.96寸I2C接口的SSD1306接PB6和PB7。I2C通信比SPI慢但显示重量这种低频刷新完全够用。按键用了三个去皮、校准、切换单位接PA0、PA1、PA2配置成上拉输入按下为低电平。电源部分我用了一个5V的USB供电经过AMS1117-3.3V给STM32供电HX711和传感器直接用5V。注意AMS1117的压差是1.1V左右5V输入输出3.3V没问题但如果输入降到4.5V以下输出可能不稳。所以USB线不能太长线损要小。3.3 电路布局与抗干扰经验PCB布局上模拟部分和数字部分要分开。HX711和传感器接口放在板子一侧STM32和OLED放在另一侧。地平面要完整模拟地和数字地单点连接通常在HX711的GND引脚附近。传感器的信号线要走差分对尽量短远离时钟线和电源线。如果不用PCB用洞洞板或者面包板搭问题会更多。面包板的接触电阻不稳定传感器的微弱信号很容易被干扰。我一开始用面包板读数跳动能有几十克后来换成洞洞板焊接跳动降到几克最后画了PCB跳动在1克以内。所以如果你对精度有要求强烈建议至少用洞洞板焊接不要用面包板。还有一个细节传感器的金属外壳要接地但不要接到信号地接到机壳地或者电源地。如果秤台是金属的也要接地否则人体接触时会有静电干扰。4. HX711驱动与STM32程序实现4.1 HX711的通信时序详解HX711的通信协议很简单但时序要求严格。DOUT平时是高电平当数据准备好时DOUT变低。STM32检测到DOUT变低后给SCK发送25到27个时钟脉冲前24个脉冲读出24位数据MSB先出第25到27个脉冲用来选择下一次转换的通道和增益。具体来说第25个脉冲决定通道A增益128还是通道B增益32第26个脉冲决定通道A增益64。我只需要通道A增益128所以发送25个脉冲即可。注意第25个脉冲的上升沿会触发通道选择所以时序要准确。读数据的代码大概是这样uint32_t HX711_Read(void) { uint32_t data 0; while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) GPIO_PIN_SET); // 等待DOUT变低 for(uint8_t i 0; i 24; i) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); data 1; if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) GPIO_PIN_SET) data; HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); } HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); return data; }这段代码有个问题没有做超时处理。如果HX711没接好或者坏了DOUT一直不低程序就死循环了。实际使用中要加超时比如循环10000次后返回错误。还有一个坑HX711的数据是24位有符号数最高位是符号位。如果读出来是0xFFFFFF表示-1。在C语言里要把24位数据扩展成32位有符号数需要判断最高位。如果最高位是1就减去0x1000000。我一开始没处理结果负数重量显示成很大的正数。4.2 采样率10Hz还是80Hz的选择HX711的RATE引脚决定采样率。接低电平是10Hz接高电平是80Hz。我选10Hz因为电子秤是静态称重不需要快速响应而且10Hz时内部滤波更强噪声更低。实测下来10Hz时读数跳动在±5个ADC码左右80Hz时跳动在±20个码左右。对于5kg量程24位ADC满量程对应5mV1个码约0.3μV5个码约1.5μV换算成重量约1.5g。所以10Hz下跳动约1.5g80Hz下约6g。如果你要做动态称重比如传送带上称重那必须用80Hz但精度会下降。4.3 数字滤波与去皮算法原始数据即使经过HX711内部滤波还是有跳动。我在STM32里做了两级滤波第一级是滑动平均取最近10个采样值求平均第二级是一阶低通滤波系数0.2。滑动平均能平滑随机噪声低通滤波能抑制周期性干扰。实测下来滤波后跳动在±1个码以内显示稳定。去皮算法很简单开机后先采样一段时间取平均值作为零点后续所有重量都减去这个零点。去皮按键按下时把当前重量作为新的零点。注意去皮要在秤台上没有物体时进行否则会把物体重量也去掉。标定是电子秤最关键的一步。我用的是两点标定先记录空载时的ADC值零点再放一个已知重量的砝码比如1kg记录ADC值计算斜率。公式是重量 (ADC值 - 零点) / 斜率。斜率 (ADC值_砝码 - 零点) / 砝码重量。标定用的砝码精度要高至少M1级否则秤的精度无从谈起。标定参数要存在Flash里掉电不丢失。STM32F103的Flash擦写次数约1万次标定不频繁完全够用。我用了Flash的最后一页存储标定参数注意擦除时要整页擦除写入前先解锁。5. 调试过程中踩过的坑与排查方法5.1 读数跳动大、不稳定这是最常见的问题。原因可能有几个电源噪声、地线干扰、传感器接线不良、HX711去耦不足。我排查的顺序是先用万用表测HX711的AVDD和DVDD电压纹波要小于10mV。如果纹波大加电容或者换LDO。然后检查传感器的四根线是否焊接牢固特别是屏蔽线是否接地。再检查HX711的模拟地和数字地是否单点连接。最后看代码采样率是否设置正确滤波是否足够。我遇到过一次读数跳动特别大后来发现是HX711的VFB引脚没接芯片内部稳压器没工作AVDD电压不稳。接上VFB到AVDD后跳动立刻降到正常水平。5.2 重量越大读数越小这是传感器信号正负接反了。把绿线和白线对调即可。注意有些传感器的线色定义不一样最好用万用表测一下激励正和激励负之间电阻约1kΩ信号正和信号负之间电阻约1kΩ激励和信号之间电阻约1kΩ。如果测出来不对说明线序搞错了。5.3 HX711初始化失败、DOUT一直高先检查硬件HX711的供电是否正常SCK和DOUT是否接对传感器是否接好。如果硬件没问题看代码SCK初始电平是否为低DOUT是否配置为输入。HX711上电后需要一段时间稳定大概400ms所以初始化后要延时再读。如果DOUT一直高可能是HX711坏了换一片试试。5.4 标定后精度不够标定用的砝码精度不够或者标定点太少。建议用两个标定点零点和满量程的80%左右。比如5kg量程用4kg砝码标定。如果只有1kg砝码可以在1kg和零点之间标定但线性度可能不好。另外传感器的非线性误差也会影响精度C3等级的传感器非线性误差约0.02%5kg量程下约1g这是理论极限。5.5 常见问题速查表问题现象可能原因排查方法读数跳动大电源噪声、地线干扰测AVDD纹波检查单点接地重量越大读数越小传感器信号接反对调绿白线DOUT一直高HX711未工作、接线错误检查供电和SCK/DOUT标定后不准砝码精度不够、标定点少换高精度砝码增加标定点显示负数24位数据未扩展符号判断最高位减去0x1000000串口无输出波特率不对、TX/RX接反检查波特率和接线6. 精度提升与功能扩展思路6.1 从1g到0.1g的精度提升路径如果想做到0.1g分辨率5kg量程下需要50000个分度24位ADC理论上有16777216个码看起来够但实际有效位数只有20位左右约100万个码对应5kg是0.005g理论上够。但问题在传感器C3传感器的综合误差是0.02%5kg下是1g这是瓶颈。要提升精度得换C6等级的传感器误差0.008%5kg下0.4g。再往上就是电磁力平衡传感器了那是分析天平级别成本高得多。另外HX711的噪声在10Hz下约50nV对应5kg量程约0.05g所以HX711不是瓶颈。电源噪声和机械结构才是。秤台要刚性足够不能有弹性变形。传感器安装要水平受力要均匀。环境温度变化也会影响应变片有温度漂移需要软件补偿。6.2 加入蓝牙或WiFi上传数据STM32F103没有内置无线可以外接HC-05蓝牙模块或者ESP8266 WiFi模块。HC-05通过串口和STM32通信配置成从机模式手机配对后就能收到重量数据。ESP8266可以连WiFi通过MQTT协议上传到云平台。注意无线模块的电源要独立不要和模拟部分共用否则射频干扰会影响ADC。6.3 低功耗设计与电池供电如果要电池供电STM32可以进入Stop模式HX711也有掉电模式。但HX711的掉电模式需要把PD_SCK拉高超过60μs唤醒需要拉低。实际使用中可以每秒钟唤醒一次采样一次然后继续休眠。STM32的Stop模式功耗约20μAHX711掉电模式约1μA整体可以做到100μA以下用2000mAh电池可以撑两年。但OLED显示耗电较大可以改成按键唤醒显示。6.4 多传感器阵列与量程扩展单个传感器量程有限如果要称更重的东西可以用多个传感器并联。比如四个5kg传感器并联量程变成20kg但灵敏度不变因为并联后输出电流相加电压不变。注意并联时四个传感器的灵敏度要一致否则受力不均会导致误差。安装时要保证四个传感器高度一致秤台刚性足够。7. 我的实操心得与最后几句这个项目我从画原理图到写代码到调试前后用了两周。最大的体会是电子秤的精度三分靠电路七分靠机械结构和标定。电路再完美传感器装歪了、秤台有弹性、标定砝码不准都白搭。我一开始用面包板搭读数跳动几十克后来换成洞洞板降到几克最后画了PCB才稳定在1克以内。所以如果你要做硬件上不要省该画板就画板该焊接就焊接。另一个体会是HX711的时序虽然简单但细节很多。比如第25个脉冲的上升沿触发通道选择如果脉冲宽度不够通道切换会失败。还有DOUT是开漏输出上拉电阻不能省。这些细节数据手册上都有但容易忽略。最后分享一个小技巧标定时先用一个已知重量的物体比如一袋500g的盐称一下看看读数偏差多少然后调整斜率。反复几次就能把误差调到最小。如果没有标准砝码可以用硬币一元硬币约6g但精度不高只能粗略标定。这个秤我后来加了串口输出接到电脑上画了个简单的上位机实时显示重量曲线用来做实验数据记录挺方便的。如果你也想扩展可以从串口输出开始成本最低效果最直接。
返回列表