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.
▶ Open Simulation in CirkitDesignWhat 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.
How the HX711 System Works
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).
What You Need
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.
Wiring Reference Tables
HX711 → Arduino Uno
| HX711 Pin | Arduino Pin | Purpose |
|---|---|---|
| VCC | 5V | Power supply |
| GND | GND | Ground |
| DAT (DT) | D4 | Serial data output |
| SCK (CLK) | D5 | Serial clock input |
Load Cell → HX711
| Load Cell Wire | HX711 Terminal | Function |
|---|---|---|
| 🔴 Red | E+ | Excitation positive |
| ⚫ Black | E- | Excitation negative |
| ⬜ White | A+ | Signal positive |
| 🟢 Green | A- | Signal negative |
Building the Project
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.
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.
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).
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.
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.
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:
reset at any time to restart the tare → calibrate flow without re-uploading the sketch.
(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.
// 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:
Test in CirkitDesign
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
.png)
Comments
Post a Comment