The Direct Answer: Wiring a Strain Gauge to an Arduino
To interface a passive strain gauge (load cell) with an Arduino, you cannot connect it directly to the microcontroller's analog pins. You must use a 24-bit analog-to-digital converter (ADC) with a built-in programmable gain amplifier (PGA), almost universally the HX711 module. For a standard 10kg straight-bar load cell, wire the HX711 Data (DT) pin to Arduino D2 and Clock (SCK) to D3. Power the HX711 with 5V and GND, and connect the load cell's four wires (E+, E-, A+, A-) to the corresponding HX711 screw terminals.
This guide targets the Arduino Uno R3 (and compatible ATmega328P boards like the Nano or Pro Mini) running the HX711_ADC library by Olav Kallhovd, which provides non-blocking reads and robust timeout error handling.
Why You Need the HX711 (The Physics)
A typical aluminum strain gauge operates on a Wheatstone bridge circuit and outputs a differential voltage proportional to the excitation voltage. The sensitivity is usually rated at 1.0 mV/V to 2.0 mV/V. If you excite the cell with 5V, a full-scale 10kg load generates only 10mV to 20mV.
Parts List & Spec Sheet
Here is the exact hardware required for a reliable bench-scale build, based on current 2026 component availability and pricing.
| Component | Exact Variant / Model | Specs & Notes | Est. Price |
|---|---|---|---|
| Microcontroller | Arduino Uno R3 (Official or Clone) | ATmega328P, 5V logic. Do not use 3.3V boards (ESP32/Zero) without level shifting the HX711 SCK line. | $14 - $27 |
| ADC Module | HX711 Breakout Board (Avia Semiconductor IC) | 24-bit, 80 SPS, Channel A (128x gain). Ensure it has the RATE pin pulled low for 10Hz output. | $2 - $4 |
| Strain Gauge | 10kg or 20kg Straight-Bar Aluminum Load Cell | Full-bridge, 4-wire. Rated output 1.0mV/V. Includes M4 threaded mounting holes. | $8 - $12 |
| Wiring | 22 AWG 4-Conductor Shielded Cable | Shielding is critical to block 50/60Hz mains hum from the high-gain PGA. | $5 / spool |
Pin Mapping & Physical Wiring Steps
The HX711 communicates via a proprietary two-wire serial protocol (not standard SPI or I2C). It requires strict timing on the clock line.
| HX711 Pin | Arduino Uno R3 Pin | Wire Color (Typical) | Function |
|---|---|---|---|
| VCC | 5V | Red | Module power & logic high reference |
| GND | GND | Black | Common ground |
| DT (Data) | D2 | White / Yellow | Serial data out from HX711 to Arduino |
| SCK (Clock) | D3 | Green / Blue | Serial clock from Arduino to HX711 |
Load Cell to HX711 Wiring
- Identify the wires: Standard color codes are Red (E+ / Excitation), Black (E- / Ground), White (A+ / Signal +), and Green (A- / Signal -). Always verify with a multimeter if your load cell lacks a datasheet.
- Measure resistance: You should read ~400Ω between E+ and E-, ~350Ω between A+ and A-, and ~300Ω across the diagonals (E+ to A+).
- Terminate: Strip 5mm of insulation, tin the stranded wire, and secure under the HX711 screw terminals. Ensure the shield drain wire is connected to the HX711 GND terminal at one end only to prevent ground loops.
Complete Compilable Code (HX711_ADC)
Install the HX711_ADC library by Olav Kallhovd via the Arduino Library Manager. This library is vastly superior to the older 'bogde' library because it implements non-blocking reads and hardware timeout flags, preventing your sketch from hanging if a wire comes loose.
#include <HX711_ADC.h>
// --- PIN DEFINITIONS ---
const int HX711_dout = 2; // Data pin
const int HX711_sck = 3; // Clock pin
// --- OBJECT INITIALIZATION ---
HX711_ADC LoadCell(HX711_dout, HX711_sck);
// --- CALIBRATION FACTOR ---
// Change this based on your calibration routine
const float CALIBRATION_FACTOR = -21.5;
const unsigned long STABILIZING_TIME = 2000; // ms to let the ADC settle
const unsigned long READ_INTERVAL = 100; // ms between serial prints
unsigned long lastRead = 0;
void setup() {
Serial.begin(57600);
while(!Serial); // Wait for serial monitor (Leo/Micro) or timeout (Uno)
Serial.println("Initializing HX711...");
LoadCell.begin();
// start() performs a hardware tare and checks for timeouts
// The parameter is the timeout in milliseconds
LoadCell.start(STABILIZING_TIME);
// Check for hardware timeout errors immediately
if (LoadCell.getTareTimeoutFlag()) {
Serial.println("FATAL: HX711 timeout: DT/SCK line stuck HIGH");
Serial.println("Check VCC, GND, and ensure DT/SCK are not swapped.");
while(1) {
// Halt execution to prevent erratic behavior
delay(1000);
}
}
LoadCell.setCalFactor(CALIBRATION_FACTOR);
Serial.println("HX711 initialized and tared successfully.");
}
void loop() {
// Non-blocking update: checks if data is ready without halting the CPU
LoadCell.update();
// Read at specified intervals
if (millis() - lastRead > READ_INTERVAL) {
lastRead = millis();
if (LoadCell.getDataReady()) {
float weight = LoadCell.getData();
// Sanity check for NaN or extreme overflow values
if (isnan(weight) || weight > 50000.0 || weight < -50000.0) {
Serial.println("Error: ADC overflow or NaN. Check load cell seating.");
} else {
Serial.print("Weight: ");
Serial.print(weight, 2);
Serial.println(" g");
}
}
// Check for runtime communication loss
if (LoadCell.getSignalTimeoutFlag()) {
Serial.println("Warning: Signal timeout during read. Wire intermittent?");
LoadCell.resetSignalTimeoutFlag();
}
}
// Optional: Tare via Serial Command
if (Serial.available() > 0) {
char c = Serial.read();
if (c == 't' || c == 'T') {
LoadCell.tareNoDelay();
Serial.println("Tare command received.");
}
}
}
Debugging: First 3 Things to Check When It Fails
Strain gauge circuits are notoriously sensitive. If your serial monitor outputs FATAL: HX711 timeout: DT/SCK line stuck HIGH or your readings are jumping by ±500g erratically, follow this ranked diagnostic path.
1. Verify Excitation Voltage (The 'Stuck High' Fix)
If you see the timeout: DT/SCK line stuck HIGH error, the HX711 is unpowered or in sleep mode. Take your multimeter and measure DC voltage between the E+ and E- terminals on the load cell side. You must read between 4.2V and 4.8V. If it reads 0V, your VCC trace is broken, or your Arduino's 5V rail is browned out. If it reads exactly 5.0V but the HX711 isn't talking, the IC is likely dead (common with cheap clones subjected to static discharge).
2. Check for SCK/DT Pin Swaps
The HX711 protocol is unidirectional per pin. If you accidentally wire Arduino D2 to SCK and D3 to DT, the Arduino will pull the clock line low, but the HX711 will never see the clock pulses, resulting in an immediate timeout. Verify continuity from the HX711 board silkscreen to the exact Arduino digital pins defined in your code.
3. Eliminate Ground Loops and Mains Hum
If the code compiles and runs, but your readings look like 145.22, -89.41, 302.11 (wild swings), you are picking up 50Hz/60Hz electromagnetic interference. The HX711's 128x gain amplifies noise just as much as signal.
The Fix: Ensure your load cell cable is shielded. Connect the shield braid to the Arduino GND only at the Arduino end. Keep the load cell wires at least 6 inches away from any AC mains wiring or switching power supplies.
Extending and Simplifying the Build
Depending on your project requirements, you can scale this architecture up or down.
How to Simplify (No Calibration Required)
If you want to skip the HX711 wiring and calibration math entirely, switch to an I2C Digital Load Cell (like the Adafruit I2C NAU7802 breakout or a fully integrated digital scale module). These feature onboard MCUs that handle the ADC conversion and output calibrated weight directly over I2C, requiring only 4 wires (VCC, GND, SDA, SCL) and zero analog noise debugging.
How to Extend (Multi-Axis & Telemetry)
To build a multi-axis force plate, you can daisy-chain up to four HX711 modules. Because the HX711 uses a proprietary protocol, you cannot share a single clock line easily without multiplexing. Instead, assign a unique DT pin to each HX711, but share the SCK pin across all modules. The HX711_ADC library supports multi-instance arrays. For telemetry, add an ESP32 to the build and push the weight data via MQTT to a Home Assistant dashboard using the PubSubClient library.
Strain Gauge Arduino FAQ
How to calibrate a strain gauge Arduino setup without known weights?
You can perform a 'relative' calibration using the known mass of the mounting hardware, or use a digital kitchen scale to weigh a common object (like a 1-liter bottle of water, which is exactly 1000g at 4°C, or roughly 998g at room temp). Place the object on the cell, read the raw ADC value via the library's getData() function before applying the cal factor, and divide the raw value by your known weight to derive the CALIBRATION_FACTOR. For legal-for-trade applications, you must use NIST-traceable test weights; this DIY method is strictly for prototyping and hobbyist telemetry.
Why is my Arduino strain gauge reading drifting over time?
Drift is primarily caused by thermal expansion and creep. Aluminum load cells expand as ambient temperature changes, altering the baseline resistance of the Wheatstone bridge (typically 0.02% per °C). Additionally, the adhesive bonding the strain gauge foil to the aluminum deforms slightly under sustained load (creep). To mitigate this, implement a software 'auto-tare' routine in your Arduino code that zeroes the scale whenever the reading remains within a ±2g deadband for more than 30 seconds, assuming the platform is empty.
Can I connect multiple strain gauges to one Arduino?
Yes, but with caveats. You can connect up to four HX711 modules to a single Uno R3. Wire the SCK (Clock) pins of all HX711 modules together to a single Arduino pin (e.g., D3), and wire each DT (Data) pin to a separate digital pin (D2, D4, D5, D6). The shared clock pulses all chips simultaneously, and you read the data lines individually. Do not attempt to wire multiple raw load cells to a single HX711 unless you are building a parallel summing junction box with individual trimming resistors, which is an advanced analog technique prone to severe balancing issues.






