In this tutorial, I will show you how to create a digital scale using a load cell and the HX711 amplifier with the Arduino Mega. Load cells can be used in various applications, such as weight measuring, variance over time and presence detection. Here, you will learn how to wire the load cell and the HX711 amplifier to the Arduino, scale it, and finally display the measurements to build a fully functional digital scale.
Parts Required
- Arduino Mega 2560;
- USB 2.0 Cable Type A/B;
- 1 kg Load Cell;
- HX711 Amplifier;
- 4-Digit 7-Segment display;
- 74HC595N Shift Register;
- Male-to-male jumper wires;
- Male-to-female jumper wires;
- 1 Breadboard;
Note: You may need to solder the load cell wires and header pins on the HX711 amplifier.
The Load Cell
A load cell is a transducer which converts force into an electrical signal that can be measured [1].
The inner working of a load cell differs based on the chosen load cell. There are several types of load cells, such as:
- Hydraulic – measures weight as a change in pressure of the internal filling fluid (water or oil);
- Pneumatic – uses pressurised air or gas to balance a given applied force. The amount of air or gas necessary to balance it is correlated to a force measurement;
- Strain gauge – a strain gauge is inside the load cell and converts the load acting on it into an electrical signal.
Regarding strain gauge load cells, these are sensors whose resistance varies with applied force (pressure, tension, weight, etc.), converting it into a change in electrical resistance which can then be measured. A typical strain gauge consists of 3 layers, as shown in Figure 2.
Once bonded to a surface in which a force is being applied, the strain gauge will flex alongside that surface. This causes a shift in electrical resistance proportional to the force being applied [2]. The output of the load cell is then proportional to the force applied, making it possible to calibrate it so that its value can be in any mass unit (e.g., grams, kilograms or pounds). With their wide range of features and capabilities, strain gauge load sensors are the most commonly used among the three types. This type of sensor offers accuracies from within 0.03% to 0.25% full scale and is suitable for almost all industrial applications. However, because the changes in resistance measured by the strain when a force is being applied to it are extremelly small, an amplifier is needed. Usually, for this kind of applications, the load cell we’re using is sold together with an HX711 amplifier, which we will see in more detail right away.
The HX711 Amplifier
According to its datasheet, the HX711 module is a precision 24-bit analog-to-digital converter designed for weigh scales and industrial control applications to interface directly with a bridge sensor. Thus, the HX711 load cell amplifier is used to get measurable data from a load cell and strain gauge.
Once wired the load cell wires on the corresponding side, the HX711 communicates with the Arduino using two-wire interface (Clock and Data), which pins on the other side of the amplifier.
Digital Scale Setup
Once acquiring a load cell sensor, it may come in the form of a kit, which can help you develop your scale. Unfortunately, I wasn’t that lucky (or smart enough), and so I had to improvise. Thus, I started by cutting two round pieces of hard cardboard, which will work as plates. Then I got one 5mm screw and one 4mm screw , along with their corresponding nuts. This was necessary because the screw holes on one side of the load cell are smaller than those on the other (as seen in Figure 1). Finally, I managed to find two solid plastic pieces to use as spacers between the load cell and the two cardboard plates. The surprising result can be seen in Figure 4.
To make this a fully functional digital scale, we must display the measured values from the load cell. For this purpose, I am utilizing a 4-digit 7-segment display. You can refer to our previous tutorial, where we explain its operation and how to set up this hardware correctly.
Circuit
Let’s begin by examining the connections for the HX711 amplifier. For clarity, I’ve provided the following table, as it is the most intuitive way to explain the connections.
Load Cell | HX711 | HX711 | Arduino Mega |
VCC | E+ | GND | GND |
GND | E- | DT | Pin 2 |
Output – | A- | SCK | Pin 3 |
Output + | A+ | VCC | 5V |
Afterward, refer to this tutorial to understand the connections required for setting up the 4-digit 7-segment display and the 74HC595N shift register correctly. The end result should resemble the circuit’s schematic depicted in Figure 5.
Code
Finally, let’s move on to the coding part. Firstly, we need to install the HX711 Arduino Library to utilize the amplifier. Open the Arduino IDE and navigate to Sketch > Include Library > Manage Libraries. Then, search for the library by its name and proceed to install it (see Figure 6).
Moreover, if you haven’t installed it already, download the Timer.h library given in the following link.
https://github.com/JChristensen/Timer/archive/master.zip
This is necessary to implement the multiplexing method in the code and utilize the 4-digit 7-segment display as intended. Then, in the Arduino IDE, navigate to Sketch > Include Library > Add .ZIP Library… and search for the .zip file you have just downloaded (follow the tutorial for more detailed information). I message will appear once the library is downloaded.
Before obtaining the weight values, it’s crucial to scale the load cell and determine the scaling factor. This factor varies from one load cell to another, making it a critical step in this tutorial. To find the scaling factor, copy the following code into the Arduino IDE and place a known weight on the scale.
#include <Arduino.h> // Include the Arduino core library
#include "HX711.h" // Include HX711 amplifier library
// Define HX711 amplifier pins
const int doutPin = 2; // Data output pin
const int sckPin = 3; // Clock pin
HX711 scale; // Create an amplifier object
int val = 0; // Value given by the HX711 amplifier (scaled)
unsigned long lastDisplayUpdate = 0; // Tracks the last time the display has been updated
const unsigned long displayUpdateInterval = 500; // Update display every 500 milliseconds
void setup() {
Serial.begin(9600); // Start serial communication at 9600 baud
// Initialize HX711 amplifier
scale.begin(doutPin, sckPin); // Initiates the data and clock pins of the HX711 amplifier
scale.set_scale(1); // Scalling factor
scale.tare(); // Sets the current value measured by the HX711 amplifier as the reference
}
void loop() {
unsigned long currentMillis = millis();
// Update the display at a fixed interval
if (currentMillis - lastDisplayUpdate >= displayUpdateInterval) {
lastDisplayUpdate = currentMillis;
val = scale.get_units(5); // Read the weight
Serial.print("Weight: ");
Serial.println(val);
}
}
Afterward, check the output value in the serial monitor (accessible via Tools > Serial Monitor). You can compute the scaling factor using the following formula:
scalling factor = (output value)/(known weight)
Lastly, copy the following code into the Arduino IDE and replace the “*your scaling factor*” placeholder in the code with your actual scaling factor.
#include <Arduino.h> // Include the Arduino core library #include "HX711.h" // Include HX711 amplifier library #include "Timer.h" // Include timer library Timer t; // Create a timer object // Define HX711 amplifier pins const int doutPin = 2; // Data output pin const int sckPin = 3; // Clock pin HX711 scale; // Create an amplifier object const int cathodePins[4] = {5, 6, 7, 8}; // Define 4-digit 7-segment display cathode pins // Define 74HC595N shift register pins const int latchPin = 11; // Latch pin const int clockPin = 10; // Clock pin const int dataPin = 12; // Data pin int digits[4]; // Define an array to store the digits of the display // Define which LEDs will turn on for the digits to show the intended character byte numbers[10] { B11111100, // 0 B01100000, // 1 B11011010, // 2 B11110010, // 3 B01100110, // 4 B10110110, // 5 B10111110, // 6 B11100000, // 7 B11111110, // 8 B11110110}; // 9 int val = 0; // Value given by the HX711 amplifier (scaled) unsigned long lastDisplayUpdate = 0; // Tracks the last time the display has been updated const unsigned long displayUpdateInterval = 500; // Update display every 500 milliseconds void setup() { Serial.begin(9600); // Start serial communication at 9600 baud // Initialize cathode pins as outputs and set them to HIGH for (int i = 0; i < 4; i++) { pinMode(cathodePins[i], OUTPUT); digitalWrite(cathodePins[i], HIGH); } // Set shift register pins as outputs pinMode(clockPin, OUTPUT); pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); // Initialize HX711 amplifier scale.begin(doutPin, sckPin); // Initiates the data and clock pins of the HX711 amplifier scale.set_scale(*your scalling factor*); // Scalling factor scale.tare(); // Sets the current value measured by the HX711 amplifier as the reference } void loop() { t.update(); // Update the timer unsigned long currentMillis = millis(); // Update the display at a fixed interval if (currentMillis - lastDisplayUpdate >= displayUpdateInterval) { lastDisplayUpdate = currentMillis; val = scale.get_units(); // Read the weight // Ensure the weight value is within a valid range if (val < 0 || val > 1000){ val = 0; } else { // Print the weight value to the serial monitor Serial.print("Weight: "); Serial.println(val); } // Break the weight value into individual digits break_number(val); } // Display each digit sequentially for (int i = 0; i < 4; i++) { // Activate the latch pin to update the display digitalWrite(latchPin, LOW); // Shift out the byte representing the current digit shiftOut(dataPin, clockPin, LSBFIRST, numbers[digits[i]]); // Activate the corresponding cathode pin to turn on the current digit digitalWrite(cathodePins[i], LOW); // Deactivate the latch pin to apply the changes digitalWrite(latchPin, HIGH); // Delay to show each digit delay(5); // Shows each digit every 5 milliseconds // Turn off the current digit before moving to the next one digitalWrite(cathodePins[i], HIGH); } } // Function to break the weight value into individual digits void break_number(int weight) { digits[0] = weight / 1000; int remainder = weight % 1000; digits[1] = remainder / 100; remainder = remainder % 100; digits[2] = remainder / 10; digits[3] = remainder % 10; }
Results
For a known weight, I used a 120g tuna can. Observe the value displayed on the 4-digit 7-segment display as the tuna can is placed on and removed from the scale!
That’s it! If you enjoyed this tutorial, you can visit our YouTube channel and watch our many tutorials. Thanks for following us and be sure to rate, comment and share our content.
References
[1] https://www.omega.com/en-us/resources/load-cells
[2] https://www.omega.com/en-us/resources/strain-gages
Towards the Future !!! 😉