It is really pretty easy.
I just watched Jonathan’s video, and that looks much more complicated than what I did. It looks like the IOT system is wanting to mediate the reading of the device, and I would be totally lost. Going direct with native Arduino there are tons of tutorials that make it super easy.
Not an expert, but I think it’s also going to be simpler to hook up the bar-with-hole style load cell, rather than the “bathroom scale” type that has four separate pads that you have to wire together correctly. The bar-with-hole has four wires that are connected directly to the HX711 and the tutorials are pretty clear about which goes where. Then the Arduino reads out the digital value using a library and that’s it. You have to calibrate the weight because the HX711 doesn’t know how sensitive the load cell is, it just produces a readout that’s proportional to weight.
I did it with an Arduino sketch instead of VS Code because for me it’s still simpler that way.
The essential part I’m using is
#include <HX711.h>
#define LOADCELL_DOUT_PIN 3
#define LOADCELL_SCK_PIN 2
HX711 scale1;
float calibration_factor = -225600; // <--- empirically derive this number
void setup() {
Serial.begin(9600);
scale1.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale1.set_scale();
scale1.tare();
scale1.set_scale(calibration_factor);
}
void loop() {
float weight1 = scale1.get_units();
Serial.println(weight1, 3);
}
In my application it does an automatic tare at power-up, but in the sample code that I stole, there are comments that imply that the tare weight can be hard-coded so that the scale can wake up and know the weight without having to tare the scale.
Here is the entire code that I’m running (not cleaned up or anything). Basically just bodged together a load cell tutorial/sample and an OLED sample. The OLED was confusing me until I realized I had to hook up Vcc to 3.3V instead of 5V.
Code
#include <HX711.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define LOADCELL_DOUT_PIN 3
#define LOADCELL_SCK_PIN 2
#define LOADCELL2_DOUT_PIN 6
#define LOADCELL2_SCK_PIN 5
HX711 scale1;
HX711 scale2;
float calibration_factor = -225600;
float calibration_factor2 = 203040;
#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)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// Clear the buffer
display.setTextSize(2); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.clearDisplay();
display.display();
display.setCursor(0,0); // Start at top-left corner
display.print("Starting..");
display.display();
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("HX711 calibration sketch");
Serial.println("Remove all weight from scale");
Serial.println("After readings begin, place known weight on scale");
Serial.println("Press + or a to increase calibration factor");
Serial.println("Press - or z to decrease calibration factor");
scale1.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale1.set_scale();
scale1.tare(); //Reset the scale to 0
scale2.begin(LOADCELL2_DOUT_PIN, LOADCELL2_SCK_PIN);
scale2.set_scale();
scale2.tare(); //Reset the scale to 0
//long zero_factor = scale.read_average(); //Get a baseline reading
//Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
//Serial.println(zero_factor);
// Clear the buffer
display.clearDisplay();
display.display();
scale1.set_scale(calibration_factor); //Adjust to this calibration factor
scale2.set_scale(calibration_factor2); //Adjust to this calibration factor
}
void loop() {
// truncate floating point so we don't get "-0.000"
int thou;
float weight1 = scale1.get_units();
thou = weight1 * 1000.0f + 0.5;
weight1 = (float)thou/1000;
float weight2 = scale2.get_units();
thou = weight2 * 1000.0f + 0.5;
weight2 = (float)thou/1000;
if (1) {
// put your main code here, to run repeatedly:
Serial.print("Reading: ");
Serial.print(weight1, 3);
Serial.print(", ");
Serial.print(weight2, 3);
Serial.print(" lbs"); //Change this to kg and re-adjust the calibration factor if you follow SI units like a sane person
//Serial.print(" calibration_factor: ");
//Serial.print(calibration_factor);
Serial.println();
}
display.clearDisplay();
display.setCursor(0,0); // Start at top-left corner
if (weight1 >= 0) {
display.print("X: ");
}
else {
display.print("X:");
}
display.println(weight1, 3);
//display.println("lbs");
if (weight2 >= 0) {
display.print("Y: ");
}
else {
display.print("Y:");
}
display.print(weight2, 3);
display.display();
if (0) {
if(Serial.available())
{
char temp = Serial.read();
if(temp == '+' || temp == 'a')
calibration_factor += 10;
else if(temp == '-' || temp == 'z')
calibration_factor -= 10;
}
}
}
IMO this is squarely within the strength of Arduino, where a novice can get a device working by just plugging in the device and installing a library for it, and it works.
I got four for $20 and it’s already got me thinking where else I might use these.