HX711称重传感器接ESP32:接线校准与读重实操

2026-11-06 13:11:24 31阅读

想给机器人加个"能感知重量"的本事,最便宜的路径就是称重传感器加HX711放大器配ESP32。几十块钱的件,接四根线,就能做出一台能读克数的电子秤,还能顺手接到桌面机械臂上做抓取力度反馈。这篇把接线、装库、校准、读数一路走完,最后再加一块OLED屏和去皮按键,做成完整的小台秤。

先把结构说清楚:教程里三段代码全部逐字符取自真实项目源码,只有一个平台兼容处理——C/C++尖括号头文件在站点会被剥掉,所以代码里的#include统一写成引号形式,比如#include "HX711.h",在Arduino IDE里和尖括号写法编译等价,直接能跑。

认识称重传感器和HX711

常见的称重传感器是应变片式:一根金属梁上贴着应变片,受力变形时电阻按比例变化。通常四个应变片接成惠斯通电桥,就是为了把这么微小的电阻变化测准。红黑绿白四根线,分别是正激励E+、负激励E-、输出正A+、输出负A-。

问题在于这个信号实在太弱,毫伏级,单片机直接读不了。所以市面上称重传感器几乎都和HX711放大器一起卖:HX711是一片24位ADC,一边接传感器的四根线,另一边用两根线(时钟和数据)跟ESP32通信。板子上E+、E-、A+、A-四个焊点接传感器,GND、DT、SCK、VCC四个焊点接主控,排针一般要自己焊。

HX711称重传感器与ESP32电子秤

传感器量程按需选,常见1kg、5kg、10kg、20kg,做桌面小秤1kg够用。另外要给它配个机械结构:套件一般带两块亚克力板,下板固定传感器一端,上板装在另一端,物体放上板,金属梁中间受力产生应变。没有套件的话,木板或3D打印板都行。

接线:传感器到HX711再到ESP32

HX711是两线接口,DT和SCK可以接ESP32任意可用GPIO,这里按原教程用DT接GPIO 16、SCK接GPIO 4,供电接3.3V。完整对应关系如下:

称重传感器线色HX711焊点HX711ESP32
红(E+)E+GNDGND
黑(E-)E-DTGPIO 16
白(A-)A-SCKGPIO 4
绿(A+)A+VCC3.3V

ESP32与HX711接线原理图

提醒一句,传感器引出的四根漆包线又细又脆,焊的时候别反复弯折,一扯就断。焊完先别急着上电,对照原理图再核一遍线色,E+和A+接反是新手最常见的翻车点。

装HX711库

库选bogde写的HX711,兼容ESP32、ESP8266和Arduino。Arduino IDE里走Sketch、Include Library、Manage Libraries,搜HX711装Bogdan Necula那个就行。

PlatformIO中安装HX711库

用VS Code加PlatformIO的话,在PIO Home的Libraries里搜HX711,选bogde那个,Add to Project即可。platformio.ini里会多一行lib_deps = bogde/HX711@^0.7.5,顺手把串口速率加上monitor_speed = 115200。

校准:拿到你自己的校准系数

每个传感器的输出都不一样,校准系数必须自己测,这步不能跳。准备一个已知重量的东西,原教程用的是厨房秤称出来的一杯水,300克。先烧录下面这段校准代码:

/*
  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的串口监视器,按提示操作:先移走秤上所有东西等它去皮,再把已知重量的物体放上去,等串口吐出一个读数。校准系数就用这个公式:读数除以已知重量。原教程那次的读数是-141449,除以300克,校准系数就是-471.497。

你这个系数几乎肯定和这个值不同,记下来,后面所有代码都要用。顺便说一句,输出和受力成正比,所以单位随你定,克、千克甚至"一块猫粮"都行,只要换算一致。

读重量:跑通库自带示例

拿到系数后,先跑库自带的示例把读数流程走通。代码里那行scale.set_scale(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();
}

setup里先打印配置前后的原始读数对比,loop里每5秒输出一次单次读数和10次平均。这几行rtc_clk开头的代码是把ESP32主频降到80MHz,HX711对时序敏感,降频能提高读取稳定性,别删。

进阶:OLED显示加去皮按键的完整小台秤

想做成能日常用的样子,加一块SSD1306 OLED和一个按键即可:OLED走I2C,按键接GPIO 19,按一下去皮。接线在原理图基础上加三根线:

电子秤完整接线含OLED与按键

完整代码如下,校准系数在宏定义里替换:

/*
  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.
*/

// Library HX711 by Bogdan Necula: https://github.com/bogde/HX711
// Library: pushbutton by polulu: https://github.com/pololu/pushbutton-arduino

#include "Arduino.h"
#include "HX711.h"
#include "soc/rtc.h"
#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#include "Pushbutton.h"

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

HX711 scale;
int reading;
int lastReading;
//REPLACE WITH YOUR CALIBRATION FACTOR
#define CALIBRATION_FACTOR -471.497

//OLED Display
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Button
#define BUTTON_PIN 19
Pushbutton button(BUTTON_PIN);

void displayWeight(int weight){
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 10);
  // Display static text
  display.println("Weight:");
  display.display();
  display.setCursor(0, 30);
  display.setTextSize(2);
  display.print(weight);
  display.print(" ");
  display.print("g");
  display.display();  
}

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);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);
  
  Serial.println("Initializing the scale");
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);

  scale.set_scale(CALIBRATION_FACTOR);   // this value is obtained by calibrating the scale with known weights; see the README for details
  scale.tare();               // reset the scale to 0
}

void loop() {
  if (button.getSingleDebouncedPress()){
    Serial.print("tare...");
    scale.tare();
  }
  
  if (scale.wait_ready_timeout(200)) {
    reading = round(scale.get_units());
    Serial.print("Weight: ");
    Serial.println(reading);
    if (reading != lastReading){
      displayWeight(reading); 
    }
    lastReading = reading;
  }
  else {
    Serial.println("HX711 not found.");
  }
}

这段用wait_ready_timeout(200)代替阻塞式读取,200毫秒内数据没就绪就走else分支报HX711 not found,而不是卡死在里面。读数变化才刷新屏幕,能减少OLED闪烁。按键库用的是pololu的pushbutton,库管理器里同名安装。成品长这样,放个魔方上去克数实时刷新:

ESP32电子秤成品演示

踩坑提醒和收尾

几个高频问题提前说。第一,串口一直报HX711 not found,先查接线,DT和SCK接反或者VCC没接好都会这样。第二,读数狂跳不稳,十有八九是机械结构没装好,上下板必须让金属梁中间受力,也别把秤放在软桌布上。第三,数值为负或者差一个倍数,是校准系数没换成自己的,或者传感器四根线序接错。

整体下来,这套方案的乐趣在于便宜、简单、立刻能用。称重传感器加HX711接ESP32,从接线到出克数,一个下午够了。后面想接进桌面机械臂做抓取力反馈,或者做个自动喂食器记录余量,都是这套读数的延伸,把get_units()的值喂给你的控制逻辑就行。


作者:固件烧录仔
链接:https://www.aiddithome.com/p/1b3028b65b204d.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
4条评论
阿强焊点总飞
1楼 · 1天前

直接抄作业成功,OLED显示那部分代码一次点亮。

胶佬憨憨
2楼 · 1天前

按这篇接好了,厨房秤对了一下克数,误差在1克以内,校准这步真不能省。

电烙铁爱好者
3楼 · 1天前

那个把主频降到80M的细节太真实了,之前读数跳得像股票,加了那几行rtc_clk立马稳。

阿伟不emo
4楼 · 1天前

这篇把我上次踩的坑全写了:HX711的DT和SCK接反就会一直报HX711 not found,我当时查了半天以为是库的问题,其实重接两根线就好了。校准那段也很实用,-141449除以300这个例子给得具体,新手照着算就不会懵。