ARTICLE DETAIL

资讯详情

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

HX711称重程序设计:从硬件接线到零点追踪的完整实战指南

HX711称重程序设计:从硬件接线到零点追踪的完整实战指南 简介一份基于51单片机的HX711高精度称重程序工程包面向嵌入式从业者、电子爱好者及实验室场景用于解决称重传感器的微弱信号采集与稳定测量问题。程序围绕HX711芯片24位Σ-Δ型ADC编写涵盖初始化配置、数据读取与累计平均、增益调整、软件滤波等核心模块可直接编译烧录也可借鉴其轮询逻辑与校准思路。压缩包共15个文件仅22KB以C语言源码、HEX烧录文件、STARTUP.A51启动代码及Keil UV2工程文件为主另有LST列表文件、OBJ目标文件等编译辅助产物便于查看编译过程与调试信息。目前已有1338人学习下载程序在多数场合下基本可用但需要根据传感器量程和灵敏度微调校准系数、时钟延时等参数适配后即可用于工业配料、实验室称重等场景。整体来看这套工程轻巧实用文件组织清晰既适合新手入门HX711驱动开发也为二次修改提供了可直接运行的工程基础。 HX711 这个芯片在电子秤、小量程测力、压力检测这些项目里太常用了。不管你是做 Arduino 小玩具、STM32 工控板还是树莓派扩展模块只要涉及应变式压力传感器基本绕不开它。我最初接触 HX711 是为了做一个仓储用的简易称重终端当时被零点漂移这东西折腾得不轻后面才彻底搞懂了它的底层逻辑和程序层面的补偿思路。这篇博文就围绕 HX711 称重程序的完整落地流程来写从硬件接线到代码框架再到零点追踪的实现细节最后附上实际调试中遇到的典型坑和排查方法给正准备做称重功能的朋友一份能直接照着干的参考。1. 整体设计与选型思路1.1 为什么选 HX711 而不是其他 ADC做称重方案时第一反应可能是直接用单片机自带的 ADC 去采集传感器信号。我最初也是这么想的省一片芯片板子还能做小一点。但实际测下来就会发现单片机的 12 位或 16 位 ADC 在称重这种低速高精度场景下有几个硬伤一是内部参考电压温漂明显数据会随着板温变化慢慢跑偏二是信号输入端没有专用的低噪声增益级毫伏级别的微弱信号直接会被噪声淹没三是没有专门的稳定激励源电桥传感器的供电波动会直接转化为测量误差。HX711 这类专用的桥式传感器 ADC 芯片本质上是把“稳压供电激励 可编程增益放大器 高精度 Δ-Σ ADC 数字滤波”打包在了一起。它内部集成了稳压电路能给电桥传感器提供稳定的 5V 或 2.6V 激励PGA 增益支持 32、64 和 128 倍选择能把传感器输出的毫伏级差分信号放大到 ADC 能分辨的水平核心的 24 位 Δ-Σ ADC 保证了分辨率而通过简单的串行时序读数据也让程序驱动变得相当直白。对于称重这种每秒采样几十次就够用的场景HX711 在成本、性能和开发难度上是最平衡的选择。1.2 完整方案组成一个可靠的称重系统不只是一片 HX711 加一个传感器那么简单。我的建议是把整个项目拆成几个模块来看传感器部分常见的是铝制或钢制悬臂梁式应变传感器量程根据项目选100g、1kg、5kg、20kg 都有。选型时注意灵敏度参数一般是 1.0mV/V 或 2.0mV/V这决定了 HX711 的增益档位选择。信号调理与采集就是 HX711 芯片及其外围电路包括去耦电容、电源滤波、传感器接口。主控逻辑单片机负责配置 HX711、读取原始值、做数字滤波、执行零点追踪和标定计算最终把 ADC 原始码换算成重量值。交互输出OLED/LCD 显示、串口输出、蓝牙上传、继电器控制等按项目需求来。软件层面我习惯把代码分成三层最底层是 HX711 的驱动层只负责时序读写中间是称重逻辑层处理标定系数、零点、滤波算法最顶层才是业务层比如显示、报警、数据上报。这样分层的好处是换传感器或换主控时只需要改驱动层或者重新标定核心算法不需要大动。2. HX711 硬件接线与关键信号解析2.1 引脚功能与接线要点HX711 常用的是 SOP-16 封装引脚不算多但接线时有几个细节容易踩坑。核心引脚包括VSUP、AVDD、DVDD电源相关引脚。我用的是 Arduino 5V 供电方案VSUP 接 5VAVDD 通过一个 10Ω 电阻接到 VSUPDVDD 直接用 3.3V 或 5V 都可以。VFB、BASE、VREG内部稳压输出引脚。习惯上把 VREG 和 BASE 之间接一个 0.1μF 电容VFB 和 AVDD 之间接一个 1μF 电容确保稳压环路稳定。HX711 的模拟电源 AVDD 会通过 VFB 引脚和芯片内部稳压产生接传感器电桥的激励正端。E、E-、S、S-传感器接口分别接电桥的激励正、激励负、信号正、信号负。PD_SCK 和 DOUT数字接口PD_SCK 是时钟输入同时负脉冲还能控制芯片进入掉电模式DOUT 是数据输出。接线方面我的经验和很多新手教程不太一样传感器和 HX711 之间的连线尽量短并且用双绞线或者屏蔽线。应变式传感器输出的是差分信号好处是抗共模干扰但如果两根信号线走了不同的路径引入的差模噪声就会直接叠加到信号上。我实测过用普通跳线长距离飞线和用双绞线连接同样滤波算法下数据稳定度差距能达到好几倍。2.2 模拟电源去耦与接地策略HX711 的数据手册里推荐了外围电路但我实际做下来还有几个补充要点。第一10μF 钽电容和 0.1μF 陶瓷电容并联放在 AVDD 对地这组去耦电容的位置要尽量靠近芯片电源引脚千万别图省事放得远远的。第二数字地和模拟地最好单点汇合如果板子上空间允许可以在 HX711 芯片下方把 AGND 和 DGND 统一接在一个地平面区域。我最早打样时没太在意结果读出来的数据有周期性的低频波动查了很久才发现是地环路引入了干扰。关于增益档位HX711 支持 128 和 64 倍增益其中 128 倍对应通道 A64 倍可以切换到通道 B。称重场景用通道 A 128 倍增益是默认配置读数据时在 DOUT 拉低后的第 25 个脉冲上升沿之前需要先输出 25 个脉冲其中前 24 个是数据位第 25 个决定下一次读取的增益和通道。具体来说第 25 个脉冲为高电平时选择通道 A 的 128 倍增益低电平时选择通道 B 的 32 倍增益。程序里必须严格按这个时序来否则读出来的数据通道就乱了。3. 称重程序核心逻辑拆解3.1 数据读取时序理解HX711 的串行接口非常简单但实际上手时很多朋友会把时序搞混淆。整个读取流程是这样的等待 DOUT 引脚从高电平变为低电平这个下降沿表示 ADC 转换完成数据已经就绪。在 PD_SCK 上产生 24 个脉冲每个脉冲的上升沿读取 DOUT 引脚电平从最高位第 1 个脉冲到最低位第 24 个脉冲依次组成一个 24 位二进制数。产生第 25 个脉冲用于设置下一次转换的通道和增益。有一个很容易被忽略的点第 25 个脉冲的上升沿或下降沿并不真正影响本次已经读出的数据它影响的是下一次的转换。所以如果你的代码在第 25 个脉冲之后立即就去读数据可能读到的还是旧数据需要等待 DOUT 再次拉低。另一个大坑是24 位数据是有符号的。当传感器受正压力时数据是正数无负载时接近零如果传感器接反或者受到拉力数据可能变成负数。如果程序里把它当成无符号数处理负值就会变成很大的正数整个标定就直接废了。解释一下有符号问题HX711 输出的是二进制补码格式。最高位是符号位当最高位为 1 时表示负数。在 C 语言里如果你把数据读入一个 unsigned long 类型的变量再强制转成 long编译器会按照变量类型的位宽来解释通常不会出错。但如果你用的是某些脚本语言或平台可能就要手动做符号扩展。3.2 零点追踪的原理与必要性最近不少朋友在搜“hx711 零点追踪”这个关键词说明大家在实际项目里都遇到了同一个麻烦传感器在空载时的读数不是固定的而是会随时间缓慢漂移。这个漂移的来源主要有三个温度漂移应变片的电阻值随温度变化即便没有任何负载电桥的输出也会发生变化。机械蠕变传感器弹性体在长时间受力后会产生微小的形变恢复过程卸载后读数要过一段时间才能稳定回原来的零点。电路漂移HX711 的模拟前端、参考电压、PGA 增益都会随温度和时间产生微小变化。如果不做零点追踪一个 1kg 量程的秤早上开机可能显示 0.0g到了中午可能就变成 2.3g 或者 -1.7g。当然你可以用去皮功能在每次称重前手动清零但很多应用场景是不允许每次都去按一下去皮键的。零点追踪Zero Tracking就是在软件中自动检测并修正这个漂移当系统判断当前处于空载状态时把当前的读数慢慢吸收到零点参考值中使显示重量始终回到零附近。这里有一个关键逻辑什么时候算“空载”如果重量一直稳定在一个值附近比如 0.1g 以内并且持续了几秒钟就可以认为是空载。但如果你设定一个触发阈值比如 0.3g那么任何小于 0.3g 的负载都会被自动清零。这在称重精度要求高的场景下是绝对不能接受的。所以零点追踪的触发条件必须包含“稳定”和“持续时间”两个维度而不能只看瞬间值。3.3 数字滤波与平滑策略HX711 原始数据其实是很吵的即便在静态负载下最低几位也会跳动。这个跳动幅度取决于传感器量程、激励电压、布线质量和电源干净程度。比如我那个仓储称重项目5kg 量程的传感器在无负载时原始 ADC 值跳动大概在 ±5 个码左右换算成重量大约是 ±0.05g。这个跳动看起来不大但如果直接显示到小数位数字还是会来回跳观感很差。解决思路是数字滤波但我建议不要一上来就上特别复杂的滤波算法。先搞清楚你的项目需要多高的响应速度如果是静态称重比如厨房秤、电子秤那用滑动平均或一阶低通滤波就够了如果是动态称重比如在线分选设备滤波就要适当减弱否则动态响应会拖后腿。我常用的组合是先做一个 4 次采样的中位值滤波去掉明显的毛刺再做 8 点滑动平均进一步平滑。中位值滤波能有效去除脉冲干扰滑动平均则能压低随机噪声。这个组合计算量小在 Arduino 这种 8 位单片机上跑也毫无压力。4. 完整称重程序实现与标定流程4.1 核心代码框架这里给出一份可以在 Arduino 平台上直接跑通的程序结构上做了分层方便移植到其他平台。底层驱动部分我没有直接用现成的库而是自己写这样能更好地理解时序细节。首先定义一下接线和常量#define PIN_DOUT 3 #define PIN_SCK 2 float calibration_factor 106.0f; // 标定系数由标定流程得出 float zero_offset 0.0f; // 零点偏移用去皮或者零点追踪更新HX711 的底层读取函数如下long HX711_Read() { while (digitalRead(PIN_DOUT)); // 等待 DOUT 变低表示数据就绪 long raw 0; for (int i 0; i 24; i) { digitalWrite(PIN_SCK, HIGH); delayMicroseconds(1); raw (raw 1) | digitalRead(PIN_DOUT); digitalWrite(PIN_SCK, LOW); delayMicroseconds(1); } digitalWrite(PIN_SCK, HIGH); // 第 25 个脉冲设置下一次为通道 A 128 倍增益 delayMicroseconds(1); digitalWrite(PIN_SCK, LOW); delayMicroseconds(1); if (raw 0x800000) { // 符号扩展处理 24 位有符号数 raw | 0xFF000000; } return raw; }这里最关键的是符号扩展那一行。HX711 返回的 24 位数据如果最高位是 1说明是负数需要把高 8 位全部补 1才能得到在 32 位有符号整数中正确的负数值。很多库没有这一步结果在测拉力或传感器反向安装时数据就错了。4.2 标定流程与系数计算拿到原始 ADC 值之后怎么换算成重量核心公式是重量 (当前原始值 - 零点原始值) / 标定系数其中零点原始值就是空载时的平均 ADC 读数标定系数表示每产生 1g 重量对应的 ADC 码变化量。标定的目的是确定这个系数。我的标定流程是这样的空载状态下连续读取 50 次原始值取平均作为零点原始值。放上一个已知重量的标准砝码比如 500g等待读数稳定连续读取 50 次取平均。计算标定系数系数 (砝码平均原始值 - 零点原始值) / 砝码重量单位是“ADC 码/g”。以我的仓储称重项目为例5kg 量程传感器在 128 倍增益下空载零点原始值大约在 8388608 附近24 位 ADC 的中心值放上 500g 砝码后读数约 8898608那么标定系数 (8898608 - 8388608) / 500 102000 / 500 204 码/g这个系数可以直接写死在程序里也可以通过串口命令在线修改方便后期校准。如果换了一个传感器或者改变了激励电压、增益档位这个系数一定要重新标定。4.3 零点追踪的工程实现零点追踪的代码实现要小心不要在秤上有长期小负载时把真实重量慢慢“吃掉”。我采用的做法是设定一个触发窗口比如 ±5 个 ADC 码对应约 0.025g。只有当连续 2 秒内滤波后的原始值都落在这个窗口内才认为处于空载状态。在空载状态下每个控制周期把当前读数以极小的步长逼近零点比如每次只调整零点值的 0.1%这样即使误判修正速度也很慢不会产生明显误差。一旦检测到读数超出触发窗口立即冻结零点追踪防止把负载吸收掉。代码逻辑大致如下float filtered_value; // 滤波后的重量,单位g float display_weight; // 最终显示重量 float zero_ref 0.0f; // 当前零点重量参考 bool zero_track_enabled true; void updateZeroTracking(float current_weight) { if (!zero_track_enabled) { zero_ref current_weight; // 手动去皮时直接更新 zero_track_enabled true; return; } static int stable_count 0; if (fabs(current_weight - zero_ref) 0.05f) { // 在零点附近 stable_count; if (stable_count 100) { // 大约2秒稳定 zero_ref (current_weight - zero_ref) * 0.01f; // 缓慢追零 } } else { stable_count 0; } zero_offset zero_ref; }这种慢速追踪有几个好处一是对真实漂移有良好的跟随性二是即使判断失误也不会瞬间跳变三是实现简单不需要高深的控制理论。如果你做的是计重秤还可以增加一个“半自动”零点追踪逻辑也就是只在开机时和空载超过 5 秒时执行一次快速追零中间不进行追踪这样能兼顾响应速度与精度。5. 常见问题与调试经验实录5.1 数据跳动过大的排查我遇到的最典型问题是数据一直在较大范围内跳动排查步骤如下第一步确认传感器和 HX711 的电源是否干净。检查 HX711 的 AVDD 电源引脚处是否有明显的纹波用万用表的交流档测量一下如果超过 20mV说明电源滤波不够。建议在 VSUP 和 AVDD 处分别增加 100μF 电解电容并确认 0.1μF 陶瓷电容离芯片引脚足够近。第二步检查传感器信号线是否受到了数字信号干扰。PD_SCK 和 DOUT 线在翻转时会带来高频噪声如果它们和 S、S- 信号线平行走线过长噪声会耦合到模拟信号上。我自己试过把信号线从主控板下面穿过结果数据跳动明显增加后来改成双绞线并远离数字线才恢复。第三步检查滤波算法的截止频率是否匹配你的采样速度。HX711 内置的滤波带宽大概在 10Hz如果你的程序采样周期是 10ms那采样速度已经接近内置滤波器带宽了此时再叠加数字滤波要注意相位滞后。可以用示波器观察一下滤波前后的数据曲线如果滤波后数据存在明显滞后导致放上砝码后要等很久才稳定说明滤波深度过大需要平衡。5.2 标定系数漂移问题有些朋友反映标定好的系数过几天再测就不准了。这里面有几种可能传感器本身受到过超范围冲击导致弹性体产生永久形变灵敏度发生了改变。这类情况只能换传感器。激励电压漂移。如果 AVDD 不稳电桥输出电压和 ADC 参考电压可能会不成比例地变化导致标定系数改变。检查方法是在标定前、后分别测量 E 对地的电压如果偏差超过 5mV就要检查供电。温度引起的灵敏度变化。应变式传感器的灵敏度温漂是物理特性无法完全消除但可以通过软件温漂补偿来优化。如果项目工作环境温度变化大可以在系统中增加温度传感器通过查表或拟合公式修正标定系数。我在仓储项目里做过一个简单的温漂补偿在 10℃ 到 40℃ 范围内做了一组标定实验发现 5kg 量程传感器的系数大约每 10℃ 变化 0.3%于是我在软件里加了温度查表修正把最大误差从原来的 2.5g 降到了 0.6g。如果你的项目也在宽温环境下工作这个方法可以参考。5.3 零点追踪误判与应对零点追踪最大的风险是“把重量吃掉”。为了验证这个问题我专门做了一个实验在秤面上放一个 50g 的重物让程序连续运行 10 分钟观察重量是否被逐渐修正掉。结果是由于 50g 远大于 0.05g 的触发窗口追踪逻辑会立即冻结重量完全不会被改动。但如果放的是 0.1g 的轻物并且秤的机械结构稳定程序会判断为空载漂移并把它慢慢归零。这在某些高精度应用场景下是不允许的所以如果你做的是实验室用秤或者微量秤建议把零点追踪功能做成可配置的默认关闭或者把触发窗口设置为更小的档位。另一个值得注意的坑是机械结构引起的零点回滞。比如秤盘被碰了一下传感器受力后变形之后虽然没有任何负载但机械结构无法完全回到原来的状态零点读数可能偏移了比较多。此时零点追踪因为触发窗口太小而无法自动修正就需要用户手动去皮。我在程序里做了一个简单处理如果空载状态的读数偏移超过 50 个 ADC 码就自动执行一次快速去皮相当于半自动的零点恢复。6. 工程化落地时的一些额外心得说实话HX711 驱动本身不难难的是把“能用”变成“好用”。我踩过几次坑之后总结了几个小技巧第一采样频率不要一味求快。HX711 内部 ADC 的最高输出速率可以设到 80Hz速率由 PD_SCK 高电平时间控制但实际称重场景特别是静态称重40Hz 就完全够用了。降低采样率可以更充分地发挥内置滤波器的效果数据更平滑。如果项目需要动态响应可以适当提高但要在后端加更强的数字滤波器。第二在批量生产或长期运行的项目里最好把标定参数、零点数据存在 EEPROM 或 Flash 中避免每次断电后重新标定。开机时先读取保存的参数并用一个简短的自检流程验证数据是否合法。比如标定系数如果超出合理范围就说明存储区可能被写坏或者从未标定过此时应提示用户重新标定而不是带病运行。第三PCB 布局上HX711 尽量靠近传感器接口减少模拟信号走线长度。芯片底部的散热焊盘如果有就接到地平面上去能改善一点热稳定性能对零点漂移有微小的正面帮助。第四如果用 HX711 做多路称重比如一台设备上有 4 个称重点一定要让每片 HX711 的 PD_SCK 独立控制DOUT 可以共用总线也可以分别接引脚。但要注意SCK 时钟频率不宜太高否则数字噪声会通过公共电源耦合到模拟部分影响数据质量。最后再分享一个我在实际项目中使用的调试技巧在开发时把原始 ADC 值、滤波后重量值、零点参考值、追踪状态全部通过串口打印出来用曲线绘图工具比如 SerialPlot 或 Arduino Plotter实时观察。你会发现很多看起来奇怪的“软件Bug”本质上是硬件层面的干扰通过这种方式能很快定位问题源头。如果你正在做或者准备做称重相关项目希望这篇内容对你有实际的帮助。HX711 只是一个基础模块真正决定一个称重系统好不好用的是电磁兼容处理、标定流程和长期稳定性的软件补偿策略。这些细节往往比多写几行代码更重要。本文还有配套的精品资源点击获取
返回列表