arduino intermediate 40 min

Arduino: build a digital scale with a load cell and HX711

Turn a $8 load cell into a working digital scale with the HX711 amp and an Arduino Uno. Wiring, the calibration step everyone skips, and 1 g resolution.

Code available for: Arduino CESP32 Arduino
Published Sep 22, 2026

A load cell is a strain gauge in a metal frame: put weight on it, the frame flexes a few microns, and a tiny bridge circuit changes by a few millivolts. Those millivolts are far below what any microcontroller ADC can read directly. The HX711 exists to amplify and digitize exactly that signal, 24 bits at a time, for about $2.

The ESP32 version of this build lives in another tutorial. This one is the Arduino Uno take, and the trap I hit on mine applies to both: I screwed the load cell flat to a board, put a mug on it, and read noise. Load cells need to flex. Screwed flat to a tabletop they cannot, so they report nothing useful. The cell mounts through the holes on both ends with spacers, force flows through the arrow stamped on the metal, and the tabletop idea goes in the bin (e.g. two plates with the cell sandwiched between them on standoffs is the standard mount).

Second trap, quieter: the calibration factor everyone copies from tutorials is somebody else’s number. Mine needed 426.7. Yours needs its own. The two-step calibration below takes five minutes and is the difference between “reads something” and “reads grams.”

What you need

Needed

ItemQtyPurposeEst. cost
Arduino Uno or Nano1the brain$10-$25
Load cell, 5 kg bar type (four wire: red/black/white/green)1the sensor$8
HX711 breakout (green board, two big screw terminals)1amplifies + digitizes$2
Mounting plate + 4 spacers, or printed brackets1 setlets the cell flex$0-$5
Jumper wires6connections$3

Pick the cell capacity for the job (e.g. 1 kg for a kitchen scale, 5 kg general, 20 kg for a pet feeder, 100 kg under a beehive). A cell rated way above your use reads coarse; way below, it saturates.

Nice to have

  • Soldering iron and solder if you want the wires crimped into the screw terminals instead of just trapped under them
  • Wire stripper for making clean ends
  • Multimeter (e.g. to verify continuity between the cell wires and the HX711 screw terminals after assembly)
  • Anti-static wristband: the HX711 front end is a sensitive analog part and worth the two seconds of caution

Wiring

The load cell wires land on the left screw terminals, the logic pins on the right header:

Wire key: VCC5VGNDDATAD-pinSCK
HX711 pinConnects to
E+load cell RED wire
E-load cell BLACK wire
A-load cell WHITE wire
A+load cell GREEN or BLUE wire
VCCArduino 5V
GNDArduino GND
DT (DOUT)Arduino D3
SCKArduino D2

Wire colors vary by manufacturer, which is the top cause of “my scale reads negative.” The mapping above is the standard 5 kg bar from SparkFun and most sellers.

Power the HX711 from 5V on an Uno and keep the data lines there too. The HX711’s DOUT swings to VCC, so on a 3.3V board (ESP32) you power it from 3.3V instead. Mixing 5V VCC with 3.3V logic is the classic way to end up with a module that talks garbage or nothing.

Install

Arduino IDE >> Sketch >> Include Library >> Manage Libraries >> search “HX711” >> install the one by bogde. It is called HX711 Arduino Library and it is the one every example on the internet assumes.

The code

#include "HX711.h"

#define LOADCELL_DOUT_PIN 3
#define LOADCELL_SCK_PIN  2

HX711 scale;

void setup() {
  Serial.begin(115200);
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);

  Serial.println("Remove all weight, stabilizing...");
  delay(2000);
  scale.tare();          // zero: current reading = 0 grams
  Serial.println("Tared.");

  // Calibration factor: YOUR number, see the calibration section.
  // 228.0f is a starting point for a 5 kg bar cell at 5V; mine needed 426.7.
  scale.set_scale(228.0f);
  Serial.println("Calibration guess loaded. Calibrate for real (below).");
}

void loop() {
  if (scale.is_ready()) {
    float grams = scale.get_units(10);   // average of 10 readings
    Serial.print("Weight: ");
    Serial.print(grams, 1);
    Serial.println(" g");
  } else {
    Serial.println("HX711 not ready");
  }
  delay(500);
}

Tare the empty scale, set a factor, read grams in a loop. The two-step calibration replaces the guess with your number:

  1. Leave the tare() in setup, nothing on the plate.
  2. Add this line to loop() temporarily and place a known weight (e.g. a new roll of nickels is 200 g, a US dime is 2.268 g, or that bag of sugar with “1000 g” printed on it):
Serial.println(scale.read_average(20));   // raw counts
  1. Divide: calibration_factor = raw_reading / known_grams. Put that number in set_scale() and delete the debug line. Done. That number is specific to your cell and your supply voltage, and it will land within a few percent every time after that.

The mechanical setup

The cell only works if force flows through its arrow. One end bolts to your base, the other to the platform the weight sits on, with the spacers holding the gap. 3D printed brackets exist for every cell size; search “load cell mount 5kg” on any print site. Direct flat-mount against the table reads the table’s stiffness, not your mug.

What resolution to expect

The HX711’s 24 bits is the spec, the cell’s rated output is the truth. At 5 kg full scale with 1 mV/V sensitivity you get roughly 5 mV of signal, and the 128x gain turns that into about 640 mV of useful range. Real world: 0.1 g needs the 10-sample average and a stable bench, 1 g is solid and repeatable, and milligram claims are noise-floor fantasies. Do not chase them from a single cell.

What you learned

  • Load cells output millivolts; the HX711 amplifies and digitizes them over a two-wire serial link.
  • tare() zeroes, set_scale() converts counts to grams, and the factor is yours alone.
  • Mounting decides whether the cell can flex, which decides whether you get data.

When something breaks

  • Readings go negative with weight applied: the white and green wires are swapped, or the cell is mounted against its arrow. Fix the wiring first; if the mount is the issue, negating the calibration factor also works and the cell does not care.
  • “HX711 not ready” forever: DT and SCK are swapped, or VCC is floating. The two wires look identical in ribbon cable; swap and retry.
  • Readings drift upward over minutes: thermal drift, real and expected. Tare at startup; for long-running projects re-tare on a schedule or on a button press.
  • Values jump by grams between reads: wobbly surface or a loose screw terminal. Average more samples (get_units(20)) and check the terminal screws with a small screwdriver.
  • Everything works until a Wi-Fi or relay project shares the board: the HX711 hates noise on its supply. The relay module tutorial’s wiring notes cover isolating the supply; the one-line version is a 100 uF cap across the HX711’s VCC and GND.

What to build next

  • A pet feeder: this scale plus the servo tutorial, plus a timer, weighs portions instead of guessing them.
  • A kitchen scale with tare button: add a push button on D4 that calls scale.tare(), done.
  • The ESP32 weight scale tutorial is the same build with Wi-Fi, which pairs with MQTT publishing: grams on the topic, graph on the dashboard.

The book IoT with ESP32 bundles the sensor tutorials including both versions of this scale.