Weighing Scale using Arduino, HX711, and a Load Cell
Table of Contents
Weighing Scale:
Weighing Scale using Arduino, HX711, and a Load Cell- Here, I have my DIY weighing scale, which I built for only about 8 dollars. And next to it, I have a commercial weighing scale that costs around 60 dollars. That’s a huge price difference!
Can this low-cost DIY Weighing Scale actually match up to a professional one? Well, that’s exactly what we are going to find out. I will be testing the accuracy of my DIY scale by comparing it to the commercial Scale.
To make this test as fair as possible, I have a set of known weights that we will measure on both scales. By the end of this article, you will be able to see the results and decide for yourself if building a DIY weighing scale is a good idea or if it’s better to stick with a commercial Scale.
Note: You can also read my article on IoT Weighing Scale using ESP32, HX711 Amplifier board, Load Cell, and Blynk application.
So, without any further delay, let’s get started!!!
Amazon Links:
Arduino Nano USB C type (Recommended)
*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!
This is my setup from the previous DIY Weighing Scale project. I have not made any changes to the hardware. I am still using the same steel plate mounted on a 5Kg load cell, or strain gauge.
The load cell’s 4 wires are connected to the HX711 amplifier board, and another set of 4 wires connects the HX711 to the Arduino Nano. You can also use an Arduino Pro Micro, Arduino Uno, or even an Arduino Mega.
The Development board also has the I2C-supported SSD1306 OLED display module. You can ignore the other components on this development board. For the connections, just follow this circuit diagram.
HX711 with Arduino Circuit Diagram:
To power up the Arduino Nano you can use 7V to 9V adaptor or a battery. You can also use a 12V adaptor, but to be on the safe side use a power source with a voltage around 9 volts.
On the Left side, you can see a 5Kg Load Cell or Strain Gauge. The type of the Load cell I am using has 4 wires Red, White, Black, and Green which are connected to the HX711 Amplifier board 4 pin’s E+, E-, A-, and A+ respectively.
The other 4 Pins on the HX711 (GND, DT, SCK, and 5V) are connected to the Arduino. Connect the GND and 5V pins to the Arduino GND and 5V. Connect the DT pin to the Arduino D3 and SCK to the Arduino D2.
Connect the VCC and GND pins of the I2C supported SSD1306 Oled display module to the Arduino 3.3V and GND. Connect the SDA and SCL pins to the Arduino A4 and A5 Pins. A4 and A5 pins on the Arduino are the I2C pins.
After looking at the circuit diagram, you probably have an idea that the hardware is exactly the same. You will see these same connections everywhere because these are the basic connections needed to connect a load cell, HX711 amplifier board, and the SSD1306 OLED display module to the Arduino.
To make this DIY weighing scale compete with the commercial scale, I reprogrammed the Arduino from scratch. The previous code was pretty basic. It measured some weights with high precision, but for other weights, it either showed a bit more or a bit less than the actual value.
The accuracy of a weighing scale depends on its calibration. When I calibrated it with a 1Kg weight, it gave slightly incorrect values for higher weights. And when I calibrated it with a 5Kg weight, it became less accurate for lower weights. This inconsistency was really frustrating.
To solve this issue,
float calibration_factor_low = 419640; // Calibration factor for lower weights
float calibration_factor_mid = 407000; // Calibration factor for mid-range weights
I defined two calibration factor values; one for lower weights and another for mid-range weights.
Not only that, but I also calibrated the scale from as low as 0.01 grams all the way up to 5 kilograms, covering every level.
if (weight > .01 && weight <= .12) {
weight = (raw_value – zero_factor) / calibration_factor_low;
weight = weight + .000;
}
if (weight > .12 && weight <= .2) {
weight = (raw_value – zero_factor) / calibration_factor_low;
weight = weight + .01;
}
if (weight > .21 && weight <= .53) {
weight = (raw_value – zero_factor) / calibration_factor_low;
weight = weight + .024;
}
if (weight > .53 && weight <= 1.13) {
weight = (raw_value – zero_factor) / calibration_factor_low;
weight = weight + .042;
}
if (weight > 1.13 && weight <= 2.13) {
weight = (raw_value – zero_factor) / calibration_factor_low;
weight = weight – .030;
}
if (weight > 2.13 && weight <= 3.13) {
weight = (raw_value – zero_factor) / calibration_factor_low;
weight = weight – 0.015;
}
if (weight > 3.13 && weight <= 4.13) {
weight = (raw_value – zero_factor) / calibration_factor_mid;
weight = weight + 0.07;
}
if (weight > 4.13 && weight <=5.13) {
weight = (raw_value – zero_factor) / calibration_factor_mid;
weight = weight – 0.214 ;
This was important because, in the past, when I added small weights like 250 grams or 50 grams on top of 1, 2, 3, 4, or 5 kilograms, the readings would be a bit off. With this new approach, those issues are gone.
Now, you might be wondering what the zero_factor is. Let me explain: without setting the zero_factor value, you cannot get accurate results. You need to define this value at the start of your program.
long zero_factor = 50000; // Stores the zero offset value
To find the zero_factor value, I used a separate program that lets you manually zero the scale.
Arduino Zero Factor Program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include "HX711.h" // HX711 circuit wiring #define DOUT 3 #define CLK 2 HX711 scale; long zero_factor = 0; void setup() { Serial.begin(9600); scale.begin(DOUT, CLK); // Zeroing the scale manually // uncomment the following instructions and find the zero factor value // when there is no weight or pressure on the load cell // then copy and paste that value in the zero factor variable above zero_factor = scale.read_average(10); // Average of 10 readings Serial.println("Zero Factor Value: "); Serial.println(zero_factor); } void loop() { zero_factor = scale.read_average(10); // Average of 10 readings Serial.println("Zero Factor Value: "); Serial.println(zero_factor); } |
This step is very important because, if you don’t manually zero the scale, you will get incorrect readings. When you run this program, make sure there is no weight on the scale.
Different values will display, and you can choose one of them, copy it, and assign it to the zero_factor variable in the main program.
Arduino DIY Scale Program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
#include "HX711.h" #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // HX711 circuit wiring #define DOUT 3 #define CLK 2 HX711 scale; long zero_factor = 49763; // Stores the zero offset value float calibration_factor_low = 419640; // Calibration factor for lower weights float calibration_factor_mid = 407000; // Calibration factor for mid-range weights float weight; #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); void setup() { scale.begin(DOUT, CLK); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); delay(2000); display.clearDisplay(); display.setTextColor(WHITE); } void loop() { // Read raw data from the HX711 long raw_value = scale.read_average(10); // Average of 10 readings // Determine which calibration factor to use based on weight float weight = (raw_value - zero_factor) / calibration_factor_low; //weight = weight - 0.04; if (weight > .01 && weight <= .12) { weight = (raw_value - zero_factor) / calibration_factor_low; weight = weight + .000; } if (weight > .12 && weight <= .2) { weight = (raw_value - zero_factor) / calibration_factor_low; weight = weight + .01; } if (weight > .21 && weight <= .53) { weight = (raw_value - zero_factor) / calibration_factor_low; weight = weight + .024; } if (weight > .53 && weight <= 1.13) { weight = (raw_value - zero_factor) / calibration_factor_low; weight = weight + .042; } if (weight > 1.13 && weight <= 2.13) { weight = (raw_value - zero_factor) / calibration_factor_low; weight = weight - .030; } if (weight > 2.13 && weight <= 3.13) { weight = (raw_value - zero_factor) / calibration_factor_low; weight = weight - 0.015; } if (weight > 3.13 && weight <= 4.13) { weight = (raw_value - zero_factor) / calibration_factor_mid; weight = weight + 0.07; } if (weight > 4.13 && weight <=5.13) { weight = (raw_value - zero_factor) / calibration_factor_mid; weight = weight - 0.214 ; } if (weight <= 0.01 ){ weight = 0; } display.clearDisplay(); display.setTextSize(3); display.setCursor(0,0); // column row display.print("Weight:"); display.setTextSize(3); display.setCursor(0,35); display.print(weight,3); display.setTextSize(3); display.setCursor(92,35); //75,35 display.print("Kg"); display.display(); } |
#include “HX711.h”
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
I have explained how to install these libraries in the previous article. If this is your first time working on a weighing scale project, I highly recommend reading that article. In that article, I covered everything from the basics, including how a load cell works and many other details.
Anyway, I have already uploaded this program and now let’s watch the DIY Scale in action.
DIY Weighing Scale vs. Commercial Weighing Scale:
Let’s start with a commercial scale first. I am going to start with 100 grams.
The scale shows 102 grams. I am not sure if the issue is with this weight or if the scale is reading it wrong. Let’s see how it reads the other weights.
Next, I will check 200 grams.
The scale shows 192 grams. This time it’s showing 8 grams less. Earlier, it showed 2 grams more. We will find out in a bit when I check these weights on my own weighing scale. Anyway, let’s check the next weight.
This one is 500 grams.
This time, the difference is quite a lot. You can clearly see it shows 486 grams, which is 14 grams off. It seems like the scale’s calibration isn’t accurate for lighter weights. Let’s check the next weight.
Here is 1 kilogram weight.
The scale shows 978 grams, a difference of 22 grams. This scale is not good for the shop owner because a 22-gram difference can cause bigger losses over time. Let’s check the other weights.
Now, this is 2 kilograms.
The scale reads 2.082 kilograms, showing 82 grams more this time. It’s clear that this scale isn’t calibrated correctly. If it were, there wouldn’t be such big differences. Anyway, let’s check the next weight.
Here is a 3-kilogram weight.
The scale shows 3.088 kilograms, which is a big difference. I was not expecting such a difference in a commercial scale. Let’s check the next weight.
This one is 4 kilograms.
Now, the scale shows 3.9 kilograms, a 100-gram difference. Earlier, it was 88 grams over, and now it is 100 grams under.
This time, let’s measure 5 kilograms using the 3-kilogram and 2-kilogram weights together.
As you can see, the scale reads 5.172 kilograms, which is 172 grams off. That is a big difference. Now, we will find out if the problem is with this scale or with all the weights when we check them on my DIY weighing scale. So, let’s start the testing.
DIY Weighing Scale Accuracy Test:
Let’s start with the 100 grams weight.
On the display, you can see it shows 99 grams; just a 1-gram difference, while the commercial scale showed 2 grams more.
Let’s check the 200 grams weight.
On the display, it shows 197 grams, which is close to 200 grams. On the commercial scale, it was 192 grams, which was an 8-gram difference.
Let’s check the 500 grams weight.
This is amazing – it shows 499 grams, just 1 gram off. On the commercial scale, it was 486 grams, a difference of 14 grams. My scale only has a 1-gram difference. This accuracy is possible because of the calibration. Let’s check another weight.
This is a 1-kilogram weight.
Perfect accuracy! On the other scale, it was 978 grams, a difference of 22 grams. On my DIY scale, it’s exactly 1 kilogram. As I mentioned, this accuracy is due to calibration at different levels. Let’s check the next weight.
This is a 2-kilogram weight.
The display shows 2.007 kilograms – again, simply amazing. Only a 7-gram difference. For a 2-kilogram weight, a difference of 5 to 10 grams is acceptable. On the other scale, the difference was 82 grams, while on my DIY scale, it’s just 7 grams. Let’s check the next weight.
This is a 3-kilogram weight.
You can see it shows 3.006 kilograms, which is very close to 3 kilograms. Just a 6-gram difference. This is nothing! Even a difference of 10 grams would be acceptable. On the commercial scale, it was 88 grams off. That was too much. This scale is working perfectly. Let’s check the next weight.
This is a 4-kilogram weight.
This is mind-blowing – it’s showing 4.004 kilograms, just a 4-gram difference. When we measured the same weight on the commercial scale, it was off by 100 grams, while on my scale, it’s only 4 grams.
Now, let’s measure 5 kilograms using the 3-kilogram and 2-kilogram weights together.
As you can see, the scale reads 5.001 kilograms, just a 1-gram difference. On the other scale, it was off by 172 grams. In terms of accuracy, the DIY weighing scale is the winner.
The programming approach I used for the 5-kilogram load cell can be used for other load cells too. So, that’s all for now.