⚖️ ESP32 HX711 称重传感器实战:DIY 高精度电子秤
📅 2026-05-30 · 📂 硬件编程 · ⏱ 阅读约 7 分钟
📺 B站推荐视频:Arduino跨平台开发——HX711称重传感器——ESP32平台演示
📖 概述
称重传感器是物联网中最实用的传感器之一。从厨房电子秤、快递扫码称重、到智能货架库存管理,称重无处不在。今天我们要玩的 HX711 是一款专为称重传感器设计的 24 位高精度 ADC 芯片,只需两根数据线,就能把压力传感器的微弱电压信号转换成精确的重量数值。
为什么说 HX711 是"高手级"入门模块?它的 ADC 有 24 位分辨率(1677万级),比 ESP32 内置的 12 位 ADC(4096 级)高了三个数量级。配合惠斯通电桥结构的压力传感器,可以稳定分辨到 0.1g 的变化。今天你将学会:接线 → 校准 → 去皮 → 滤波平滑 → 配合 OLED 显示,打造一台媲美市售产品的智能电子秤。
💡 工作原理速览:压力传感器内部是一个惠斯通电桥,受力时电阻变化产生微伏级差分电压。HX711 内置 PGA(可编程增益放大器,128倍),将微伏信号放大后由 24 位 Σ-Δ ADC 转换为数字量,通过两线串行接口输出给 ESP32。
🛒 物料清单
| 物料 | 型号/参数 | 数量 | 参考单价 |
| 开发板 | ESP32-WROOM-32 | 1 | ¥18 |
| HX711 模块 | 绿色小板(带稳压、EMI滤波) | 1 | ¥3.5 |
| 压力传感器 | 5kg 电阻应变片半桥(配铝合金支架) | 1 | ¥6 |
| 面包板 + 杜邦线 | 830孔面包板 + 公母杜邦线若干 | 1套 | ¥8 |
| OLED 显示屏 | 0.96寸 SSD1306 I2C(128×64) | 1 | ¥8 |
| 砝码 | 标准砝码(100g/200g/500g 各一) | 1套 | ¥15 |
💰 总预算约 ¥58.5。如果没有标准砝码,可以用矿泉水瓶——500ml 瓶装水约 500g,精度足够日常校准。压力传感器建议选带铝合金支架的套装,固定好不易偏移。
🔌 接线图
HX711 模块有 4 个引脚连接 ESP32,另外 4 个引脚连接压力传感器(E+/E-/A+/A- 或红/黑/白/绿):
ESP32 → HX711 模块
─────────────────────
3.3V → VCC
GND → GND
GPIO16 → DT (数据引脚)
GPIO4 → SCK (时钟引脚)
压力传感器 → HX711 模块
─────────────────────
红线 (E+) → E+ (激励电压正)
黑线 (E-) → E- (激励电压负)
白线 (A-) → A- (信号输出负)
绿线 (A+) → A+ (信号输出正)
🔌 注意:HX711 模块建议接 ESP32 的 3.3V 而非 5V。虽然模块手册写着 2.7~5.5V 供电,但 AVDD 直接取自 VCC,3.3V 时传感器激励电压更稳定,ADC 噪声也更低。
💻 基础代码:读取原始值 + 校准 + 显示克数
安装 HX711 Arduino Library(作者:bogde),在 Arduino IDE 库管理器中搜索 "HX711" 即可安装。以下代码包含校准和去皮逻辑:
// ⚖️ ESP32 + HX711 电子秤完整示例
#include <HX711.h>
// 引脚定义
#define DOUT 16 // DT 接 GPIO16
#define SCK 4 // SCK 接 GPIO4
HX711 scale;
// 校准参数(需根据你的传感器实测调整)
const float CALIBRATION_FACTOR = -420.0;
void setup() {
Serial.begin(115200);
Serial.println("⚖️ HX711 电子秤启动中...");
scale.begin(DOUT, SCK);
// 设置校准因子
scale.set_scale(CALIBRATION_FACTOR);
// 自动去皮(假设启动时托盘为空)
Serial.println("⏳ 执行自动去皮,请确保托盘为空...");
delay(2000);
scale.tare();
Serial.println("✅ 去皮完成,准备就绪!\n");
}
void loop() {
// 读取重量(单位:克),多次采样取平均
float weight = scale.get_units(10);
// 滤除微小抖动(小于0.5g视为0)
if (abs(weight) < 0.5) weight = 0.0;
Serial.print("⚖️ 重量: ");
Serial.print(weight, 1);
Serial.println(" g");
delay(500);
}
🔧 如何获取校准因子
上面的 CALIBRATION_FACTOR 每个传感器都不同,需要实测获得。方法如下:
// 校准模式:获取 CALIBRATION_FACTOR
void setup() {
Serial.begin(115200);
scale.begin(DOUT, SCK);
scale.set_scale(); // 先清除校准
scale.tare(); // 空载去皮
Serial.println("放上已知重量砝码(如200g),等待读数稳定后记下 raw 值");
}
void loop() {
Serial.print("raw: ");
Serial.println(scale.get_units(10), 0);
long raw = scale.read_average(10) - scale.get_offset();
Serial.print("raw_avg: ");
Serial.println(raw);
// CALIBRATION_FACTOR = raw_avg / 砝码克数(如 200.0)
delay(1000);
}
💡 放上 200g 砝码后,假设 raw_avg 显示 -84200,则 CALIBRATION_FACTOR = -84200 / 200 = -421.0。把这个值填入正式程序的 set_scale() 即可。负号取决于传感器接线方向,不影响结果。
🚀 进阶应用
1. OLED 屏幕实时显示(联动第14课 OLED SSD1306)
串口看数据不够直观?把之前学的 0.96寸 OLED 加上,做个独立电子秤:
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <HX711.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
HX711 scale;
#define DOUT 16
#define SCK 4
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
scale.begin(DOUT, SCK);
scale.set_scale(-420.0);
scale.tare();
}
void loop() {
float weight = scale.get_units(5);
if (abs(weight) < 0.3) weight = 0.0;
display.clearDisplay();
display.setTextSize(2);
display.setCursor(10, 10);
display.print("⚖️ 电子秤");
display.setTextSize(3);
display.setCursor(20, 35);
display.printf("%.1fg", weight);
display.display();
delay(300);
}
2. 按键去皮 + 滑动平均滤波
商业电子秤都有"去皮"按钮——放上容器后按一下归零。再加一个滑动窗口滤波,消除读数抖动:
#define TARE_BTN 15 // 去皮按键(低电平触发)
#define FILTER_SIZE 8
float filter_buf[FILTER_SIZE];
int filter_idx = 0;
float moving_average(float new_val) {
filter_buf[filter_idx % FILTER_SIZE] = new_val;
filter_idx++;
float sum = 0;
for (int i = 0; i < FILTER_SIZE; i++) sum += filter_buf[i];
return sum / min(filter_idx, FILTER_SIZE);
}
void loop() {
// 检测去皮按键
if (digitalRead(TARE_BTN) == LOW) {
delay(50); // 消抖
if (digitalRead(TARE_BTN) == LOW) {
scale.tare();
Serial.println("✅ 已去皮");
while (digitalRead(TARE_BTN) == LOW); // 等待松开
}
}
float raw = scale.get_units(3);
float weight = moving_average(raw);
if (abs(weight) < 0.5) weight = 0.0;
Serial.printf("重量: %.1f g\n", weight);
delay(200);
}
🏭 实战场景
场景一:IoT 智能药房秤(联动 WiFi + MQTT + OLED)
需求:中药房抓药时,每味药材需要精确到克的称重记录,数据自动上传云端存档。
物料组合:ESP32 + HX711 + 5kg传感器 + OLED + WiFi + MQTT。
实现思路:称重完成后自动锁定读数(2秒内波动<1g视为稳定),通过 MQTT 发布到 "pharmacy/scale/herb_name" topic,OLED 显示药材名 + 重量 + "✅已上传"。服务端用 Node-RED 或 Python 订阅后存入数据库。
🔗 关联课程:第6课 WiFi 联网、第22课 MQTT 协议、第14课 OLED 显示。把这三课的知识与 HX711 组合,就是一个完整的物联网项目。
场景二:宠物自动喂食器重量监测(联动 L298N + SG90)
需求:自动喂食器每次出粮后,用称重传感器确认实际出粮量,防止卡粮或余粮不足。
物料组合:ESP32 + HX711 + 1kg传感器 + L298N 驱动螺旋下料 + SG90 挡板。
实现思路:食盆底部放置称重传感器,每次出粮前先去皮,出粮过程中实时监控重量增量,达到目标克数(如 50g)后立即停止电机并关闭挡板。误差控制在 ±3g 以内为合格。
🔗 关联课程:第15课 SG90 舵机、第25课 L298N 电机驱动。配合今天学的 HX711,打造闭环控制的自动喂食器。
⚠️ 常见问题
⚠️ 读数一直跳、不稳定? 检查三点:(1) 传感器必须水平放置,桌面不能晃动;(2) HX711 模块 VCC 接 3.3V 而非 5V,供电噪声更小;(3) 代码中用 get_units(10) 而非 get_units(1),多次采样取平均值。如果还跳,加滑动平均滤波。
⚠️ 校准因子怎么都不对? 先确认 read_average() 返回的原始值是稳定的(波动<±500 为正常)。校准必须在传感器水平放置、无负载且稳定后进行。另外注意:不同供电电压下校准因子不同——如果你用 USB 供电校准的,换成电池供电后需要重新校准。
⚠️ 重量显示负数? 检查压力传感器的接线方向。E+/E- 或 A+/A- 接反会导致读数符号反转。最简单的处理方法是把 CALIBRATION_FACTOR 取相反符号(正改负、负改正)。或者对调 A+ 和 A- 两根信号线。
⚠️ 传感器机械安装的坑: 压力传感器上的箭头标记表示受力方向。传感器一端固定(螺丝锁在底板上),另一端悬空作为秤盘支撑点。如果装反了——固定端当秤盘端——传感器会被杠杆力矩损坏。此外,传感器引出的四根细线非常脆弱,建议用热熔胶在根部加固。
💡 精度进阶:商业电子秤通常使用多点校准(如 0g、100g、200g、500g、1000g),做线性回归拟合而非单点比例。HX711 库的 set_scale() 仅支持单点校准,若需要多点校准,可自行在代码中实现查表插值或二次多项式拟合。