The idea
A compact inline monitor that measures the voltage, current, and wattage flowing through a USB-C cable every 500 ms and streams the readings to a small web dashboard hosted on the device itself. Built around an ESP32-S3 and an INA228 current-sense IC, it sits between a charger and a device without interrupting USB-PD negotiation. Plug in, open a browser to the device's IP, and watch the charging curve build in real time.
No cloud account, no companion app. The dashboard is a local webpage served directly from the microcontroller's flash.
Why build this
USB-C and USB Power Delivery made charging capable but opaque. A cable that works for data may not carry 65 W. A charger labeled 100 W may deliver 45 W under real conditions. A device that advertises fast charging may only activate it under specific voltage and temperature windows. None of this is visible without instrumentation.
Commercial USB power meters exist — the FNB58, the ChargerLAB Power-Z — but they are display-only. You see the current wattage on a small screen, with no history and no way to export the session. Understanding whether a charger sustains its rated power across a 45-minute charge cycle, or comparing two chargers head to head, requires a data logger, not a meter.
An ESP32-based logger costs around $15 in parts and generates a timeseries you can analyze, export, and keep.
Stack sketch
- Microcontroller: ESP32-S3 DevKit — enough RAM for a small async HTTP server, a 5,000-sample ring buffer, and a JSON endpoint; built-in USB FS for firmware flashing without a separate programmer
- Power sense IC: INA228 over I2C — 85 V bus voltage range, 10 A current range, 16-bit resolution; breakout boards available from Adafruit and SparkFun; firmware computes current and power from the shunt measurement
- Shunt: 10 mΩ resistor inline on the VBUS line of a USB-C passthrough breakout; D+, D−, CC1, and CC2 lines connected straight through so PD negotiation is unaffected
- Firmware: Arduino framework with
ESPAsyncWebServer,AsyncTCP, and a community INA228 library; Wi-Fi credentials stored in NVS after a one-time provisioning AP flow - Dashboard: single HTML page with an embedded Chart.js line chart; page served from PROGMEM; updates via a polling
GET /data.jsonevery second — no build step, no framework - Export:
GET /export.csvserializes the ring buffer; open in a spreadsheet for post-session analysis
Scope for v1
- Continuous measurement of VBUS voltage (4–20 V), current (0–5 A), and computed wattage at 500 ms intervals
- 5,000-sample in-memory ring buffer covering roughly 40 minutes of readings
- Local web dashboard showing a live-updating line chart plus a sidebar with current wattage, session peak, running average, and cumulative energy in Wh
GET /export.csvendpoint for downloading the full session buffer as a flat file- First-boot provisioning AP: device broadcasts an SSID, you connect and POST the target SSID and password via a small HTML form; credentials persist to NVS and the device reconnects automatically on subsequent boots
- Deliberately out of scope for v1: USB-PD protocol sniffing, battery-backed RTC for wall-clock timestamps, SD card or MQTT logging, a physical display, multi-session storage
Where it could go
The natural hardware extension is USB-PD protocol sniffing via a FUSB302 or HUSB238 IC on the CC lines. These decode the negotiation exchange — which voltage/current profiles the charger offered, which one the device selected, and when renegotiations occurred. Combined with the existing wattage curve, you get the complete charging story: not just "65 W arrived" but "the device negotiated PD 3.0 PPS at 10 V / 5 A, held it for 28 minutes, then dropped back to 9 V as the battery approached full." That level of detail distinguishes a properly implemented charger from one that only hits its rated wattage under ideal conditions.
On the software side, a webhook alert is low-effort and high-value. A configurable wattage threshold that fires an HTTP POST to ntfy.sh, n8n, or Home Assistant lets you build simple automations: notify when a laptop finishes its fast-charge phase, alert if a device draws unexpectedly high current, or toggle a smart switch when trickle charge begins. The HTTP client is already in the firmware; the alert is a dozen additional lines.
Watch out for
Placing any electronics inline on a USB-C cable carrying significant current is a real safety consideration. Verify the PCB trace width on the VBUS path is rated for your target current, confirm the shunt resistor's power dissipation (a 10 mΩ shunt at 5 A dissipates 250 mW — stay within the component's rated wattage with margin), and run a full charging session at your bench before trusting the device unattended. Thermal behavior at continuous high current is the primary failure mode to characterize before calling v1 done.