HX711 Load Sensor Demo Using Arduino | Digital Weight Measurement Project

HX711 Load Cell with Arduino – Digital Weighing Scale Tutorial | MakeMindz
Sensors Beginner Arduino 24-bit ADC CirkitDesign

HX711 Load Cell
with Arduino Uno
Digital Weighing Scale

Build a high-precision digital weighing scale with tare, calibration, and real-time weight streaming. Uses the HX711 24-bit ADC amplifier — no complex analog circuits needed.

📅 February 2026 ⏱ 20 min read 🔬 Beginner–Intermediate 📡 24-bit ADC Precision
▶ Open Simulation in CirkitDesign

What This Project Does

This project turns an Arduino Uno and a load cell sensor into a fully functional digital weighing scale. The HX711 amplifier module reads the tiny millivolt signals from the load cell, converts them into precise 24-bit digital data, and streams real-time weight values via the Arduino Serial Monitor.

The sketch guides users through a three-stage flow via serial commands: tare → calibrate → stream. No buttons or LCD required — just a Serial Monitor and a known reference weight.

✔ 24-bit ADC resolution
✔ Tare & calibration built-in
✔ Real-time kg streaming
✔ 2-wire interface only
✔ Works on Uno / Nano / Mega

How the HX711 System Works

⚖️
Load Cell
Converts applied force into a tiny differential voltage via a Wheatstone bridge
🔊
HX711 Amplifier
Amplifies millivolt signal using gain 32/64/128 and converts to 24-bit digital
🧠
Arduino
Reads raw ADC counts, applies tare offset and calibration factor to get kg/g
📡
Serial Output
Streams live kg readings with raw ADC values at 200 ms intervals

Wheatstone Bridge Principle

A load cell contains four strain gauges arranged in a Wheatstone bridge. When weight is applied, the gauges deform, causing a tiny resistance imbalance. This produces a differential voltage of just a few millivolts — far too small for a standard Arduino ADC to read accurately. The HX711 amplifies this signal by up to 128×, then digitises it to 24-bit precision (~16 million counts).

🔬
Why not use Arduino's built-in ADC? Arduino's ADC is only 10-bit (1024 steps) and lacks the differential input and low-noise amplification needed for load cells. The HX711 provides 24-bit resolution with dedicated instrumentation amplifier circuitry.

What You Need

🔵
Arduino Uno
Microcontroller
⚖️
Load Cell
1 kg / 5 kg / 10 kg
🔴
HX711 Module
24-bit ADC amplifier
🔌
Jumper Wires
Male–male & mixed
🔋
USB Cable
For Serial Monitor
⚖️
Known Weight
E.g. 1 kg reference
📦
Library needed: Install HX711 by Bogdan Necula (Bogde) via Arduino Library Manager before uploading the sketch. Search "HX711" and select the Bogde version.

Wiring Diagram

The diagram below shows the complete wiring between the Arduino Uno, HX711 module, and load cell. Only 4 wires connect the HX711 to Arduino and 4 wires connect the load cell to the HX711.

HX711 Load Cell – Circuit Diagram Arduino Uno + HX711 Amplifier + Load Cell ARDUINO UNO R3 USB D4 (DAT) D5 (SCK) 5V GND HX711 24-bit ADC HX711 IC DAT SCK VCC GND E+ E- A+ A- LOAD CELL PLATFORM BASE SERIAL MONITOR Step 1: type: tare > tare Taring (10 samples)... Offset = 43820 > cal 1.000 Cal OK. cpkg=21503.4 kg=1.001 raw=65328 kg=0.998 raw=65290 kg=1.000 raw=65320 USB Wire Legend D4 → DAT (data) D5 → SCK (clock) 5V → VCC (dashed) GND → GND (dashed) Load Cell Wires Red → E+ (excitation +) Black → E- (excitation -) White → A+ (signal +) Green → A- (signal -)
⚠️
Load cell wire colours vary by manufacturer. Always check your load cell datasheet. Common mapping: Red=E+, Black=E-, White=A+(S+), Green=A-(S-). Yellow wire (if present) is shield/ground — connect to GND.

Wiring Reference Tables

HX711 → Arduino Uno

HX711 PinArduino PinPurpose
VCC5VPower supply
GNDGNDGround
DAT (DT)D4Serial data output
SCK (CLK)D5Serial clock input

Load Cell → HX711

Load Cell WireHX711 TerminalFunction
🔴 RedE+Excitation positive
⚫ BlackE-Excitation negative
⬜ WhiteA+Signal positive
🟢 GreenA-Signal negative
💡
The HX711 has two input channels (A and B). This project uses Channel A with gain 128, which is the default and most sensitive setting for a single load cell.

 


Building the Project

1

Install the HX711 Library

Open Arduino IDE → Sketch → Include Library → Manage Libraries. Search "HX711" and install the version by Bogdan Necula (Bogde). This library provides the tare(), set_scale(), and get_units() functions used in the sketch.

2

Connect Load Cell to HX711

Wire the four load cell wires to the HX711 screw terminals: Red→E+, Black→E-, White→A+, Green→A-. Tighten the terminals firmly to avoid loose connections that cause noisy readings.

⚠️
Check your datasheet — some load cells use different colour conventions. Swapping E+ and E- just inverts the reading; swapping A+ and A- also inverts it.
3

Wire HX711 to Arduino

Connect: VCC → 5V, GND → GND, DAT → D4, SCK → D5. Only 2 signal wires are needed — the HX711 uses a simple synchronous serial protocol (not I²C or SPI).

4

Upload the Sketch

Copy the code from Section 9 below. In Arduino IDE, select Board: Arduino Uno and the correct COM port. Click Upload. Open Serial Monitor at 115200 baud.

5

Mount the Load Cell

Fix the load cell base firmly to a stable surface. Attach a platform plate to the sensing end. Ensure the load cell is level — tilt causes measurement error. Keep the weighing platform free from contact with anything else.

6

Tare → Calibrate → Stream

Follow the three-step calibration process described in Section 8 below. Type commands into the Serial Monitor. Once calibrated, live weight readings stream automatically every 200 ms.

Three-Step Calibration Flow

The sketch uses a guided serial command flow. Open the Serial Monitor at 115200 baud and follow these three steps:

Remove all weight
Platform must be empty
type: tare
Place known weight
E.g. 1 kg reference mass
cal 1.000
Live streaming
Real-time kg every 200ms
automatic
🔄
Need to redo calibration? Type reset at any time to restart the tare → calibrate flow without re-uploading the sketch.
📐
Calibration factor (counts_per_kg) is calculated as: (raw_reading_with_mass − tare_offset) ÷ known_mass_in_kg. The sketch does this automatically and prints the result so you can save it for future use.

Arduino Sketch

Complete sketch with tare, calibration, and live streaming. Uses the Bogde HX711 library. Copy and paste into Arduino IDE or CirkitDesign's code editor.

Arduino C++ — HX711 Weighing Scale
// HX711 Load Cell – Tare → Calibrate → Stream (kg)
// Library: "HX711" by Bogdan Necula (Bogde)
// Wiring:  DAT → D4,  SCK → D5
// MakeMindz.com | February 2026

#include <HX711.h>

const uint8_t PIN_DOUT = 4;   // DAT pin
const uint8_t PIN_SCK  = 5;   // SCK pin

// ── Tunables ─────────────────────────────────
const uint8_t AVG_TARE   = 10;   // samples for tare
const uint8_t AVG_CAL    = 10;   // samples for calibration
const uint8_t AVG_STREAM = 5;    // samples per streamed reading
const unsigned long STREAM_MS = 200;  // stream interval (ms)

HX711 scale;

enum Stage { WAIT_TARE, WAIT_CAL, STREAMING };
Stage stage = WAIT_TARE;

unsigned long lastStream = 0;
String inLine;

void printIntro() {
  Serial.println(F("─────────────────────────────────────────"));
  Serial.println(F("  HX711 Digital Weighing Scale | MakeMindz"));
  Serial.println(F("  Commands: tare | cal <kg> | reset"));
  Serial.println(F("─────────────────────────────────────────"));
  Serial.println(F("Step 1: Remove all load. Type: tare"));
}

void setup() {
  Serial.begin(115200);
  while (!Serial) { }  // wait for USB

  scale.begin(PIN_DOUT, PIN_SCK);
  scale.set_gain(128);  // Channel A, gain 128

  printIntro();
}

void handleSerial() {
  while (Serial.available()) {
    char c = (char)Serial.read();
    if (c == '\r') continue;
    if (c == '\n') {
      inLine.trim();
      inLine.toLowerCase();

      if (inLine == "reset") {
        stage = WAIT_TARE;
        Serial.println(F("Reset. Step 1: type 'tare' with no load."));

      } else if (stage == WAIT_TARE) {
        if (inLine == "tare") {
          Serial.print(F("Taring ("));
          Serial.print(AVG_TARE);
          Serial.println(F(" samples)..."));
          scale.tare(AVG_TARE);
          Serial.print(F("Offset = "));
          Serial.println(scale.get_offset());
          stage = WAIT_CAL;
          Serial.println(F("Step 2: Place known mass. Type: cal <kg>"));
          Serial.println(F("  Example: cal 1.000"));
        } else if (inLine.length()) {
          Serial.println(F("Type 'tare' with no load on the scale."));
        }

      } else if (stage == WAIT_CAL) {
        if (inLine.startsWith("cal ")) {
          double kg = inLine.substring(4).toFloat();
          if (kg <= 0.0) {
            Serial.println(F("ERR: mass must be > 0. e.g., cal 1.000"));
          } else {
            // Flush stale conversions before sampling
            (void)scale.read();
            (void)scale.read();

            long rawAvg = scale.read_average(AVG_CAL);
            long offset = scale.get_offset();
            long delta  = rawAvg - offset;

            Serial.print(F("rawAvg=")); Serial.print(rawAvg);
            Serial.print(F("  delta=")); Serial.println(delta);

            if (delta == 0) {
              Serial.println(F("ERR: no change from tare. Check mass or re-tare."));
            } else {
              double counts_per_kg = (double)delta / kg;
              scale.set_scale(counts_per_kg);

              Serial.print(F("Cal OK. counts_per_kg="));
              Serial.println(counts_per_kg, 1);

              double kg_verify = scale.get_units(AVG_CAL);
              Serial.print(F("Verify: "));
              Serial.print(kg_verify, 3);
              Serial.println(F(" kg"));

              Serial.println(F("─── Streaming kg (type 'reset' to redo) ───"));
              stage = STREAMING;
              lastStream = 0;
            }
          }
        } else if (inLine.length()) {
          Serial.println(F("Type: cal <kg>  e.g., cal 1.000"));
        }
      }
      inLine = "";
    } else {
      inLine += c;
    }
  }
}

void loop() {
  handleSerial();

  if (stage == STREAMING) {
    unsigned long now = millis();
    if (now - lastStream >= STREAM_MS) {
      lastStream = now;

      double kg     = scale.get_units(AVG_STREAM);
      long   rawAvg = scale.read_average(AVG_STREAM);
      long   delta  = rawAvg - scale.get_offset();

      Serial.print(F("kg="));      Serial.print(kg, 3);
      Serial.print(F("  raw="));   Serial.print(rawAvg);
      Serial.print(F("  delta=")); Serial.println(delta);
    }
  }
}

Expected Serial Output

Open Serial Monitor at 115200 baud. You will see this guided flow:

─────────────────────────────────────────
HX711 Digital Weighing Scale | MakeMindz
Commands: tare | cal <kg> | reset
─────────────────────────────────────────
Step 1: Remove all load. Type: tare
 
> tare
Taring (10 samples)...
Offset = 43820
Step 2: Place known mass. Type: cal <kg>
Example: cal 1.000
 
> cal 1.000
rawAvg=65323 delta=21503
Cal OK. counts_per_kg=21503.0
Verify: 1.000 kg
─── Streaming kg (type 'reset' to redo) ───
kg=1.001 raw=65340 delta=21520
kg=0.999 raw=65298 delta=21478
kg=1.000 raw=65322 delta=21502
kg=0.428 raw=53035 delta=9215
kg=0.000 raw=43828 delta=8

Test in CirkitDesign

🖥️ Simulate in Your Browser — Free

Import the diagram.json, paste the sketch, and test the tare/calibration flow without any physical hardware.

▶ Open CirkitDesign Simulator

What you can do in simulation:

  • ⚖️ Apply virtual load to the load cell and observe weight changes
  • 📡 Watch real-time kg values streaming in the virtual Serial Monitor
  • 🔁 Test the tare and reset commands interactively
  • 🔢 Adjust the calibration factor to match different load cell ranges
  • 📊 Observe raw ADC values vs calibrated kg output side by side

What You Can Build With This

⚖️DIY Weighing Scale
🍳Smart Kitchen Scale
🏭Industrial Monitor
📦Package Verifier
🌐IoT Inventory
🔬Force Experiments

Upgrade Ideas

📺 Add 16×2 LCD display
📶 Bluetooth weight logging
☁️ WiFi + ESP32 IoT dashboard
📱 OLED display integration
🔔 Overweight buzzer alert

Related Sensor & IoT Tutorials

Comments

try for free