参考🔗:https://randomnerdtutorials.com/esp32-load-cell-hx711/
7月12日 Update:
- 修改为
克g
,盎司oz
,克拉ct
之间的切换- 增加计数功能版本代码
需要安装的arduino库
- Adafruit SSD1306
- Adafruit GFX 库
- HX711库
- PushButton库
后面两个库是用户贡献库,需要注意作者名称,如下图
获取校准因子
#include <Arduino.h>
#include "soc/rtc.h"
#include "HX711.h"
// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 4; //HX711的DT引脚
const int LOADCELL_SCK_PIN = 16; //HX711的SCK引脚
HX711 scale;
void setup() {
Serial.begin(115200); //波特率设置为115200
// rtc_clk_cpu_freq_set(RTC_CPU_FREQ_80M);
setCpuFrequencyMhz(RTC_CPU_FREQ_80M);
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(3000);
scale.tare();
Serial.println("Tare done...");
Serial.print("Place a known weight on the scale...");
delay(3000);
long reading = scale.get_units(10);
Serial.print("Result: ");
Serial.println(reading);
}
else {
Serial.println("HX711 not found.");
}
delay(1000);
}
使用以下公式计算校准系数:
calibration factor = (reading)/(known weight)
每个设备的这个参数不同,需要自己测量
显示
“Place a known weight on the scale”
后再把物品放上去,tare
是“去皮”的意思
校准称重传感器 Arduino IDE 串行监视器(波特率为115200
)
在我们的例子中,读数是 -141449
。放置到压力传感器上的物体已知重量为 300g
,因此我们的校准因子将为:-141449/300 = -471.497
。
calibration factor = -141449/300 = -471.497
称重计代码
已更新成克,盎司,克拉之间的切换,自测可行,注意自调引脚
#include <Arduino.h>
#include "HX711.h"
#include "soc/rtc.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Pushbutton.h>
#include <esp32-hal-cpu.h>
// 需要自行更改的引脚有以下4个:
// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 16; //HX711的DT
const int LOADCELL_SCK_PIN = 4; //HX711的SCK
//Button
#define Tare_BUTTON_PIN 14 //去皮按键
#define Switch_BUTTON_PIN 12 //切换单位按键
#define CALIBRATION_FACTOR 465.344 //校准因子
HX711 scale;
float reading ;
float lastReading ;
//OLED Display
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // 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);
Pushbutton Tare_Button(Tare_BUTTON_PIN);
Pushbutton Switch_Button(Switch_BUTTON_PIN);
int per_unit = 0; //g, oz, ct。单位切换,默认为g,依次为克、盎司、克拉
void displayWeight(float weight) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
// Display static text
display.println("Weight:");
display.display();
display.setCursor(0, 15);
display.setTextSize(2);
// display.print(weight);
char weightStr[10];
if(per_unit == 1){
weight = 0.0353 * weight;
}
else if (per_unit == 2){
weight = 5 * weight;
}
dtostrf(weight, 5, 1, weightStr); //通过函数将float数转换成表示一位小数的字符串
display.print(weightStr);
display.print(" ");
if(per_unit == 0){
display.print("g");
}
else if(per_unit == 1){
display.print("oz"); //盎司
}
else if(per_unit == 2){
display.print("ct"); //克拉
}
display.display();
}
void setup() {
Serial.begin(115200);
// rtc_clk_cpu_freq_set(RTC_CPU_FREQ_80M);
setCpuFrequencyMhz(100);
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 (Tare_Button.getSingleDebouncedPress()) { //去皮按键被按下过
Serial.print("tare...");
scale.tare();
}
if (Switch_Button.getSingleDebouncedPress()){ //切换单位按键被按下过
Serial.print("switch...");
// per_unit = !per_unit;
//0代表g,1代表oz,2代表ct
if(per_unit == 2){
per_unit = 0;
}
else{
per_unit++;
}
}
if (scale.wait_ready_timeout(1000)) {
// reading = round(scale.get_units());
reading = scale.get_units();
Serial.print("Weight: ");
Serial.println(reading);
if (reading != lastReading) {
displayWeight(reading);
}
lastReading = reading;
}else {
Serial.println("HX711 not found.");
}
}
调试tips
- 测校准因子时,建议等到串口能连续输出在0左右的值后,再把测量的物体放上去
- 测一部手机时,串口输出值应该在7w到12w之间
- 如果出现读值跳变异常,可能是
HX711
和压力传感器
之间的连接问题(我们组的那四个脚甚至需要掰成一个奇怪的形状才能读值正常==- 用来计算校准因子的物品重量最好准确,校准因子和最后的测重值似乎不是线性相关,所以参数差一点点都可能会导致侧重结果误差较大
- 测重时,如果初始显示值不为0,可以使用
去皮
功能调整到0
带计数功能的代码
- 只使用了两个按键,用切换单位的按键按三下切到计数功能
- 对单个物品的重量读取是在
Getting weight
显示结束后- 在显示
Put
时放上要计数的物品
#include <Arduino.h>
#include "HX711.h"
#include "soc/rtc.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Pushbutton.h>
#include <esp32-hal-cpu.h>
// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 16;
const int LOADCELL_SCK_PIN = 4;
//Button
#define Tare_BUTTON_PIN 14 //去皮按键
#define Switch_BUTTON_PIN 12 //切换单位按键
HX711 scale;
float reading ;
float lastReading ;
float singleWeight;
#define CALIBRATION_FACTOR 465.344 //校准因子
//OLED Display
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // 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);
Pushbutton Tare_Button(Tare_BUTTON_PIN);
Pushbutton Switch_Button(Switch_BUTTON_PIN);
int per_unit = 0; //g, oz, ct。单位切换,默认为g,依次为克、盎司、克拉、到3时切换到计量模式
void Count(float singleWeight){
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
// Display static text
display.println("SingleWeight:");
display.display();
display.setCursor(0, 15);
display.setTextSize(2);
char weightStr[10];
dtostrf(singleWeight, 5, 1, weightStr); //通过函数将float数转换成表示一位小数的字符串
display.print(weightStr);
display.print(" ");
display.print("g");
display.display();
delay(2000);
Serial.print("Putting things to count on the scale...");
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
// Display static text
display.println("Put");
display.display();
delay(3000);
reading = scale.get_units();
int Quantity = round(reading / singleWeight);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
// Display static text
display.println("Quantity:");
display.display();
display.setCursor(0, 15);
display.setTextSize(2);
display.print(Quantity);
display.display();
delay(3000);
}
void displayWeight(float weight) {
// if(per_unit == 3){
// Count();
// return;
// }
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
// Display static text
display.println("Weight:");
display.display();
display.setCursor(0, 15);
display.setTextSize(2);
// display.print(weight);
char weightStr[10];
if(per_unit == 1){
weight = 0.0353 * weight;
}
else if (per_unit == 2){
weight = 5 * weight;
}
dtostrf(weight, 5, 1, weightStr); //通过函数将float数转换成表示一位小数的字符串
display.print(weightStr);
display.print(" ");
if(per_unit == 0){
display.print("g");
}
else if(per_unit == 1){
display.print("oz"); //盎司
}
else if(per_unit == 2){
display.print("ct"); //克拉
}
display.display();
}
void setup() {
Serial.begin(115200);
// rtc_clk_cpu_freq_set(RTC_CPU_FREQ_80M);
setCpuFrequencyMhz(100);
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 (Tare_Button.getSingleDebouncedPress()) { //去皮按键被按下过
Serial.print("tare...");
scale.tare();
}
if (Switch_Button.getSingleDebouncedPress()){ //切换单位按键被按下过
Serial.print("switch...");
// per_unit = !per_unit;
//0代表g,1代表oz,2代表ct
if(per_unit == 3){
per_unit = 0;
}
else{
per_unit++;
}
}
if (scale.wait_ready_timeout(1000)) {
// reading = round(scale.get_units());
reading = scale.get_units();
if(per_unit == 3){
Serial.print("Getting singleWeight...");
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Getting weight");
display.display();
delay(2500);
reading = scale.get_units();
singleWeight = reading;
Count(reading);
per_unit = 0;
}
Serial.print("Weight: ");
Serial.println(reading);
if (reading != lastReading) {
displayWeight(reading);
}
lastReading = reading;
}else {
Serial.println("HX711 not found.");
}
}