HX711称重传感器接ESP32:电子秤从接线到校准

2026-11-13 20:28:15 33阅读 所属项目:ESP32 开发板

给机器人做抓握力度反馈、给料斗做余量监测、或者就想要一台自己标定的桌面秤——这些需求的背后都是同一对组合:称重传感器加 HX711。称重传感器输出的是毫伏级的微弱差分信号,ESP32 的 ADC 直接读不出有意义的东西,中间必须垫一块 24 位 ADC 放大板,HX711 干的就是这个活。这套方案便宜、资料多,但新手最容易卡在两处:接线对不上颜色,以及 calibration factor 不知道从哪来。

这篇把整条链路按顺序理一遍:应变片和惠斯通电桥的原理、HX711 的接口与参数、接线表、装库、校准算系数、读数与去皮。参数与代码对照了底稿教程页和 Avia Semiconductor 的 HX711 数据手册逐项核验,两段例程代码逐字符搬运自教程页,除头文件写法外未动一行。

HX711称重传感器与ESP32开发板

称重的物理底子:应变片与惠斯通电桥

常见的称重传感器是应变片式:一根金属条上贴着应变片(教程页实物图里白胶下面就是它)。应变片是一种把形变转成电阻变化的传感元件,金属条受力发生微小形变时,应变片的阻值随之改变,而且阻值变化量与所受载荷成正比——这就是称重的物理依据。

单枚应变片的阻值变化太小,直接测不出可靠的数值。所以商用称重传感器通常把四枚应变片接成惠斯通电桥,利用桥路的差分输出获得足够精度的电阻测量。从传感器引出的四根线,颜色约定一般是:红线 E+(供电正)、黑线 E-(供电负)、白线 A-(输出负)、绿线 A+(输出正)。不同厂家配色偶有出入,接之前最好核一下自己手上那款的说明书。

受力之后形变量很小,桥路输出信号也是毫伏量级,所以需要放大器。教程页用的就是传感器与 HX711 打包出售的常见组合,本文以它为准。

HX711:24 位 ADC 把微弱信号读出来

HX711 是 Avia Semiconductor 专为电子秤设计的精密 24 位 ADC,内置低噪声可编程增益放大器(PGA):A 通道增益可选 128 或 64,5V 供电下分别对应 ±20mV、±40mV 的满量程差分输入;B 通道固定增益 32。供电范围 2.6V 到 5.5V,输出数据速率 10SPS 或 80SPS 两档可选。这些参数都出自 HX711 数据手册,选型时用得上的主要是两条:量程由传感器决定、精度由 24 位转换加放大倍数保证。

它与单片机的通信是两线接口:DOUT(串行数据输出)和 PD_SCK(掉电控制兼串行时钟输入),全部控制都走引脚、不需要读写内部寄存器,接两个普通 GPIO 就能用。教程页还提到一个安装细节:HX711 板上要焊排针才能连 ESP32,而传感器引线又细又脆,直接焊到 E+/E-/A-/A+ 时要小心别拉断线。

秤体的组装教程页也给了一个思路:套件里的两块亚克力板(木板或 3D 打印板也行)分别装在金属条两端,下板固定传感器、上板放重物,装配的要点是让金属条两端之间产生应变。常见量程有 1kg、5kg、10kg、20kg 几档,按你要称的东西选。

接线:两根数据线加四根传感器线

HX711 与 ESP32 之间用两线接口,接任何可用 GPIO 都行。教程页的选择是 DT(数据)接 GPIO 16、SCK(时钟)接 GPIO 4,供电取 ESP32 的 3.3V。整理成表:

称重传感器线HX711 引脚ESP32 引脚
红线 E+E+—
黑线 E-E-—
白线 A-A-—
绿线 A+A+—
—VCC3.3V
—GNDGND
—DTGPIO 16
—SCKGPIO 4

对应的原理接线图如下:

HX711接ESP32接线图

库用 bogde 的 HX711 库(作者 Bogdan Necula),兼容 ESP32、ESP8266 和 Arduino。Arduino IDE 里走 Sketch > Include Library > Manage Libraries,搜 HX711 Arduino Library 装 Bogdan Necula 那个;用 VS Code 加 PlatformIO 的话,在 platformio.ini 里加一行 lib_deps = bogde/HX711@^0.7.5,顺手把 monitor_speed 设成 115200。

校准:calibration factor 必须自己算一遍

每个传感器的灵敏度都不一样,所以 calibration factor 没有通用值,必须用自己的秤和已知重量的东西标定一遍。教程页的准备物是一杯水,用厨房秤称出来 300g。下面是校准代码:

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-load-cell-hx711/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

// Calibrating the load cell
#include "Arduino.h"
#include "soc/rtc.h"
#include "HX711.h"

// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 16;
const int LOADCELL_SCK_PIN = 4;

HX711 scale;

void setup() {
  Serial.begin(115200);
  rtc_cpu_freq_config_t config;
  rtc_clk_cpu_freq_get_config(&config);
  rtc_clk_cpu_freq_to_config(RTC_CPU_FREQ_80M, &config);
  rtc_clk_cpu_freq_set_config_fast(&config);
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
}

void loop() {

  if (scale.is_ready()) {
    scale.set_scale();    
    Serial.println("Tare... remove any weights from the scale.");
    delay(5000);
    scale.tare();
    Serial.println("Tare done...");
    Serial.print("Place a known weight on the scale...");
    delay(5000);
    long reading = scale.get_units(10);
    Serial.print("Result: ");
    Serial.println(reading);
  } 
  else {
    Serial.println("HX711 not found.");
  }
  delay(1000);
}

//calibration factor will be the (reading)/(known weight)

烧录后打开串口监视器(115200),复位 ESP32,跟着提示走:先移走秤上的所有东西(程序自动去皮),五秒后把已知重量的物体放上去,等串口吐出一个读数。系数按这个公式算:

calibration factor = (reading)/(known weight)

教程页的实测是读数 -141449、已知重量 300g,所以 calibration factor = -141449 / 300 = -471.497:

calibration factor = -141449/300 = -471.497

串口输出长这样:

HX711校准串口输出

你的读数几乎一定和这个值不同,正负都可能,把算出来的系数存好。另外单位是自选的:传感器输出与受力成正比,系数用什么重量标定,读数就是什么单位——克、磅、公斤都行,教程页甚至提过有人拿猫粮粒数当单位。

读数与去皮:把秤真正用起来

拿到系数后就可以称东西了。下面是库自带的示例(教程页引用的 bogde/HX711 例程),烧录前把第 43/44 行的 INSERT YOUR CALIBRATION FACTOR 换成你自己的系数:

/*
 * Complete project details at https://RandomNerdTutorials.com/esp32-load-cell-hx711/
 *
 * HX711 library for Arduino - example file
 * https://github.com/bogde/HX711
 *
 * MIT License
 * (c) 2018 Bogdan Necula
 *
**/
#include "Arduino.h"
#include "HX711.h"
#include "soc/rtc.h"

// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 16;
const int LOADCELL_SCK_PIN = 4;

HX711 scale;

void setup() {
  Serial.begin(115200);
  rtc_cpu_freq_config_t config;
  rtc_clk_cpu_freq_get_config(&config);
  rtc_clk_cpu_freq_to_config(RTC_CPU_FREQ_80M, &config);
  rtc_clk_cpu_freq_set_config_fast(&config);
  Serial.println("HX711 Demo");

  Serial.println("Initializing the scale");

  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);

  Serial.println("Before setting up the scale:");
  Serial.print("read: \t\t");
  Serial.println(scale.read());      // print a raw reading from the ADC

  Serial.print("read average: \t\t");
  Serial.println(scale.read_average(20));   // print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale.get_value(5));   // print the average of 5 readings from the ADC minus the tare weight (not set yet)

  Serial.print("get units: \t\t");
  Serial.println(scale.get_units(5), 1);  // print the average of 5 readings from the ADC minus tare weight (not set) divided
            // by the SCALE parameter (not set yet)
            
  scale.set_scale(INSERT YOUR CALIBRATION FACTOR);
  //scale.set_scale(-471.497);                      // this value is obtained by calibrating the scale with known weights; see the README for details
  scale.tare();               // reset the scale to 0

  Serial.println("After setting up the scale:");

  Serial.print("read: \t\t");
  Serial.println(scale.read());                 // print a raw reading from the ADC

  Serial.print("read average: \t\t");
  Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale.get_value(5));   // print the average of 5 readings from the ADC minus the tare weight, set with tare()

  Serial.print("get units: \t\t");
  Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
            // by the SCALE parameter set with set_scale

  Serial.println("Readings:");
}

void loop() {
  Serial.print("one reading:\t");
  Serial.print(scale.get_units(), 1);
  Serial.print("\t| average:\t");
  Serial.println(scale.get_units(10), 5);

  scale.power_down();             // put the ADC in sleep mode
  delay(5000);
  scale.power_up();
}

示例里几个函数值得拆开讲:read() 读 24 位原始值;read_average(20) 取 20 次平均;get_value(5) 是 5 次平均再减去皮重;get_units(5) 则在减去皮重之后还除以 set_scale 设进去的系数,直接得到重量。set_scale() 不带参数时用于校准阶段拿原始读数,正式称重前要传入你算出的系数,再调一次 tare() 把秤归零。

示例的 loop 里每五秒读一次数,读之前 power_down() 让 ADC 进睡眠、读完 power_up() 唤醒——电池供电的项目这个机制很有用。另外例程开头把 ESP32 主频降到 80MHz,这是示例代码自带的处理,烧的时候照搬即可。

ESP32电子秤成品

想做成一台完整的桌面秤,教程页后半段给了进阶方向:加 OLED 屏实时显示读数、加一个按键做一键去皮(tare),平台仍用上面这套校准流程。把这台秤跑通之后,称重信号接进机器人做抓力反馈,或者做成料仓余量监测,都是同一套读数逻辑的延伸。


作者:舵机老炮
链接:https://www.aiddithome.com/p/49f0637a53041.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
4条评论
第三次终于亮了
1楼 · 11小时前

接线表存了,红黑白绿对 E+/E-/A-/A+,这个颜色约定记一次终身受用。

刷着刷着入坑了
2楼 · 11小时前

读数一直在跳是啥情况,电源噪声吗?打算接个稳压试试。

修啥都行二哥
3楼 · 11小时前

HX711 这套组合便宜又好买,看完这篇校准流程,感觉周末能把厨房秤安排上了。

老张装机
4楼 · 11小时前

当年第一次玩 HX711,直接抄了网上抄来的 -471.497,读数飘得没边,折腾一晚上才明白这系数每个传感器都不一样,必须自己拿已知重量标。文章里 300g 一杯水加公式那步是精华,千万别跳。另外四根传感器线真的细,我焊绿线的时候弄断过一次,刮线重新上锡才焊回去,新手 solder 前最好先把排针固定牢。