HX711 称重传感器放大器
| 器材 | 数量 | 参考 |
|---|---|---|
| HX711 模块 + 称重传感器(load cell) | 1 | — |
价格随渠道波动,以购买页实时为准。
想自己做个电子秤,或者给一桶咖啡豆、一仓饲料装个"还剩多少"的监测——绕不开一个问题:重量怎么变成数字?答案是一对搭档。承重的那块金属叫称重传感器(load cell),它受力会产生一个微弱到几乎读不出的电信号;HX711 就是专门伺候它的那颗芯片,把这点微弱信号放大几百倍、再用高分辨率 ADC 数字化,送进主控。两根线、一段标定代码,桌上的杂物就能被秤到零点几克的精度。
工作原理
要理解 HX711,得先看它服务的对象——称重传感器内部到底发生了什么。
称重传感器(load cell)= 应变片 + 惠斯通电桥。 那块铝合金或钢的金属梁上,贴着四片"应变片"。应变片是一根极细的金属箔,被拉长时电阻变大、被压缩时电阻变小。金属梁受力会发生肉眼看不见的微小形变(弹性形变),四片应变片随之电阻发生微变。这四片应变片接成一个"惠斯通电桥"——一个四臂的电阻桥路,外加一个激励电压(HX711 提供,约 45V)。没受力时电桥平衡、输出为 0;一受力,四个臂的电阻一升一降打破平衡,电桥两端就输出一个差分电压。问题在于:这个电压极其微弱,量级只有毫伏甚至更小——满量程往往只有激励电压的千分之一二(典型 12 mV/V),加 5V 激励满载也就几毫伏。普通单片机的 ADC 根本分辨不出这么小的变化。
HX711 = 高倍放大器 + 24 位 ADC。 HX711 干两件事:先把电桥输出的毫伏级差分信号放大(A 通道默认放大 128 倍),再用一个 24 位 ADC 把放大后的电压数字化。24 位意味着理论上能区分 2²⁴ ≈ 1600 万个台阶,配合 128 倍前置放大,对那点微弱信号的分辨能力极高——这正是它能做到高精度称重的原因。芯片内部还集成了激励电源(给电桥供电)和稳压,外围几乎不用搭电路。
为什么不是 SPI 也不是 I2C。 HX711 用一套专用的两线时序,不是标准总线:一根 SCK(时钟)、一根 DT/DOUT(数据)。主控拉低观察 DT,DT 变低代表"数据就绪",然后主控在 SCK 上打 25~27 个脉冲,把这一次 24 位转换结果一位位移出来,同时用脉冲个数选择下次的通道和增益(25 个脉冲=A 通道 128 倍)。关于 ADC 怎么把电压变成数字,可以看模数转换原理;信号在"模拟"与"数字"之间的来回,参见数字与模拟。
一句话串起来:力 → 金属形变 → 应变片电阻微变 → 惠斯通电桥输出毫伏差分 → HX711 放大 128 倍 → 24 位 ADC 数字化 → 两线送给主控。
接线
分两段:HX711 ↔ ESP32 是数字两线;load cell ↔ HX711 是四根模拟线。
| HX711 | ESP32 | 说明 |
|---|---|---|
| VCC | 3.3V / 5V | 5V 供电信号更稳、噪声更小;3.3V 也能跑 |
| GND | GND | 共地 |
| DT (DOUT) | GPIO16 | 数据线,普通 GPIO 即可 |
| SCK | GPIO4 | 时钟线,由主控驱动 |
load cell 的四根线按颜色接到 HX711 的电桥端子(不同厂家颜色可能不同,以你模块的丝印为准):
| load cell 线 | 接 HX711 | 作用 |
|---|---|---|
| 红 E+ | E+ | 电桥激励正 |
| 黑 E- | E- | 电桥激励负 |
| 白 A- | A- | 信号输出负(差分) |
| 绿 A+ | A+ | 信号输出正(差分) |
四线接法是这里最容易翻车的地方:E+/E- 是给电桥供电的激励对,A+/A- 是读差分信号的输出对,两对不能混。万一读数方向反了(压下去数值变小),最简单的修法是把 A+ 和 A- 对调即可。HX711 用低电平判定数据就绪,这背后是简单的电压高低电平逻辑。
完整代码
用 bogde 的 HX711 库(库管理器搜 HX711 就有)。核心是 tare() 去皮和 set_scale() 标定系数两步,标定好之后 get_units() 直接返回克数。
#include "HX711.h"
const int DT_PIN = 16; // 数据线
const int SCK_PIN = 4; // 时钟线
HX711 scale;
// 标定系数:原始计数 / 克数。先填 1,跑标定算出真值后回填这里
float calibrationFactor = 1.0;
void setup() {
Serial.begin(115200);
scale.begin(DT_PIN, SCK_PIN);
Serial.println("空载去皮中,请勿放任何东西...");
delay(2000);
scale.tare(); // 去皮:把当前空载读数记为零点(皮重)
scale.set_scale(calibrationFactor); // 设置标定系数,之后读数即为克
Serial.println("准备就绪");
}
void loop() {
// get_units(n):取 n 次平均后,减皮重再除以标定系数,得到克数
float grams = scale.get_units(5);
Serial.printf("重量: %.1f g\n", grams);
// 想看标定前的原始计数,用 read_average()
// Serial.printf("原始: %ld\n", scale.read_average(5));
delay(300);
}
第一次跑时
calibrationFactor填 1,get_units()出来的是"没意义的大数"——别慌,这是要靠下一节标定算出来的。get_units(5)里的 5 是取 5 次平均,越大越稳但越慢,一般取 3~10。
你应该看到什么
打开串口监视器(115200):
- 空载、且已正确标定:读数在 0 上下小幅跳动(±0.几克的抖动是正常的)。
- 放一枚标准砝码(比如 100g):读数应接近 100,误差在百分之一两以内。
- 放杯水再拿走:数值随放上、拿走平滑地涨上去、回到 0。
- 没标定(系数还是 1):放东西数值会变,但显示的是几万、几十万的原始计数,不是克——这说明硬件通了,只差标定。
- 手指轻压传感器:读数立刻上升,松手回落,反应灵敏。
如果放东西数值纹丝不动、或者一直显示固定大数从不变化,多半是 load cell 四线接错或没接好,回去检查 E/A 两对线。
标定两步
标定就两件事,做完秤才有意义。第一步去皮,第二步求标定系数。
第一步:去皮(tare,空载置零)。 秤盘自身、传感器支架都有重量,这叫"皮重"。上电后在空载状态下调一次 scale.tare(),库会把此刻的读数记下来当作零点,之后每次读数都自动减掉它——这样秤上只放被测物时,显示的才是净重。这也是为什么很多电子秤有个"去皮/清零"键:放了容器后按一下,把容器重量也去掉。
第二步:求标定系数(scale)。 标定系数的定义是:原始计数 ÷ 克数,也就是"每一克对应多少个 ADC 计数"。求法很直白:去皮后放一个已知重量的物体(比如一枚 100g 砝码,或任何你能确认重量的东西),读出此刻的原始计数,再除以它的真实克数:
标定系数 = (放已知重量后的原始计数 - 空载原始计数) / 已知克数
例如空载原始计数约 0、放 100g 后读到 215000,则系数 = 215000 / 100 = 2150。把这个 2150 回填到代码的 calibrationFactor,重新烧录,之后 get_units() 内部就用 (原始 - 皮重) / 2150 算出克数。验证:再放那枚砝码,读数应该非常接近 100。换不同重量的砝码复测几次,确认线性没问题。这个系数只跟具体的 load cell 和 HX711 增益有关,标定一次记下来即可,不用每次开机重算。
选型 / 避坑
load cell 的量程怎么选——按"最大要称多重"选,并留余量。 量程是这颗传感器的承载上限,常见有 1kg / 5kg / 10kg / 20kg / 50kg 等。原则是:选一个略大于你最大被测重量的量程。量程选得越接近实际用量,分辨率越高(24 位的台阶分给更小的区间);选得过大,秤轻东西时精度就浪费了。比如做厨房咖啡秤(最多称几百克),选 1kg 的;做包裹秤(几公斤)选 5kg 或 10kg;做人体秤选 50kg 以上的。要更高采样速度或多路同时称,可以看 ADS1232 这类带多通道、更高速的称重 ADC。
称重项目最常见的几个坑:① 四线别接错——E+/E- 是激励对、A+/A- 是信号对,接混了读不出数,方向反了就把 A+ A- 对调;② 绝不能超载——施加超过量程的力会让金属梁发生不可逆的塑性形变,传感器永久损坏、再标定也回不来,安装时务必加机械限位防止压过头;③ 机械安装要让传感器正确受力——load cell 通常一端固定、另一端悬空受力(悬臂梁式),装反或两端都压死会读不准;④ 温漂——温度变化会让零点和系数轻微漂移,精密场合上电后预热几分钟再用、或做温度补偿;⑤ 上电预热——刚通电读数会缓慢爬一会儿,等它稳定再去皮。
故障排查
| 现象 | 原因 | 处理 |
|---|---|---|
| 读数乱跳、抖动大 | 接线松 / 供电有噪声 / 平均次数太少 | 焊牢四线、改用 5V 供电、get_units() 取更多次平均 |
| 读数固定不变,放东西也不动 | load cell 四线接错或断线 | 逐根核对 E+/E-/A+/A-,重新焊接 |
| 放东西方向反了(压下去变小) | 信号对接反 | 把 A+ 和 A- 两根线对调 |
| 读数不准、重复性差 | 没标定 / 机械安装不对 / 超载伤过 | 重做两步标定;检查传感器受力是否为悬臂式;确认没压过量程 |
| 零点缓慢漂移 | 没预热 / 温度变化 | 上电预热后再去皮;精密场合做温度补偿 |
| 数值偏大几万从不归零 | 标定系数还是 1 | 按上一节求出真实系数回填 calibrationFactor |
进阶 / 变体
给秤加一块 OLED 屏 显示克数,再加一个按键做"去皮"键,就是一台真正能用的桌面秤了——按一下按键调 scale.tare() 重新清零,放上容器先去皮、再倒咖啡豆,屏上直接显示净重。代码骨架很简单:
// 伪逻辑:按键去皮 + OLED 显示
if (digitalRead(BTN_PIN) == LOW) { // 检测到按下
scale.tare(); // 重新清零(去皮)
}
float grams = scale.get_units(5);
oled.printf("%.1f g", grams); // 显示在 OLED 上
再往上走,把称重数据接到判断逻辑里——比如"低于某重量就报警料快用完了",甚至把重量序列喂给模型识别"现在在称的是什么",就进入了传感器接 AI 的玩法。
典型应用
- 电子秤 / 咖啡秤:最经典的用途,加 OLED 和去皮键即可成品。
- 料仓 / 料位监测:靠整桶整袋的重量推算"还剩多少",比液位/光学方案更直接。
- 健身器材:测握力、配重、踏板压力。
- 力的测量:拉力、压力、张力测试,本质都是测力。
- 库存自动盘点:货架装秤,靠重量变化判断取了几件。
小结 · 相关
HX711 是 load cell 的"翻译官":把应变片惠斯通电桥那点毫伏微弱信号放大 128 倍、再用 24 位 ADC 数字化,两根线送给主控。用好它记住三件事——四线(E 对 / A 对)别接错、量程按最大重量留余量选、上电后做"去皮 + 已知重量求系数"两步标定。绝不超载,否则传感器永久报废。
参数以上方 datasheet 为准;本页公开资料整理,接线与代码请结合实物验证。