Projects / Power
USB-C PD Bench Supply with Power Meter
Turn a laptop charger into a 9/12/20 V bench supply with a phone-controlled switch and current trip.
Overview
Any USB-C Power Delivery charger can supply 9, 12 or 20 V — the ET-P14 trigger board asks for the voltage you choose. The ET-P15 INA226 measures voltage, current and power on the output, and a channel of the ET-MD08 MOSFET driver switches the load on and off.
The ET-P12 buck converter powers the ET-M02 from the same charger, so the whole bench supply runs from one USB-C cable. A web page on your phone shows live readings, totals the energy used, and trips the output if the current goes above your limit — handy for testing motors, LED strips and new boards.
- 9, 12 or 20 V from any USB-C PD charger
- Live volts, amps, watts and Wh on your phone
- Output on/off switch
- Adjustable over-current trip
What you need
ElectroTrical boards
You'll also need
- USB-C PD charger (45–65 W laptop charger recommended)
- USB-C cable rated for the current (5 A e-marked for over 3 A)
- Banana sockets or a screw terminal for the output
- Hook-up wire rated for 3 A
- 1 Qwiic cable
Wiring
Set the ET-P14 voltage jumper before connecting: 12 V is the default. The ET-MD08 is rated 24 V and 3 A per channel, so keep loads within that. Program the ET-M02 over USB first, then disconnect USB and run it from the ET-P12.
Power path
| From | To | Note |
|---|---|---|
| ET-P14 VBUS | ET-P15 J4 supply + | |
| ET-P15 J4 load + | ET-MD08 J4 V+ | |
| ET-P14 GND | ET-MD08 J4 − | |
| Your load + / − | ET-MD08 channel 1 terminal V+ / OUT1 | Switched on the low side |
| ET-P14 VBUS | ET-P12 VIN | |
| ET-P14 GND | ET-P12 GND | |
| ET-P12 VOUT | ET-M02 VBUS | Don't connect the ET-M02's USB at the same time |
| ET-P12 GND | ET-M02 GND |
Control
| From | To | Note |
|---|---|---|
| ET-M02 Qwiic | ET-P15 Qwiic | INA226 at 0x40 |
| ET-M02 IO4 | ET-MD08 IN1 | |
| ET-M02 GND | ET-MD08 GND (J3) |
Build it
- 01
Choose the voltage
Set the ET-P14 jumper to 9, 12 or 20 V. The charger must support that voltage — most laptop chargers offer all three.
- 02
Program the controller
Install the Espressif ESP32 package, select “ESP32S3 Dev Module”, enable USB CDC On Boot, and upload the sketch over USB.
- 03
Wire the power path
Unplug USB from the ET-M02. Wire the power path with wire rated for your load current. Double-check polarity before plugging in the charger.
- 04
Connect your phone
Join the Wi-Fi network “ET-Bench” (password electrotrical) and open http://192.168.4.1. The output starts off.
- 05
Set the trip current
Enter a current limit on the page. If the load draws more, the output switches off within about 100 ms and the page shows “TRIPPED”.
- 06
Test with a known load
Try a 12 V LED strip or a power resistor and compare the reading with a multimeter.
Arduino code
Written for the ET-M02 ESP32-S3 Dev Board. No extra libraries are needed.
#include <Wire.h>
#include <WiFi.h>
#include <WebServer.h>
const int OUT_PIN = 4; // ET-MD08 IN1
const uint8_t INA = 0x40;
const float SHUNT = 0.015; // ET-P15 shunt
const float CURRENT_LSB = 0.0002; // 0.2 mA per bit (±5.4 A range)
WebServer server(80);
bool outputOn = false, tripped = false;
float limitA = 2.0, volts, amps, watts, wh = 0;
void inaWrite(uint8_t reg, uint16_t v) {
Wire.beginTransmission(INA); Wire.write(reg); Wire.write(v >> 8); Wire.write(v & 0xFF); Wire.endTransmission();
}
int16_t inaRead(uint8_t reg) {
Wire.beginTransmission(INA); Wire.write(reg); Wire.endTransmission(false);
Wire.requestFrom(INA, (uint8_t)2);
return (int16_t)((Wire.read() << 8) | Wire.read());
}
void setOutput(bool on) { outputOn = on; digitalWrite(OUT_PIN, on); }
void handleRoot() {
if (server.hasArg("on")) { tripped = false; setOutput(true); }
if (server.hasArg("off")) setOutput(false);
if (server.hasArg("limit")) limitA = server.arg("limit").toFloat();
if (server.hasArg("reset")) wh = 0;
String s = "<!doctype html><meta name=viewport content='width=device-width'><meta http-equiv=refresh content=2>"
"<body style='font:18px sans-serif;max-width:420px;margin:24px auto'><h2>USB-C bench supply</h2>";
s += "<p style='font-size:30px;margin:0'>" + String(volts, 2) + " V · " + String(amps, 3) + " A</p>";
s += "<p>" + String(watts, 2) + " W · " + String(wh, 3) + " Wh</p>";
s += String("<p><b>") + (tripped ? "TRIPPED" : outputOn ? "Output ON" : "Output off") + "</b></p>";
s += "<p><a href='/?on=1'>Turn on</a> <a href='/?off=1'>Turn off</a> <a href='/?reset=1'>Reset Wh</a></p>";
s += "<form>Trip at <input name=limit size=4 value='" + String(limitA, 2) + "'> A <button>Set</button></form>";
server.send(200, "text/html", s);
}
void setup() {
pinMode(OUT_PIN, OUTPUT);
setOutput(false);
Serial.begin(115200);
Wire.begin(8, 9);
inaWrite(0x00, 0x4527); // 16 averages, 1.1 ms conversions, continuous
inaWrite(0x05, (uint16_t)(0.00512 / (CURRENT_LSB * SHUNT))); // calibration
WiFi.softAP("ET-Bench", "electrotrical");
server.on("/", handleRoot);
server.begin();
}
void loop() {
static unsigned long last = 0;
if (millis() - last >= 50) {
float dt = (millis() - last) / 3600000.0;
last = millis();
volts = (uint16_t)inaRead(0x02) * 0.00125; // bus voltage, 1.25 mV/bit
amps = inaRead(0x04) * CURRENT_LSB;
watts = (uint16_t)inaRead(0x03) * 25 * CURRENT_LSB;
if (outputOn) wh += watts * dt;
if (outputOn && amps > limitA) { setOutput(false); tripped = true; }
}
server.handleClient();
}
Troubleshooting
Output is 5 V instead of 12 V
The charger didn't agree to PD. Use a PD-capable charger and cable, and check the jumper is set to a voltage the charger lists on its label.
Trips immediately on capacitive loads
Large capacitors draw a short surge. Raise the limit a little, or add a 50–100 ms delay before the trip check.
Voltage reading is low under load
The INA226 reads at the load side of the shunt; thin wires drop voltage. Use short, thick wires to the output terminals.
Take it further
- Add an ET-D10 LCD for a stand-alone display
- Use the other three ET-MD08 channels for more switched outputs
- Log V/A/W to the ET-A14 FRAM for long tests
Turning this into a product?
We design custom boards that combine these sensors on one PCB, with firmware and production.