← SHEET 02 · ASSEMBLIES EL-010
Bench Power Monitor
| PART NO | EL-010 |
|---|---|
| MATL / SYSTEM | ESP32 · INA219 · SSD1306 |
| TOOLS | Arduino IDE · Wokwi · C++ |
Every other electronics build on this bench eventually asks the same question — how much current does it actually draw, and for how long? This is the meta-tool that answers it: an ESP32 + INA219 monitor that sits in series with any project’s supply rail, reads voltage, current, and power at 10 Hz, integrates them into mAh/mWh on an OLED, and streams a CSV to a laptop for a capacity or consumption plot. It exists to verify the power budgets the other designs only assume — e.g. checking the desk-buddy’s or a plant-waterer’s deep-sleep current against its stated milliamp-hour claim instead of trusting the datasheet.
OVERVIEW & MOTIVATION
A bench power monitor is a small, permanent piece of test equipment rather than a one-off project: wire it once between a bench supply and whatever DUT (device under test) is on the bench that week, and it reports live V/mA/mW plus a running mAh/mWh total since the last reset. The INA219 does the actual current sensing (high-side, through a fixed onboard shunt) so the DUT’s own ground reference is never disturbed. An SSD1306 OLED gives a live readout without a laptop attached; a serial CSV stream gives the same data to a computer for plotting capacity curves or consumption-over-time graphs. A single button both cycles the OLED’s three pages and — held down — zeroes the integrator for a fresh run.
COMPONENTS & BOM
| REF | COMPONENT | SPEC | ROLE |
|---|---|---|---|
| U1 | ESP32 DevKit-C | ESP32-WROOM-32 dev board | controller — sampling, integration, OLED, logging |
| U2 | INA219 breakout | Adafruit INA219, 0.1Ω onboard shunt, I2C addr 0x40 | high-side V/I/P current-sense ADC |
| U3 | SSD1306 OLED | 128×64, I2C addr 0x3C | live / integrated / min-max readout |
| SW1 | Pushbutton | 6 mm tactile, momentary, normally open | short = cycle page, hold 1.5 s = reset integrator |
| — | Hookup wire | 22-26 AWG, stranded | I2C bus + logic-side wiring |
| — | Test leads | insulated, alligator-clip or banana-to-pin | DUT power path (VIN+/VIN-, GND return) |
WIRING
The maroon path is the one actually being measured: bench supply positive goes into the
INA219’s VIN+, through its fixed 0.1Ω onboard shunt, out VIN-, and on to the DUT. The
DUT’s ground returns straight to the bench supply’s ground (ink, top of the drawing) —
it never routes through the INA219, which is what lets the chip report current without
disturbing the DUT’s own ground reference. SDA/SCL (blue) are a single shared I2C bus across
the INA219, ESP32, and OLED.
| ESP32 PIN | NET | PERIPHERAL PIN |
|---|---|---|
| GPIO21 | I2C SDA | INA219 SDA · SSD1306 SDA |
| GPIO22 | I2C SCL | INA219 SCL · SSD1306 SCL |
| GPIO27 | BUTTON, active low | PUSHBUTTON signal leg (other leg → GND) |
| 3V3 | LOGIC SUPPLY | INA219 VCC · SSD1306 VCC |
| GND | LOGIC GND | INA219 GND · SSD1306 GND · PUSHBUTTON GND leg |
| n/a — not an ESP32 pin | MEASURED PATH | BENCH SUPPLY(+) → INA219 VIN+ · INA219 VIN- → DUT(+) |
| n/a — not an ESP32 pin | GND RETURN | BENCH SUPPLY(-) → DUT(-) direct, bypasses INA219 |
FIRMWARE & MEASUREMENT MATH
The INA219 is read through the Adafruit_INA219 library (not raw register access), using
its setCalibration_32V_1A() profile: ±1.3 A headroom to survive a motor-driver DUT’s
inrush, with 40 µA/bit resolution — a real step up from the library’s default 2 A
profile (100 µA/bit) for characterizing small idle/sleep currents, though still coarse
next to a dedicated microamp meter for true deep-sleep verification.
Every 100 ms (10 Hz) the firmware reads bus voltage, current, and power, then integrates charge and energy with the trapezoidal rule instead of a rectangular sum — it averages the previous and current sample rather than holding the last value flat for the whole interval, which matters when current ramps between samples (e.g. a motor spin-up) instead of stepping:
double dtHours = dtMs / 1000.0 / 3600.0;
mAh_total += (prevCurrent_mA + current_mA) / 2.0 * dtHours;
mWh_total += (prevPower_mW + power_mW) / 2.0 * dtHours;
Every sample is also written to Serial as a CSV line for offline plotting:
// millis_ms,bus_V,current_mA,power_mW,mAh,mWh
Serial.print(now); Serial.print(',');
Serial.print(busVoltage_V, 3); Serial.print(',');
Serial.print(current_mA, 3); Serial.print(',');
Serial.print(power_mW, 3); Serial.print(',');
Serial.print(mAh_total, 5); Serial.print(',');
Serial.println(mWh_total, 5);
The button is debounced against millis(): a short press cycles the OLED between LIVE,
INTEGRATED (mAh/mWh + elapsed time), and MIN-MAX pages; holding it 1.5 s zeroes the mAh/mWh
totals and the min/max tracking for a clean new run.
SIMULATION
Wokwi has no INA219 part, so diagram.json is an honest partial simulation: it wires the real
ESP32 + SSD1306 + pushbutton exactly as the real build (I2C on GPIO21/22, button on GPIO27),
plus two potentiometers on GPIO34/GPIO35 labeled as V stand-in / I stand-in for the missing
sensor. The shipped sketch.ino talks to a real INA219 over I2C and will fail ina219.begin()
in the simulator, since no such device exists on the bus. Swapping the ina219.* calls for
analogRead(34)/analogRead(35) in serviceSample() — a few lines — lets the sim exercise
everything except the sensor itself: OLED page cycling, the trapezoidal mAh/mWh math, the CSV
log format, and the button’s short/long-press behavior. See README.md in the source folder
for the exact steps.
STATUS
Design and simulation complete; not bench-verified. The firmware compiles against the
Adafruit_INA219 API and the calibration/resolution figures above (±1.3 A range, 40
µA/bit) are datasheet-typical for the library’s 32V_1A profile, not numbers measured on
this build. No physical INA219 has been wired to a real DUT yet, so no real V/I/mAh trace
exists. Planned next: bench-wire it in series with the desk-buddy project’s supply rail, log a
full sleep/wake cycle, and compare the logged mAh against that project’s assumed sleep-current
budget.
USE CASES & APPLICATIONS
Battery-life validation for any of the low-power builds on this bench — logging mAh over a full duty cycle beats trusting a datasheet’s typical-current figure. Charger/supply profiling: watch voltage sag and current draw through a charge cycle. Rough solar-node sizing: log a day’s consumption profile to estimate panel/battery sizing before committing to hardware. Lab teaching: the trapezoidal-integration and high-side-sensing concepts here are the same ones behind bench multimeters’ mAh functions and commercial USB power meters.
FILES
sketch.ino— firmware: Adafruit_INA219 driver, 10 Hz sample/integrate/log loop, trapezoidal mAh/mWh integration, three-page OLED UI, debounced short/long-press button.diagram.json— Wokwi diagram: ESP32 + SSD1306 + pushbutton wired as the real build, plus two potentiometers standing in for the (unsimulated) INA219 — see SIMULATION above.README.md— Wokwi sim steps and real-build notes: shunt placement, wire gauge, and the current-range-vs-resolution tradeoff across the INA219’s calibration profiles.