HX711 and load cell

The HX711 load cell amplifier on its green board, wired to a bar load cell: the kitchen scale every kit builds. Aliases: load cell, scale, weight sensor.

A load cell is an aluminum bar with four strain gauges glued to it in a Wheatstone bridge. Weight on the free end bends the bar a few micrometers, and the bridge's output moves by about a millivolt per volt of supply at full load. No Arduino ADC can see that, so the HX711 is a 24-bit converter with an amplifier in front of it and a two-wire serial output of its own, neither I2C nor SPI.

Pins

Pin What it does
GND Ground.
DT Data out (the datasheet's DOUT): low when a reading is ready, then the bits.
SCK Clock in (PD_SCK), driven by the board. Held high, it puts the chip to sleep.
VCC Supply, 2.6 V to 5.5 V.

The cell's four wires, red E+, black E-, white A- and green A+, are already connected on the far side of the board.

Properties

capacity is the cell's rated load in kg, 5 by default. sensitivity is its rated output in mV/V, 1.0 by default. zero is its output with nothing on it, 0.02 mV/V by default: no real cell is balanced, which is why every sketch starts with tare(). noise is the chip's input noise in nanovolts rms, 50 by default, the datasheet's figure. rate is 10 or 80 readings a second (the green boards run at 10). load is the weight on the cell when the circuit opens, in grams.

While it runs

Drag the slider to put weight on the free end of the bar, up to the capacity. The weight is drawn on the bar.

What the model gets right

The protocol, from the datasheet. DT is high while a conversion runs and goes low when one is ready. Each rising edge on SCK puts the next bit on DT, most significant first, 24 of them in two's complement. One, two or three more pulses (25, 26 or 27 in all) choose the next conversion's input and gain: channel A at 128, channel B at 32, channel A at 64. SCK held high for more than 60 µs puts the chip to sleep, and taking it low again wakes it, reset to channel A at 128. After a wake or a change of gain the first good reading takes four conversions: 400 ms at 10 a second.

The number. The bridge and the converter run from the same supply, so the supply cancels and the reading is the bridge's ratio times the gain: code = (sensitivity x load / capacity + zero) x 2 x gain x 2^23. With the defaults at gain 128 that is about 430 counts a gram and an offset of about 43 000. On top of that is the input noise, some twenty counts at gain 128, so the last digit of a scale reading grams wanders: that is why the library averages ten readings.

The library

#include "HX711.h" and the tutorial works as written: begin(dt, sck), tare(), set_scale(), get_units(10), read(), read_average(), is_ready(), wait_ready_timeout(), set_gain(), power_down() and power_up(). get_units() returns a float you can print or do sums on, and the calibration tutorial's calibration_factor += 10 loop works as written. The scale itself is kept to a hundredth inside the library.

A hand-written driver has one thing to know: the boards here run in 10 µs slices, so wait at least 10 µs after raising SCK before reading DT (the datasheet allows up to 50). The library does.

What it does not model

Channel B has nothing wired to it on this part, so it reads zero plus the noise; a real floating input reads nonsense. Not modeled either: the cell's creep (a real one reads a little more the longer a load sits on it), temperature drift, and overload: the slider stops at the capacity where a real bar bends for good.

Common mistakes

Forgetting tare(), and reading the cell's own offset as weight.

Calibrating backwards. set_scale() takes counts per unit: print read_average(10) with nothing on and again with a known weight on, and the difference divided by the weight (worked out by hand) is the number to pass.

See it in action

Kitchen scale weighs on an Uno and prints grams. Open it at /templates.