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.

Intermediate⏱ 2 hours5 ElectroTrical boards

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

ET-P14USB-C PD Trigger 9/12/20 VGets 9, 12 or 20 V from the charger
Coming soon
ET-P15INA226 Power Monitor 36 VMeasures output voltage, current and power
Coming soon
ET-MD084-Channel MOSFET DriverSwitches the output (one channel used)
Coming soon
ET-P12MP1584 Buck Converter 5 V 3 APowers the controller from the PD voltage
Coming soon
ET-M02ESP32-S3 Dev BoardController and web page
Coming soon

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

FromToNote
ET-P14 VBUSET-P15 J4 supply +
ET-P15 J4 load +ET-MD08 J4 V+
ET-P14 GNDET-MD08 J4 −
Your load + / −ET-MD08 channel 1 terminal V+ / OUT1Switched on the low side
ET-P14 VBUSET-P12 VIN
ET-P14 GNDET-P12 GND
ET-P12 VOUTET-M02 VBUSDon't connect the ET-M02's USB at the same time
ET-P12 GNDET-M02 GND

Control

FromToNote
ET-M02 QwiicET-P15 QwiicINA226 at 0x40
ET-M02 IO4ET-MD08 IN1
ET-M02 GNDET-MD08 GND (J3)

Build it

  1. 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.

  2. 02

    Program the controller

    Install the Espressif ESP32 package, select “ESP32S3 Dev Module”, enable USB CDC On Boot, and upload the sketch over USB.

  3. 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.

  4. 04

    Connect your phone

    Join the Wi-Fi network “ET-Bench” (password electrotrical) and open http://192.168.4.1. The output starts off.

  5. 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”.

  6. 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.

pd_bench_supply.ino
#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 &middot; " + String(amps, 3) + " A</p>";
  s += "<p>" + String(watts, 2) + " W &middot; " + 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> &nbsp; <a href='/?off=1'>Turn off</a> &nbsp; <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.