ARTICLE DETAIL

资讯详情

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

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

基于STM32与HX711的5kg电子称设计:从传感器选型到滤波标定 1. 项目缘起与整体设计思路电子称这东西看起来简单做起来门道不少。市面上几十块钱的厨房秤拆开看核心无非是一颗单片机、一个24位ADC、一个应变片式压力传感器再加一块LCD。但真要自己从零搭一套出来从传感器选型、信号调理、ADC采样、滤波算法到标定校准每一步都有坑。这次我做的这个基于STM32单片机的电子称量程设计为5kg分辨率做到1g带去皮、超载提示和串口输出功能整体成本控制在40元以内。先说清楚这个项目适合谁看。如果你正在做单片机课程设计、毕业设计或者单纯想搞明白电子称到底是怎么把“重量”变成“数字”的这篇文章应该能帮到你。我假设你有基本的C语言基础和STM32开发经验至少点亮过LED、用过串口。如果完全没有接触过STM32建议先找个最小系统板跑通GPIO和USART再来跟这个项目。整个系统的信号链路是这样的金属应变片受力变形惠斯通电桥输出差分电压这个电压非常微弱5kg满量程时典型输出只有几毫伏到十几毫伏。HX711内部集成了低噪声可编程增益放大器PGA增益可选32/64/128和24位Σ-Δ型ADC直接把这个微弱差分信号放大并数字化通过两线串行接口DOUT和PD_SCK把数据送给STM32。STM32负责读取数据、做数字滤波、换算成重量、驱动显示、处理按键和串口通信。为什么选HX711而不是自己搭仪表放大器加外部ADC算一笔账就明白了。自己搭方案一颗INA333仪表放大器约8元一颗ADS1232或CS5530这类24位ADC约15元再加上基准源、滤波电容、PCB面积成本轻松超过30元而且噪声控制、时序调试的难度远超预期。HX711模块市面价3到5元内部PGA和ADC已经匹配好噪声性能在10Hz采样率下等效输入噪声约50nV对于1g分辨率的要求绰绰有余。选STM32而不是51单片机主要考虑三点一是STM32的定时器资源丰富方便做精确的采样时序控制二是浮点运算和滤波算法跑起来更从容三是后续扩展比如加蓝牙、加SD卡存储空间大。注意HX711的通道A增益默认128对应满量程差分输入±20mV。如果你的传感器灵敏度是1mV/V激励电压5V满量程输出就是5mV用128增益刚好合适。但如果传感器灵敏度是2mV/V满量程输出10mV仍然在范围内只是有效位数会少一位。选传感器时尽量让满量程输出接近但不超过20mV。2. 硬件选型与电路设计要点2.1 压力传感器与HX711的匹配计算我用的传感器是5kg量程的铝合金悬臂梁式应变片传感器灵敏度1.0mV/V激励电压推荐5V。满量程输出计算5V × 1.0mV/V 5mV。HX711通道A在增益128时满量程差分输入为±20mV5mV只用了四分之一量程。这意味着24位ADC的有效位数会损失约2位实际有效分辨率大约21位。对于5kg量程理论分辨率是5000g / 2^21 ≈ 0.0024g远优于1g的要求。所以这个匹配是合理的不需要换更高灵敏度的传感器。传感器接线是四线制E激励正、E-激励负、A信号正、A-信号负。有些传感器还有屏蔽线要接到模拟地。HX711模块上通常标着E、E-、A、A-、B、B-我们只用通道A。接线时特别注意E和E-不能接反否则电桥供电反向输出信号极性反转虽然软件可以处理但容易混淆。A和A-也不能接反否则重量增加时读数反而减小。2.2 STM32最小系统与外围电路主控我选的是STM32F103C8T6也就是常说的“蓝板”或“最小系统板”价格10元左右72MHz主频64KB Flash20KB RAM资源足够。晶振用8MHz外部晶振经PLL倍频到72MHz。复位电路用10k上拉加100nF电容。BOOT0和BOOT1都下拉到地从Flash启动。HX711与STM32的连接DOUT接PA0PD_SCK接PA1。这两个引脚配置为推挽输出PD_SCK和浮空输入DOUT。注意HX711的供电是2.7V到5V我直接用5V供电这样传感器激励也是5V信噪比更好。但STM32的IO是3.3V电平HX711的DOUT输出高电平接近5V直接接STM32的IO会有过压风险。实测中很多人直接接也能用但长期可靠性存疑。稳妥做法是在DOUT和STM32引脚之间串一个1kΩ电阻再在STM32引脚端加一个3.3V稳压二极管钳位。我实际用的是1kΩ串阻加BAV99双二极管钳位到3.3V和地成本几毛钱保护到位。显示部分我用的是0.96寸OLEDSSD1306驱动I2C接口接PB6SCL和PB7SDA。为什么不用LCD16021602需要8根数据线加3根控制线占用IO太多而且显示内容有限。OLED只需要2根线显示重量、单位、状态信息绰绰有余功耗也低。按键用了三个去皮PB0、校准PB1、单位切换PB2都配置为上拉输入按下接地。电源部分整个系统用一个5V/1A的USB适配器供电STM32板上有AMS1117-3.3把5V降到3.3V给MCU和OLED。HX711和传感器直接用5V。注意模拟部分和数字部分的电源要分开走线在电源入口处单点接地否则数字噪声会串到模拟信号里读数跳动会明显增大。2.3 关键元器件的选型对比器件型号选型理由替代方案主控STM32F103C8T6资源足、资料多、价格低STM32F030、GD32F103ADCHX711集成PGA、24位、两线接口CS5530、ADS1232传感器5kg悬臂梁量程合适、灵敏度1mV/V3kg或10kg同类型显示0.96寸OLEDI2C省IO、显示清晰LCD1602、数码管稳压AMS1117-3.3通用、便宜LM1117、RT9013实操心得HX711模块买回来先别急着焊用万用表测一下模块上E和E-之间的电压应该是5V如果供5V。再测A和A-之间的电压空载时应该在0V附近偏差不超过几毫伏。如果偏差大可能是模块焊接不良或芯片损坏。我买到过一批HX711模块其中有一个A和A-之间始终有30mV偏移换芯片后正常这种不良品率大概在2%左右。3. 软件架构与核心算法实现3.1 HX711驱动时序与数据读取HX711的通信协议很简单但时序要求严格。当DOUT为高电平时表示数据未准备好DOUT变低后表示数据可以读取。此时给PD_SCK发送25到27个时钟脉冲前24个脉冲在上升沿时DOUT输出数据位MSB先行第25个脉冲用于选择下一次转换的通道和增益。具体对应关系第25个脉冲数决定下次通道1个脉冲选通道A增益1282个脉冲选通道B增益323个脉冲选通道A增益64。我用的读取函数如下uint32_t HX711_Read(void) { uint32_t data 0; uint8_t i; while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) GPIO_PIN_SET); // 等待DOUT变低 for(i 0; i 24; i) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); data 1; if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) GPIO_PIN_SET) data; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); } // 第25个脉冲选择通道A增益128 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); data ^ 0x800000; // 24位有符号数转无符号偏移 return data; }这里有个细节HX711输出的是24位二进制补码最高位是符号位。为了后续计算方便我把它异或0x800000转换成0到16777215的无符号数这样零点对应中间值。如果不做这个转换直接当有符号数处理也可以但要注意数据类型转换时的符号扩展问题。3.2 数字滤波与去极值平均原始读数跳动是必然的即使传感器空载读数也会在几十到几百个LSB之间波动。我用了两级滤波第一级是去极值平均连续采样10次去掉最大值和最小值剩下8个求平均第二级是一阶低通滤波系数0.2进一步平滑。#define SAMPLE_COUNT 10 #define FILTER_ALPHA 0.2f int32_t Get_Weight_Raw(void) { int32_t samples[SAMPLE_COUNT]; int32_t sum 0, max, min; uint8_t i; for(i 0; i SAMPLE_COUNT; i) { samples[i] HX711_Read(); } max samples[0]; min samples[0]; for(i 0; i SAMPLE_COUNT; i) { if(samples[i] max) max samples[i]; if(samples[i] min) min samples[i]; sum samples[i]; } sum sum - max - min; return sum / (SAMPLE_COUNT - 2); } float Get_Weight_Filtered(void) { static float filtered 0; int32_t raw Get_Weight_Raw(); if(filtered 0) filtered (float)raw; else filtered FILTER_ALPHA * (float)raw (1 - FILTER_ALPHA) * filtered; return filtered; }去极值平均能有效抑制突发噪声比如电源波动或机械振动引起的尖峰。一阶低通滤波则让读数变化更平滑但会引入滞后。系数0.2意味着新数据占20%权重旧数据占80%响应时间大约5个采样周期。如果采样率是10Hz响应时间约0.5秒对于电子称来说可以接受。如果追求更快响应可以把系数调到0.3到0.4但读数跳动会变大。注意HX711的采样率由RATE引脚决定接低电平是10Hz接高电平是80Hz。我建议用10Hz因为80Hz模式下噪声明显增大而且电子称不需要那么快的刷新率。10Hz配合上面的滤波读数非常稳最后一位基本不跳。3.3 标定算法与线性度校正标定是电子称精度的关键。我用的是两点标定法空载时记录零点值放上已知重量的砝码记录满量程值计算斜率。float zero_offset 0; float scale_factor 1.0f; void Calibrate_Zero(void) { zero_offset Get_Weight_Filtered(); } void Calibrate_Span(float known_weight) { float raw Get_Weight_Filtered(); scale_factor known_weight / (raw - zero_offset); } float Get_Weight(void) { float raw Get_Weight_Filtered(); return (raw - zero_offset) * scale_factor; }理论上应变片传感器的线性度很好满量程非线性误差通常小于0.05%所以两点标定足够。但如果要求更高可以做多点标定加分段线性插值。我实测用5kg传感器在0到5kg范围内两点标定后最大误差出现在2.5kg附近约±2g满足1g分辨率的要求分辨率是能分辨的最小变化精度是绝对误差两者不同。标定时砝码的选择有讲究。不要用一袋米或一瓶水那些标称重量不准。我用的是标准砝码1kg和5kg各一个。如果没有砝码可以用已知精度的厨房秤称出一袋白糖作为参考但精度会打折扣。标定时的环境温度要接近使用温度因为应变片有温度漂移温度变化10°C可能引起零点漂移几十克。3.4 OLED显示与按键交互逻辑显示部分我做了三行布局第一行显示重量数值大字体第二行显示单位g或kg第三行显示状态稳定、去皮、超载。SSD1306的驱动网上很多我用的是硬件I2C速率400kHz刷新一屏约20ms不影响采样。按键处理用状态机每个按键20ms消抖。去皮键按下后把当前重量作为新的零点偏移显示归零。再按一次取消去皮恢复原始零点。校准键长按3秒进入校准模式此时显示提示信息先空载确认再放砝码输入重量值。单位切换键在g和kg之间切换切换时重新计算显示值。void Key_Scan(void) { static uint8_t key_lock[3] {0, 0, 0}; static uint16_t key_cnt[3] {0, 0, 0}; for(int i 0; i 3; i) { if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0 i) GPIO_PIN_RESET) { if(key_cnt[i] 1000) key_cnt[i]; if(key_cnt[i] 20 !key_lock[i]) { key_lock[i] 1; Key_Handler(i); } } else { key_cnt[i] 0; key_lock[i] 0; } } }实操心得OLED的I2C地址通常是0x78或0x7A取决于模块上的电阻配置。如果屏幕不亮先用I2C扫描程序确认地址。另外OLED的VCC和GND不能接反接反会烧毁模块我烧过两个都是因为排线插反了。建议在排线座上做防呆标记。4. 常见问题排查与实战避坑指南4.1 读数跳动大或不归零这是最常见的问题。排查顺序如下先看电源用示波器测HX711的VCC和AVDD引脚纹波应该小于10mV。如果纹波大在VCC和GND之间并一个100μF电解电容加一个0.1μF陶瓷电容。再看传感器接线E和E-之间电压是否稳定A和A-之间空载电压是否接近0。如果A和A-之间有几十毫伏的固定偏移可能是传感器贴片不良或HX711损坏。还有一个容易被忽略的原因机械结构。传感器必须一端固定一端悬空受力如果两端都固定死或者受力点不在设计位置会产生侧向力或扭矩导致读数漂移。我第一版结构用亚克力板做秤盘四角支撑结果四角受力不均读数随放置位置变化。后来改成单点悬臂结构秤盘只压在传感器受力端问题解决。4.2 HX711数据读取失败或全为0如果DOUT一直为高说明HX711没有完成转换。检查PD_SCK是否在初始化时给了足够多的时钟脉冲让HX711复位。上电后HX711需要至少一个完整的转换周期10Hz模式下100ms才能输出有效数据。如果DOUT一直为低可能是PD_SCK时序不对或者HX711供电不足。还有一种情况是读出来的数据全是0xFFFFFF或0x000000这通常是接线错误或传感器断路。用万用表测传感器四根线之间的电阻E和E-之间约1kΩA和A-之间约1kΩE和A之间约1kΩ。如果某对之间电阻无穷大说明传感器内部断线。4.3 标定后精度不达标先确认砝码是否准确。我用过一批标称1kg的砝码实际用高精度天平称出来是998g差了2g。如果砝码不准标定出来的斜率就是错的。其次检查零点漂移空载放置10分钟看读数变化。如果漂移超过5g说明温度补偿没做好或者传感器质量不行。还有一个隐藏问题HX711的增益选择。如果传感器灵敏度太高满量程输出超过20mVHX711会饱和读数卡在最大值附近。这时候需要降低激励电压或换低灵敏度传感器。反过来如果灵敏度太低满量程输出只有1mV有效位数不够分辨率上不去。4.4 常见问题速查表现象可能原因排查方法解决措施读数跳动大电源纹波大示波器测VCC加滤波电容读数不归零传感器机械应力检查安装结构调整受力方式DOUT一直高HX711未复位检查上电时序增加初始化延时数据全0或全1接线错误万用表测通断重新接线标定后误差大砝码不准用高精度天平校验更换标准砝码温度漂移明显传感器温漂不同温度下测零点加温度补偿算法OLED不亮I2C地址错误I2C扫描修改地址按键无响应上拉电阻未接测引脚电平启用内部上拉避坑技巧HX711的PD_SCK引脚在空闲时必须保持低电平。如果配置成高电平HX711会进入掉电模式DOUT一直为高。我在初始化时忘了把PD_SCK拉低调试了半天才发现。另外STM32的HAL库默认把GPIO配置成推挽输出但HX711的PD_SCK需要的是开漏输出吗不需要推挽就可以但要注意电平匹配。4.5 提高精度的几个实战技巧第一个技巧是多次采样取平均。我把采样次数从10次提高到50次读数标准差从3g降到1g以内。代价是响应变慢50次在10Hz下需要5秒对于静态称重可以接受动态称重就不行了。折中方案是动态调整采样次数读数变化大时用10次快速响应读数稳定后用50次提高精度。第二个技巧是数字滤波器的系数自适应。当重量变化超过阈值时把低通滤波系数临时调大加快响应当重量稳定时系数调小抑制噪声。这个逻辑用状态机实现效果比固定系数好很多。第三个技巧是定期自动零点跟踪。电子称空载时如果读数在零点附近小幅波动可以缓慢调整零点偏移补偿温漂。但要注意如果秤上一直有东西自动跟踪会把重量也“跟踪”掉。所以自动跟踪只在读数接近零点且变化率很小时启用。5. 系统联调与性能实测5.1 联调步骤与观察指标硬件焊接完成后不要急着上电。先用万用表测各路电源对地电阻确认没有短路。然后单独给STM32下载一个串口打印程序确认MCU工作正常。再单独测试HX711用串口打印原始读数观察空载和加载时的变化。最后接上OLED和按键整体联调。联调时我重点观察三个指标零点稳定性、重复性、线性度。零点稳定性是空载放置30分钟读数最大值和最小值之差我的系统做到了±1g以内。重复性是同一砝码反复加载10次每次读数的标准差实测±1.5g。线性度是0到5kg范围内每隔1kg测一次与标准值的偏差最大偏差出现在2kg处约2g。5.2 实测数据记录标准重量(g)第一次读数(g)第二次读数(g)第三次读数(g)平均偏差(g)00000500501500499010001001100010000.320002002200120011.330003001300030000.340004001400040000.350005002500150011.3从数据看最大偏差1.3g满足1g分辨率下的合理精度。偏差在2kg和5kg处稍大可能是传感器非线性或砝码误差。整体性能对于一般称重应用足够。5.3 功耗与稳定性测试整个系统工作电流约30mA其中STM32约20mAOLED约5mAHX711和传感器约5mA。用5V/1A适配器供电连续工作8小时读数漂移小于2g。如果改用电池供电可以加一个电源开关不用时关断。HX711有掉电模式把PD_SCK拉高即可进入电流降到1μA以下但重新唤醒需要等待转换周期。注意长时间工作时AMS1117-3.3会发热手摸有点烫是正常的但不要超过60°C。如果烫手说明负载电流太大或输入电压太高。可以在AMS1117上贴一个小散热片或者换用开关电源芯片如MP1584。6. 功能扩展与后续升级方向这个基础版本做完后可以扩展的方向很多。加一个蓝牙模块HC-05或JDY-31把重量数据传到手机App做成智能秤。加一个SD卡模块记录称重数据和时间戳用于物流或仓储。加一个继电器输出做成定量控制比如达到设定重量时触发报警或停止加料。软件上可以加入更复杂的滤波算法比如卡尔曼滤波进一步抑制噪声。也可以做多点标定加分段线性插值提高全量程精度。还可以加入温度传感器DS18B20做温度补偿解决温漂问题。如果要做成产品PCB设计要重新布局模拟部分和数字部分严格分区传感器信号走差分线包地处理。外壳用3D打印或注塑秤盘用不锈钢或玻璃。这些就是另一个层面的工作了。我个人在实际操作中的体会是电子称这个项目看似简单但每一个环节都有细节。传感器安装的机械结构、HX711的电源质量、滤波算法的参数、标定用的砝码精度任何一个环节出问题最终精度都上不去。我前后改了四版硬件才把读数跳动从±10g压到±1g。如果你也在做类似的项目建议先把HX711和传感器单独调通看到稳定的原始数据后再做后续开发这样排查问题会容易很多。
返回列表