IoT Weight Logging Scale
Calibrating the Scale
Note: This example assumes you are using the latest version of the Arduino IDE on your desktop. If this is your first time using Arduino, please review our tutorial on installing the Arduino IDE. If you have not previously installed an Arduino library, please check out our installation guide.
Before we go farther into the project, we need to calibrate our scale. I've modified the calibration sketch that comes with the HX711 library to display on the scale's serial 7-segment display to make it slightly easier to use.
Upload Code to the ESP32
Here's the calibration sketch:
language:cpp
#include <HX711_ADC.h>
//HX711 constructor (dout pin, sck pin)
HX711_ADC LoadCell(5, 4);
HardwareSerial Serial2(2); // Enable 3rd serial port on ESP32
long t;
void setup() {
Serial.begin(115200);
Serial2.begin(9600);
Serial.println("Wait...");
LoadCell.begin();
long stabilisingtime = 2000; // tare preciscion can be improved by adding a few seconds of stabilising time
LoadCell.start(stabilisingtime);
LoadCell.setCalFactor(10000.0); // user set calibration factor (float)
Serial.println("Startup + tare is complete");
}
void loop() {
//update() should be called at least as often as HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS
//longer delay in scetch will reduce effective sample rate (be carefull with delay() in loop)
LoadCell.update();
//get smoothed value from data set + current calibration factor
if (millis() > t + 250) {
float i = fabs(LoadCell.getData());
float v = LoadCell.getCalFactor();
Serial.print("Load_cell output val: ");
Serial.print(i);
Serial.print(" Load_cell calFactor: ");
Serial.println(v);
// Create a string which is the integer value of the weight times 10,
// to remove the decimal point.
String weight = String(int(i*10));
Serial2.write(0x76); // Clear the display
Serial2.print(weight); // Write out the weight value to the display
// Identify which decimal point to set, and set it.
int shiftBy = 5-weight.length();
int decimalPoint = 0x08>>(shiftBy);
Serial2.write(0x77);
Serial2.write(decimalPoint & 0x0F);
t = millis();
}
//receive from serial terminal
if (Serial.available() > 0) {
float i;
char inByte = Serial.read();
if (inByte == 'l') i = -1.0;
else if (inByte == 'L') i = -10.0;
else if (inByte == 'h') i = 1.0;
else if (inByte == 'H') i = 10.0;
else if (inByte == 't') LoadCell.tareNoDelay();
if (i != 't') {
float v = LoadCell.getCalFactor() + i;
LoadCell.setCalFactor(v);
}
}
//check if last tare operation is complete
if (LoadCell.getTareStatus() == true) {
Serial.println("Tare complete");
}
}
It's pretty simple. It reads the HX711 four times a second and prints the results both to a serial console and to the 7-segment display. Note that it tares the scale at boot, so don't have any weight on the scale when you start it up!
Find the Calibration Factor
I prefer using a dedicated serial tool such as CoolTerm or a terminal program like Putty over the Arduino serial console for this step. You're going to have to step through quite a lot of values and the Arduino console isn't good for that.
The calibrate routine looks for the user to send characters over the serial console to adjust the calibration factor. The calibration factor starts at 10000 (arbitrarily), and must be increased or decreased from there until the weight reading is correct. Try increasing it first, by sending 'H' (for a 10-point increase) or 'h' (for a 1-point increase), and observe the weight reading. If the measurement gets closer to correct, keep increasing the calibration factor until the reading on the 7-segment display is true to the weight on the scale.
If the measurement gets farther from correct, try lowering the calibration factor by sending 'L' or 'l'. Note that if you are using a terminal program or serial tool other than the Arduino IDE tool, you can probably just hold down the key to constantly sending characters and change the calibration factor quite quickly.
Write that Number Down!
You'll want to record the final calibration factor so you can include it in the final version of the sketch.