For precision weighing and force measurement in embedded projects, the 24-bit NAU7802 I2C ADC paired with a 5kg aluminum parallel beam load cell is the definitive choice for modern builds. It offers over 16 million counts of resolution without the strict timing bugs and watchdog resets that plague older serial-based modules on dual-core RTOS environments. Below is the exact blueprint for wiring, scaling, and filtering this sensor technology application on an ESP32.
The Sensing Principle: Strain Gauges and Wheatstone Bridges
A load cell uses foil strain gauges bonded to a deformable metal element, typically an aluminum parallel beam. When force is applied, the metal bends, stretching or compressing the foil. This physical deformation changes the electrical resistance of the foil by a tiny fraction of an ohm. To measure this minuscule change, four strain gauges are wired into a Wheatstone bridge configuration, converting the resistance shift into a differential voltage proportional to the applied force (All About Circuits: Wheatstone Bridges).
The raw differential voltage output is incredibly small—typically 1mV to 2mV per volt of excitation (mV/V) at full scale. If you excite a 2mV/V cell with 3.3V and apply the maximum 5kg load, the bridge outputs just 6.6mV. Because a standard ESP32 12-bit ADC cannot resolve microvolt-level changes and lacks a programmable gain amplifier (PGA), you cannot wire a load cell directly to a microcontroller's analog pin. You must use a dedicated 24-bit sigma-delta ADC with an integrated PGA to amplify and digitize the signal before the microcontroller ever sees it.
Output Signal Reality: Digital Words, Not Analog Voltages
A common beginner mistake in sensor technology applications is conflating the analog nature of the raw strain gauge with the output the microcontroller actually reads. The ESP32 does not read a voltage; it reads a 24-bit signed digital integer transmitted over a digital bus.
Historically, makers used the HX711 module. The HX711 outputs this 24-bit word via a proprietary, non-standard serial protocol requiring precise microsecond clock pulsing. On an ESP32 running FreeRTOS, background WiFi tasks frequently interrupt this timing, causing missed reads or watchdog resets. The modern solution is the NAU7802, which outputs the exact same 24-bit resolution but communicates over standard I2C, allowing the ESP32's hardware I2C peripheral and FIFO buffers to handle the data transfer reliably in the background.
Wiring, Pinout, and Power Requirements
The load cell itself uses a 4-wire color code (Excitation+, Excitation-, Signal+, Signal-). The NAU7802 breakout board handles the analog front-end and bridges it to the ESP32's digital I2C bus. Below is the exact wiring matrix for a 3.3V ESP32 DevKit v1.
| Component | Pin / Wire | Connects To | Supply / Logic Range |
|---|---|---|---|
| Load Cell (Red) | E+ (Excitation+) | NAU7802 VCC / AVDD | 3.3V (Max 4.2V) |
| Load Cell (Black) | E- (Excitation-) | NAU7802 GND | 0V (Common Ground) |
| Load Cell (White) | A+ (Signal+) | NAU7802 VIN+ | 0V - 3.3V (Differential) |
| Load Cell (Green) | A- (Signal-) | NAU7802 VIN- | 0V - 3.3V (Differential) |
| NAU7802 Breakout | SDA | ESP32 GPIO 21 | 3.3V Logic (I2C) |
| NAU7802 Breakout | SCL | ESP32 GPIO 22 | 3.3V Logic (I2C) |
| NAU7802 Breakout | 3V3 / GND | ESP32 3V3 / GND | 3.3V, min 150mA capable |
Raw-to-Unit Math: Scaling and Calibration
The NAU7802 outputs a 24-bit signed integer. This means your raw reading ranges from -8,388,608 to +8,388,607. With no weight on the scale (tare), the reading will hover somewhere near the midpoint (e.g., 0 or a small offset depending on PGA gain). To convert this raw digital word into grams, you must perform a two-point calibration: finding the Tare Offset and the Calibration Factor.
The Math:
Weight_in_Grams = (Raw_ADC_Reading - Tare_Offset) / Calibration_Factor
Worked Numeric Example:
- Step 1 (Tare): With the scale empty, read the sensor 50 times and average it. Let's say your
Tare_Offsetis 12,450. - Step 2 (Span): Place a certified 1,000g calibration weight on the beam. Read the sensor 50 times and average it. Let's say the raw reading stabilizes at 4,850,120.
- Step 3 (Calculate Delta): 4,850,120 (Loaded) - 12,450 (Tare) = 4,837,670 counts.
- Step 4 (Calculate Factor): 4,837,670 counts / 1,000g = 4,837.67. This is your
Calibration_Factor.
Now, if you place an unknown object on the scale and the raw reading is 2,431,285, the math is: (2,431,285 - 12,450) / 4,837.67 = 500.01 grams.
Interference Sources and Mitigation
When dealing with microvolt-level analog signals before the ADC, noise is your primary enemy. Here are the three most common interference sources in this sensor technology application and how to kill them:
- 50/60Hz Mains Hum: Running unshielded load cell wires parallel to AC mains cables induces electromagnetic interference. Fix: Route sensor wires at 90-degree angles to AC lines, and implement a software moving-average filter of at least 20 samples (covering one full AC cycle at 50Hz/60Hz).
- Thermal EMFs (Seebeck Effect): If your solder joints on the A+ and A- pads use different amounts of solder or experience a temperature gradient, they act as tiny thermocouples, generating microvolts of DC offset drift. Fix: Keep the NAU7802 board away from heat-generating components (like the ESP32's voltage regulator or WiFi antenna) and allow a 5-minute thermal warm-up before calibrating.
- Mechanical Creep and Hysteresis: Aluminum beams exhibit "creep" where the reading slowly drifts under a constant static load over 10-20 minutes. Fix: For static weighing, trigger a rapid tare sequence right before measurement, or upgrade to a stainless steel shear-beam load cell for long-term static monitoring.
Decision Path: Selecting Your Load Cell Interface
Do not waste time guessing which ADC module to buy. Follow this decision tree to select the exact part for your workbench:
| If your project requires... | Then choose... | Why? |
|---|---|---|
| Ultra-low cost, Arduino Uno, simple serial logging | HX711 Module (Generic) | Cheap ($2), but proprietary timing fails on RTOS/WiFi MCUs. |
| ESP32/ESP8266, WiFi/BLE active, high precision | NAU7802 Breakout | Standard I2C prevents RTOS timing crashes; built-in LDO. |
| Industrial 4-20mA loop, PLC integration | Dedicated Load Cell Transmitter | Microcontrollers cannot natively drive 4-20mA current loops. |
Step-by-Step: Interfacing the NAU7802 with ESP32
Follow these exact steps to get your first calibrated reading using the Arduino IDE and the official SparkFun library.
- Install the Library: Open Arduino Library Manager, search for
SparkFun Qwiic Scale NAU7802, and install it. - Configure I2C: Wire SDA to GPIO 21 and SCL to GPIO 22. The NAU7802 default I2C address is
0x2A. - Set the Gain (LDO): In your
setup()function, initialize the scale and set the internal LDO to 3.3V. Do not exceed the load cell's rated excitation voltage.scale.begin(Wire, 0x2A); scale.setLDO(NAU7802_LDO_3V3); - Set Gain and Sample Rate: Set the PGA gain to 128x for a standard 5kg cell, and the sample rate to 80 SPS (Samples Per Second) to reject 50/60Hz mains noise via the ADC's internal digital filter.
scale.setGain(NAU7802_GAIN_128); scale.setSampleRate(NAU7802_SPS_80); - Calibrate (Zero): Ensure the scale is empty. Call
scale.calibrateAFE();to perform an internal auto-zero, then read 50 samples in a loop to establish your softwareTare_Offset. - Verify with Known Mass: Place a 1kg weight. Read the raw value, subtract the tare, and divide by 1000 to derive your
Calibration_Factor. Hardcode this factor into your production firmware.
By treating the load cell not as a simple analog sensor, but as a precision digital transducer system, you eliminate the noise, timing crashes, and drift that ruin most embedded weighing projects. Stick to the I2C NAU7802, respect the Wheatstone bridge physics, and your ESP32 will deliver lab-grade measurements consistently.






