How to Make a Digital Scale Using a Load Cell with Arduino Mega

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].

Figure 1 – Strain gauge load cell

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.

Figure 2 – Strain Gauge

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.

Figure 3 – HX711 Amplifier

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.

Figure 4 – Scale setup

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 CellHX711HX711Arduino Mega
VCCE+GNDGND
GNDE-DTPin 2
Output –A-SCKPin 3
Output +A+VCC5V
Table 1 – HX711 amplifier connection

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.

Figure 5 – Circuit’s schematic

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).

Figure 6 – HX711 amplifier library on Arduino IDE

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 !!! 😉

Leave a Reply

Your email address will not be published. Required fields are marked *

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

Powered By
100% Free SEO Tools - Tool Kits PRO