The HX711 is a precision 24-bit analog-to-digital converter (ADC) designed specifically for weigh scales and industrial control applications. Unlike standard sensors that use I2C or SPI, the HX711 communicates via a custom two-wire serial protocol (Clock and Data). While this makes wiring simple, it also means standard logic analyzers and protocol decoders often struggle to debug it when things go wrong. This guide covers the exact hardware setup, compilable code with hardware-polling safeguards, and the specific failure modes that cause the infamous "hanging" or "zero-read" issues on the bench.
The Arduino HX711 Setup: Parts and Pinout
Before writing code, you need to verify your specific hardware variants. The HX711 market is flooded with cloned breakout boards, and the component choices on these boards directly affect your excitation voltage and logic levels.
- Microcontroller: Arduino Uno R3 (ATmega328P) or Nano v3. (Code targets 5V AVR architecture; ESP32 users must use a logic level shifter or a 3.3V-specific HX711 board).
- Amplifier: HX711 Breakout Board (Green PCB). Hardware Note: Most green boards use a transistor-based LDO that outputs ~4.3V to the HX711 chip, not 5V. This is normal but affects your calibration factor.
- Sensor: 10kg or 20kg Half-Bridge Aluminum Beam Load Cell (e.g., CZL601 or YZC-1B).
- Miscellaneous: M4 screws, rigid aluminum or acrylic base plate, 4-strand 24 AWG shielded cable.
Pin Mapping Table
| HX711 Pin | Arduino Uno/Nano Pin | Function & Notes |
|---|---|---|
| VCC | 5V | Powers the module. Do not exceed 5.5V. |
| GND | GND | Common ground. Must share ground with Arduino. |
| DT (DOUT) | D2 | Data Output. Can be any digital pin. |
| SCK | D3 | Serial Clock. Can be any digital pin. |
Wiring and First Power-On
Load cells use a Wheatstone bridge configuration. The color codes on the 4-strand wire are generally standardized, but Chinese manufacturing batches occasionally swap the signal wires. Always verify with a multimeter before soldering.
- Identify Load Cell Wires: Standard colors are Red (E+ / Excitation+), Black (E- / Excitation-), White (A+ / Signal+), and Green (A- / Signal-). Variation: Some batches use Blue instead of Green.
- Multimeter Verification (Crucial Step): Before connecting to the HX711, measure the resistance. Red-to-Black should read ~400Ω. White-to-Green should read ~350Ω. If your readings are wildly different or show an open circuit (OL), your load cell is damaged or the wires are broken.
- Solder to HX711: Connect Red to E+, Black to E-, White to A+, and Green to A- on the left-side header of the HX711 board.
- Connect Digital Pins: Wire DT to Arduino D2 and SCK to Arduino D3.
- Mechanical Mounting: Bolt the load cell to a rigid base. The overhanging end must be completely free to deflect. Do not let wires touch the moving part of the beam, or you will introduce mechanical hysteresis.
Compilable Code with Error Handling
The standard HX711 library by Bogdan Symchych is the most widely used, but its default read() function is blocking. If the HX711 chip fails to pull the DOUT line low, the Arduino will hang indefinitely. The code below implements a hardware-polling safeguard with a timeout to prevent bricked loops.
Target Board: Arduino Uno R3 / Nano (AVR). Library: HX711 by Bogdan Symchych (install via Arduino Library Manager).
#include "HX711.h"
// Pin Definitions
const int LOADCELL_DOUT_PIN = 2;
const int LOADCELL_SCK_PIN = 3;
HX711 scale;
// Calibration factor. Adjust this based on your known weight test.
// A typical 10kg beam cell starts around -400 to -450.
float calibration_factor = -420.0;
void setup() {
Serial.begin(9600);
Serial.println("HX711 Scale Initialization...");
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
// Check if the HX711 is actually responding before proceeding
unsigned long startTime = millis();
while (!scale.is_ready()) {
if (millis() - startTime > 5000) {
Serial.println("FATAL ERROR: HX711 not found. Check DT/SCK wiring.");
while(1) { delay(1000); } // Halt execution safely
}
delay(50);
}
Serial.println("HX711 connected successfully.");
scale.set_scale(calibration_factor);
scale.tare(); // Reset scale to zero
Serial.println("Tare complete. Place weight on sensor.");
}
void loop() {
// Non-blocking check: only read if the chip signals data is ready
if (scale.is_ready()) {
float reading = scale.get_units(1);
Serial.print("Reading: ");
Serial.print(reading, 1);
Serial.println(" kg");
} else {
// Hardware fault or disconnected wire during operation
Serial.println("Warning: HX711 DOUT line held high. Check connections.");
}
delay(200); // 5 Hz update rate
}
Debugging: Why Is My HX711 Reading Zero or Timing Out?
When an HX711 project fails, it almost always comes down to three physical layer issues. Before rewriting code, check these first three things:
- DT and SCK Swapped: The most common mistake. If DOUT and SCK are reversed, the Arduino sends clock pulses to the data line, and the HX711 ignores them. The code will hang.
- VCC Voltage Drop: Measure the voltage at the VCC pin on the HX711 board while under load. If it drops below 4.8V, your Arduino's 5V rail is sagging, or the module's LDO is failing.
- Load Cell Color Code Mismatch: If A+ and A- are swapped, the bridge output voltage goes negative relative to the HX711's input range, resulting in a hard-pegged reading (usually 0 or 8388607 raw).
Ranked Causes by Exact Error String / Symptom
| Symptom / Error String | Root Cause | Fix |
|---|---|---|
| Code hangs indefinitely (Serial monitor stops printing after "Initialization") | DOUT line is never pulled low. DT/SCK swapped, or SCK pin is stuck HIGH due to a short. | Swap DT and SCK wires. Verify SCK pin with a multimeter (should be LOW when idle). |
| Read: 0.00 or Read: nan | Calibration factor is set to 0, or the load cell signal wires (A+/A-) are disconnected. | Verify A+/A- solder joints. Ensure calibration_factor is a non-zero float. |
| Timeout waiting for HX711 (If using HX711_ADC library) | The library's internal timeout triggered because the chip missed its clock cycle. | Check for electromagnetic interference (EMI) on long unshielded wires. Add a 0.1µF decoupling capacitor across HX711 VCC/GND. |
| Compiler: 'class HX711' has no member named 'set_scale' | Library mismatch. You installed Rob Tillaart's HX711 library but copied code meant for Bogde's library. | Uninstall all HX711 libraries in Library Manager. Reinstall only "HX711" by Bogdan Symchych. |
Extending and Simplifying Your Scale Build
Once you have a stable baseline reading, you can adapt the architecture to fit your specific application constraints.
To Simplify (Non-Blocking Background Reads):
If your main loop handles displays, motors, or WiFi, the standard blocking get_units() function will introduce lag. Switch to the HX711_ADC library by Olav Kallhovd. It uses interrupt-driven or background polling to update the weight variable without pausing the loop() execution. This is mandatory for balancing robots or fast-reacting PID controllers.
To Extend (IoT and Remote Monitoring):
Upgrade the microcontroller to an ESP32 DevKit v1. Wire the HX711 to GPIO 18 (DT) and GPIO 19 (SCK). Use the PubSubClient library to publish the weight data to an MQTT broker (like Mosquitto) every 5 seconds. Warning: The ESP32 is a 3.3V logic device. While the HX711 data line is generally 5V tolerant, it is best practice to power the HX711 from the ESP32's 3.3V pin (if the module supports it) or use a bidirectional logic level shifter on the DOUT line to prevent long-term GPIO degradation.
Frequently Asked Questions
Why does my Arduino HX711 reading drift or fluctuate over time?
Drift is usually caused by three factors: thermal expansion, mechanical creep, or poor grounding. Load cells are temperature-sensitive; a 5°C change in room temperature can shift the zero-point by several grams. Ensure your load cell is not in direct sunlight or near a heat source. Electrically, fluctuating readings (jumping ±20g rapidly) indicate a ground loop or EMI. Route your load cell cables away from AC mains lines and stepper motor drivers, and ensure the Arduino and HX711 share a single, solid ground point.
How to connect two load cells to one Arduino HX711?
You cannot simply wire two load cells in parallel to the same HX711 A+/A- pads; the Wheatstone bridges will interfere with each other. To use two half-bridge load cells (like those found in bathroom scales), you must wire them together to form a single full Wheatstone bridge. Connect the E+ of Cell 1 to E- of Cell 2, and vice versa. The remaining signal wires become your new A+ and A-. Alternatively, use a dedicated "Load Cell Combinator" breakout board which handles the bridge balancing resistors for you.
What is the difference between green and blue HX711 breakout boards?
The green boards are the most common and cheapest, but they typically use a transistor-based voltage regulator that drops the 5V input down to ~4.2V-4.3V for the HX711 chip's analog supply. This lowers the excitation voltage to the load cell, reducing the maximum output signal and slightly degrading the signal-to-noise ratio. The blue boards (often labeled "ZYX" or similar) usually feature a proper low-dropout (LDO) regulator that provides a cleaner, more stable voltage, and sometimes include better onboard decoupling capacitors. For high-precision lab scales, use a blue board or a dedicated PCB with an external precision voltage reference.
How to change Arduino HX711 gain from 128 to 32?
The HX711 has two channels. Channel A has selectable gains of 128 or 64, while Channel B has a fixed gain of 32. By default, the library uses Channel A at 128 gain. To switch to Channel B (32 gain), call scale.set_gain(32); in your setup function. Note that the HX711 datasheet specifies that changing the gain requires 27 clock pulses instead of the usual 25, which the library handles automatically. Channel B is rarely used for standard beam cells but is useful if you have a secondary sensor with a much higher output voltage that would saturate Channel A.






