为什么选择 HX711?
市面上几十块的电子秤精度只能到 1g,但用 HX711+ 称重传感器,你可以轻松做到 0.1g 甚至 0.01g 精度。关键是成本极低:HX711 模块 8 块钱,50kg 称重传感器 25 块,Arduino Nano 克隆版 15 块,总成本不到 50 元。
这个项目适合:
- 需要高精度称重的 DIY 项目(咖啡称、珠宝秤、配料秤)
- 学习传感器信号放大和 ADC 原理
- 制作智能仓储称重系统
- 想理解应变片和惠斯通电桥工作原理
硬件清单
| 组件 | 型号 | 价格 | 备注 |
|---|---|---|---|
| HX711 模块 | HX711 24 位 ADC | ¥8 | 必选,信号放大 |
| 称重传感器 | 50kg 悬臂梁 | ¥25 | 根据量程选择 |
| 主控板 | Arduino Nano | ¥15 | 或 ESP32 |
| OLED 显示屏 | 0.96 寸 I2C | ¥12 | 显示重量 |
| 杜邦线 | 公对母 | ¥5 | 连接用 |
| 面包板 | 400 孔 | ¥8 | 测试用 |
| 合计 | – | ¥73 | 批量可更低 |
购买建议:
- 淘宝搜"HX711 模块",选带稳压的版本
- 传感器量程根据需求选:1kg/5kg/10kg/50kg
- 小量程传感器(1-5kg)精度更高,适合小物件称重
HX711 工作原理
HX711 是专为高精度称重设计的 24 位 ADC 芯片。它内部集成了:
- 低噪声可编程增益放大器(PGA),增益 32/64/128 倍可选
- 24 位 Δ-Σ ADC,最高 80SPS 采样率
- 稳压输出,可直接给传感器供电
为什么需要 24 位?
称重传感器输出的是毫伏级微弱信号(满载时约 2mV/V)。假设用 5V 供电,满载输出只有 10mV。如果用 Arduino 自带的 10 位 ADC(0-1023 对应 0-5V),10mV 只占 2 个刻度,根本没法用。
HX711 的 24 位 ADC 把 0-5V 分成 1677 万份,10mV 对应约 3.3 万个刻度,精度提升上万倍。
电路连接
HX711 模块引脚定义:
- VCC: 5V 或 3.3V
- GND: 接地
- DT: 数据引脚(接 Arduino D2)
- SCK: 时钟引脚(接 Arduino D3)
称重传感器通常有 4 根线:
- 红线: E+(激励正)
- 黑线: E-(激励负)
- 白线: A+(信号正)
- 绿线: A-(信号负)
接线步骤:
- 传感器 4 根线对应接到 HX711 的 E+、E-、A+、A-
- HX711 的 VCC 接 Arduino 5V
- HX711 的 GND 接 Arduino GND
- HX711 的 DT 接 Arduino D2
- HX711 的 SCK 接 Arduino D3
如果传感器线色不同,用万用表测电阻:
- E+ 和 E- 之间电阻约 400Ω
- A+ 和 A- 之间电阻约 400Ω
- 任意其他组合电阻约 300Ω
代码实现
基础称重代码
#include "HX711.h"
// 引脚定义
#define DT_PIN 2
#define SCK_PIN 3
HX711 scale;
// 校准参数(需要实际标定)
float calibration_factor = 420.0; // 每克对应的原始值
long zero_offset = 0; // 零点偏移
void setup() {
Serial.begin(9600);
Serial.println("HX711 电子秤初始化...");
scale.begin(DT_PIN, SCK_PIN);
scale.set_scale(calibration_factor);
scale.tare(); // 自动归零
Serial.println("初始化完成,开始称重...");
}
void loop() {
if (scale.is_ready()) {
float weight = scale.get_units(10); // 读取 10 次平均
Serial.print("重量:");
Serial.print(weight, 2);
Serial.println(" g");
} else {
Serial.println("HX711 未就绪,检查接线!");
}
delay(500);
}
带 OLED 显示的完整代码
#include "HX711.h"
#include
#include
#include
#define DT_PIN 2
#define SCK_PIN 3
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
HX711 scale;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
float calibration_factor = 420.0;
long zero_offset = 0;
float current_weight = 0;
void setup() {
Serial.begin(9600);
// OLED 初始化
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED 初始化失败");
for (;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("电子秤启动中...");
display.display();
// HX711 初始化
scale.begin(DT_PIN, SCK_PIN);
scale.set_scale(calibration_factor);
scale.tare();
delay(1000);
display.clearDisplay();
display.display();
}
void loop() {
if (scale.is_ready()) {
current_weight = scale.get_units(10);
display.clearDisplay();
display.setCursor(0, 0);
display.println("当前重量:");
display.setTextSize(2);
display.setCursor(20, 25);
display.print(current_weight, 1);
display.print(" g");
display.display();
}
delay(300);
}
校准步骤
校准是电子秤精度的关键。你需要一个已知重量的砝码(或已知重量的物品)。
校准流程:
- 空载上电,等待 30 秒预热
- 上传代码,打开串口监视器
- 读取当前原始值(未除以 calibration_factor 的值)
- 放上已知重量的砝码(比如 100g)
- 读取新的原始值
- 计算校准系数:
calibration_factor = (读数 2 - 读数 1) / 已知重量
校准代码:
void calibrate() {
Serial.println("移除所有重物,准备归零...");
delay(3000);
scale.tare();
Serial.println("归零完成");
Serial.println("放上已知重量的砝码(如 100g)");
Serial.println("输入实际重量(克):");
while (Serial.available() == 0) {}
float known_weight = Serial.parseFloat();
long raw_value = scale.read_average(20);
calibration_factor = raw_value / known_weight;
Serial.print("校准系数:");
Serial.println(calibration_factor);
Serial.println("将此值写入代码中的 calibration_factor");
}
校准技巧:
- 用多个不同重量校准,取平均值更准确
- 校准后不要移动传感器位置
- 温度变化会影响精度,重要应用需温度补偿
常见问题排查
问题 1:读数一直为 0
可能原因:
- HX711 未供电(检查 VCC 是否有 5V)
- DT/SCK 引脚接错
- 传感器线序错误
解决方法:
// 添加诊断代码
void diagnose() {
Serial.print("DT 引脚状态:");
Serial.println(digitalRead(DT_PIN));
if (!scale.is_ready()) {
Serial.println("HX711 未就绪!检查接线");
}
}
问题 2:读数跳动很大
可能原因:
- 电源不稳定
- 传感器未固定好
- 环境振动
解决方法:
- 给 HX711 单独供电,避免与电机共用电源
- 增加读数平均次数:
scale.get_units(20) - 添加软件滤波:
float filtered_weight = 0;
float alpha = 0.3; // 滤波系数
void loop() {
float raw = scale.get_units(5);
filtered_weight = alpha * raw + (1 - alpha) * filtered_weight;
Serial.println(filtered_weight, 2);
}
问题 3:精度不够
提升方法:
- 换更小量程的传感器(5kg 比 50kg 精度高)
- 降低 HX711 采样率,提高分辨率:
scale.set_gain(128); // 最大增益 - 增加机械结构稳定性,减少晃动
- 使用屏蔽线连接传感器
问题 4:漂移严重
原因: 传感器温漂或蠕变
解决方法:
- 上电预热 5 分钟再使用
- 定期自动归零(每 10 秒)
- 选择质量更好的传感器(铝合金 vs 不锈钢)
进阶应用
去皮功能
void tare() {
scale.tare();
Serial.println("已去皮");
}
// 添加按键触发去皮
#define TARE_BUTTON 4
void loop() {
if (digitalRead(TARE_BUTTON) == LOW) {
tare();
delay(500); // 防抖
}
// ... 其他代码
}
多量程自动切换
float get_weight_auto_range() {
float weight = scale.get_units(10);
if (weight < 100) {
scale.set_scale(420.0); // 高精度模式
} else if (weight < 1000) {
scale.set_scale(400.0); // 中量程
} else {
scale.set_scale(380.0); // 大量程
}
return scale.get_units(10);
}
数据记录到 SD 卡
#include
File dataFile;
void setup() {
SD.begin(4);
dataFile = SD.open("weight_log.csv", FILE_WRITE);
dataFile.println("timestamp,weight");
}
void loop() {
float weight = scale.get_units(10);
dataFile.print(millis());
dataFile.print(",");
dataFile.println(weight);
dataFile.close();
delay(1000);
}
成本优化建议
如果批量制作,成本可以进一步降低:
- 用 ESP8266 替代 Arduino:¥12,还能加 WiFi 上传数据
- 定制 PCB:¥5/片(10 片起),比面包板稳定
- 批量采购传感器:10 片以上¥20/片
- 用段码屏替代 OLED:¥3,显示更清晰
批量成本(10 套):
- HX711: ¥6/片
- 传感器:¥20/片
- ESP8266: ¥12/片
- 段码屏:¥3/片
- PCB: ¥5/片
- 单套成本:¥46
总结
HX711 电子秤项目是学习传感器信号处理的绝佳入门项目。通过这个项目,你可以:
- 理解应变片和惠斯通电桥原理
- 掌握微弱信号放大技巧
- 学习 24 位 ADC 的使用方法
- 实践传感器校准和滤波算法
最重要的是,成本不到 50 元就能做出精度 0.1g 的电子秤,性价比极高。
希望这篇博客文章对您有所帮助!