压力传感器 HX711 电子秤制作:高精度称重 DIY 实战

为什么选择 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-(信号负)

接线步骤:

  1. 传感器 4 根线对应接到 HX711 的 E+、E-、A+、A-
  2. HX711 的 VCC 接 Arduino 5V
  3. HX711 的 GND 接 Arduino GND
  4. HX711 的 DT 接 Arduino D2
  5. 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);
}

校准步骤

校准是电子秤精度的关键。你需要一个已知重量的砝码(或已知重量的物品)。

校准流程:

  1. 空载上电,等待 30 秒预热
  2. 上传代码,打开串口监视器
  3. 读取当前原始值(未除以 calibration_factor 的值)
  4. 放上已知重量的砝码(比如 100g)
  5. 读取新的原始值
  6. 计算校准系数: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:精度不够

提升方法:

  1. 换更小量程的传感器(5kg 比 50kg 精度高)
  2. 降低 HX711 采样率,提高分辨率:
    scale.set_gain(128);  // 最大增益
  3. 增加机械结构稳定性,减少晃动
  4. 使用屏蔽线连接传感器

问题 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);
}

成本优化建议

如果批量制作,成本可以进一步降低:

  1. 用 ESP8266 替代 Arduino:¥12,还能加 WiFi 上传数据
  2. 定制 PCB:¥5/片(10 片起),比面包板稳定
  3. 批量采购传感器:10 片以上¥20/片
  4. 用段码屏替代 OLED:¥3,显示更清晰

批量成本(10 套):

  • HX711: ¥6/片
  • 传感器:¥20/片
  • ESP8266: ¥12/片
  • 段码屏:¥3/片
  • PCB: ¥5/片
  • 单套成本:¥46

总结

HX711 电子秤项目是学习传感器信号处理的绝佳入门项目。通过这个项目,你可以:

  • 理解应变片和惠斯通电桥原理
  • 掌握微弱信号放大技巧
  • 学习 24 位 ADC 的使用方法
  • 实践传感器校准和滤波算法

最重要的是,成本不到 50 元就能做出精度 0.1g 的电子秤,性价比极高。

希望这篇博客文章对您有所帮助!