USB-C chargers are everywhere now. Most of us already have a 30W, 65W, or even 100W PD charger sitting in a drawer somewhere. We usually think of them as simple phone or laptop chargers, but they are actually very capable power sources that can deliver different voltages on demand.
That is what inspired me to build PowerPD.
PowerPD is a compact USB-C PD/PPS power supply and PD analyzer built around an ESP32 microcontroller, an AP33772S USB-C PD sink controller, and an INA226 power monitor. The idea is simple: connect a USB-C PD charger, select the voltage using the rotary encoder, and the board automatically negotiates that voltage from the charger. At the same time, it measures voltage, current, and power in real time and displays everything on a small OLED screen.
PowerPD supports standard USB-C PD voltages such as 5V, 9V, 12V, 15V, and 20V. If the charger supports PPS (Programmable Power Supply), the output voltage can also be adjusted in small steps, making it useful for electronics testing, powering prototypes, debugging circuits, and other lightweight bench power applications.
SuppliesMain Components
- ESP32-WROOM-32E module
- AP33772S USB-C PD sink controller
- INA226 voltage/current/power monitor
- MP1584 buck converter
- AP2204K-3.3V regulator
- USB Type-C connector
- 5 mΩ current sense resistor
- MOSFET power switch
- 1.3-inch OLED display
- Rotary encoder
- Push buttons
- Status LEDs
- Passive components such as resistors, capacitors, inductor, and protection diodes
The schematic includes the AP33772S PD controller, INA226 monitor, MP1584 buck converter, 3.3V regulator, MOSFET output stage, ESP32, OLED display interface, rotary encoder, switches, and programming header.
Tools Needed
- USB-C PD charger (supports at least 9V PD)
- 3.3V USB-to-UART converter (CP2102, CH340, or FT232RL)
- Two small push buttons for BOOT and EN
- Jumper wires
- Multimeter
Before getting into the hardware, it helps to understand how PowerPD works.
When a USB-C PD charger is connected, it starts at the default 5V output. The AP33772S PD controller then reads the voltage profiles supported by the charger through the USB-C CC lines. The ESP32 selects the required voltage or PPS setting and tells the AP33772S to request it from the charger.
Once the charger switches to the selected voltage, the power flows through a 5 mΩ shunt resistor and MOSFET output switch before reaching the output terminal. The INA226 monitors voltage, current, and power in real time and sends the data to the ESP32 over I²C.
The ESP32 updates the OLED display, handles the rotary encoder and buttons, controls the output switch, and can also send live data to Adafruit IO over Wi-Fi.
The onboard buck converter and 3.3V regulator power the ESP32 and all logic circuits directly from the same USB-C PD input voltage.
Step 2: Circuit OverviewThe USB-C connector brings in power and communication lines. The AP33772S talks to the charger and requests the selected PD or PPS voltage like 5V, 9V, 12V, 15V, or 20V.
A 5 mΩ shunt resistor and INA226 monitor output voltage, current, and power in real time. The measured data is sent to the ESP32 over I²C.
Output SwitchingA MOSFET is used as an electronic output switch. The ESP32 can safely turn the output ON or OFF and disconnect the load during fault conditions.
Internal Power SupplyThe MP1584 buck converter reduces the USB-C input voltage, and the AP2204K regulator generates a clean 3.3V supply for the ESP32 and other logic circuits.
ESP32 ControllerThe ESP32 controls the entire system. It handles PD negotiation, reads sensor data, updates the OLED display, manages the rotary encoder and buttons, and optionally sends data to Adafruit IO over Wi-Fi.
User InterfaceThe board includes a 1.3-inch SH1106 OLED display, a rotary encoder, and push buttons for menu navigation, voltage selection, and output control.
Step 3: USB-C PD, PPS, and AVS BasicsUSB-C PD chargers can deliver several fixed voltage levels depending on what they support. The standard profiles in the SPR (Standard Power Range) are:
- 5V (default for all USB-C connections)
- 9V
- 12V
- 15V
- 20V
These fixed levels cover most use cases, but electronics work often needs something in between — 8.4V for a two-cell LiPo, 13.2V for a custom LED driver, or 10V for a specific regulator test. That is where PPS comes in.
PPS — Programmable Power Supply PPS lets the charger adjust its output voltage continuously in 100 mV steps, rather than jumping between fixed profiles. The current limit can also be set in 50 mA steps. This turns a capable USB-C charger into something close to a small bench supply for light work. PPS is part of the USB PD 3.0 specification, and many modern chargers support it — though not all, so always check your charger's spec sheet or label.
EPR — Extended Power Range Newer chargers can also support EPR, which adds higher fixed voltages: 28V, 36V, and 48V. These are aimed at high-power devices like monitors, workstations, and gaming laptops. PowerPD does not support EPR in the current firmware, so do not attempt to request these voltages.
AVS — Adjustable Voltage Supply AVS is a newer addition to USB PD and provides fine voltage control at higher power levels. It is similar to PPS but designed for higher-voltage, higher-power applications. PowerPD does not currently use AVS
Always check what your charger actually supports before requesting a voltage. The AP33772S will only negotiate what the charger advertises — it will not force a voltage the charger does not offer. But it is still good practice to start at 5V and step up, especially when testing new loads.
Step 4: PCB Design and AssemblyMy friend Rabindra designed the PowerPD PCB in EasyEDA.
The AP33772S USB-C PD controller is placed close to the USB Type-C connector to keep the CC traces short and clean. The INA226 is positioned right next to the 5 mΩ shunt resistor so it can use proper Kelvin sensing for accurate current measurement.
Since most of the important parts are fine-pitch SMD components, hand soldering was not a practical option. The AP33772S comes in a QFN package, the INA226 is a small SOT-23 device, and the USB-C connector has very tight pads. Because of that, I decided to go with professional PCBA from the beginning, and I used NextPCB for fabrication and assembly.
The ordering process with NextPCB was simple. I uploaded the Gerber files, BOM, and pick-and-place file through their online system.
NextPCB handled both component sourcing and PCB assembly, including the ESP32 module, AP33772S, INA226, USB-C connector, MP1584 power section, AP2204K-3.3V regulator, MOSFET output switch, and all the small passive components.
Before shipping, they also sent a photo of the assembled boards so I could visually check the component placement. This was useful because I could confirm that the parts were assembled correctly before the boards even left the factory.
When the boards arrived, there was almost nothing left to do. I connected a USB-to-UART converter to the programming header, flashed the firmware, and the board was ready for testing. There was no rework needed, no missing parts, and no cold solder joints.
If you want to build your own PowerPD, the Gerber files, BOM, and schematic are available in the GitHub repository. You can upload them directly to NextPCB and get the boards manufactured and assembled in the same way.
Step 5: Firmware OverviewFor the AP33772S USB-C PD sink controller, I used my own custom-made Arduino library. You can find this library in my GitHub repository. https://github.com/Rau7han/PowerPD
To use the code, download these files from the repository:
- AP33772S.h
- AP33772S.cpp
- PowerPD.ino
Keep all three files inside the same Arduino sketch folder. This is important because the main PowerPD.ino file includes the AP33772S library using:
#include "AP33772S.h"If the.h and.cpp files are not in the same folder, the Arduino IDE will not compile the project correctly.
Before uploading, install the required Arduino libraries:
- U8g2
- INA226
- PubSubClient
The firmware controls the complete PowerPD system. It communicates with the AP33772S for USB-C PD/PPS negotiation, reads voltage and current data from the INA226, updates the SH1106 OLED display, handles the rotary encoder and push buttons, controls the MOSFET output switch, and also includes optional Wi-Fi/MQTT monitoring support.
The main pin configuration used in the code is:
- I2C SDA GPIO21
- I2C SCL GPIO22
- PD_INT GPIO32
- MOSFET CG GPIO25
- Rotary CLK GPIO5
- Rotary DT GPIO18
- Rotary SW GPIO19
- SW1 GPIO17
- SW2 GPIO16
- LED GPIO4
Before using the board, it is good to know the basic control method:
- Rotate encoder Change selected value
- Short press encoder Move to next field
- Long press encoder Apply setting / open menu / toggle output
- SW1 short press Toggle between voltage and current setting
- SW1 long press Open menu
- SW2 short press Turn output ON/OFF
- SW2 long press Open session screen
On startup, the ESP32 initializes the display, checks the AP33772S and INA226 over I2C, reads the available PD profiles from the charger, and then shows the main screen. From there, the user can select fixed PD voltages or PPS settings and enable the output when ready.
I have also pasted the full source code below so it can be checked or copied directly. The code includes the PD negotiation, measurement, display UI, safety checks, output switching, and menu system
Step 6: Adafruit IO SetupPowerPD can also send live data to Adafruit IO, so I can monitor the board from a web dashboard. For this project, I kept the dashboard simple and only used the values that really matter:
- voltage
- current
- power
- temperature
- output
This is enough to see the real-time condition of the power supply without filling the dashboard with unnecessary data.
1. Open Adafruit IOFirst, go to Adafruit IO and log in to your account.
https://io.adafruit.com/After login, you will see the Adafruit IO overview page. Since I am using the Basic plan, I can create up to 10 feeds, which is enough for this project.
2. Create the FeedsGo to:
Feeds → New Feed
Create these five feeds one by one:
- voltage
- current
- power
- temperature
- output
I used short feed names because these same names are used in the ESP32 code.
For the descriptions, I used simple text like this:
- voltage Live output voltage measured by PowerPD
- current Live load current measured by PowerPD
- power Real-time output power
- temperature Board / PD controller temperature
- output Output state, 0 = OFF and 1 = ON
After creating the feeds, go to:
- Dashboards → New Dashboard
I created a dashboard for PowerPD monitoring. This dashboard will show live voltage, current, power, temperature, and output state.
Dashboard name example:
- PowerPD Monitor
For voltage, current, and power, I used Gauge blocks.
Click:
- New Block → Gauge
- Then select the feed and set the gauge values.
For Voltage:
- Feed: voltage
- Block Title: Voltage
- Min: 0
- Max: 25
- Label: V
- Decimal Places: 2
For Current:
Feed: current
- Block Title: Current
- Min: 0
- Max: 6
- Label: A
- Decimal Places: 3
For Power:
- Feed: power
- Block Title: Power
- Min: 0
- Max: 120
- Label: W
- Decimal Places: 2
- For temperature, I used a chart block because it is better to see temperature change over time.
Use these settings:
- Feed: temperature
- Block Title: Temperature
- Show History: 24 hours
- X-Axis Label: Time
- Y-Axis Label: Temperature °C
- Y-Axis Minimum: 0
- Y-Axis Maximum: 100
- Decimal Places: 1
- Draw Grid Lines: ON
This lets me see if the board temperature is slowly rising during a load test.
6. Add Output ToggleFor the output control, I added a Toggle block connected to the output feed.
Use these settings:
- Feed: output
- Block Title: Output
- Button On Text: ON
- Button On Value: 1
- Button Off Text: OFF
- Button Off Value: 0
This means:
- 1 = Output ON
- 0 = Output OFF
In the updated firmware, the ESP32 subscribes to this feed. So when I change the toggle from the dashboard, the ESP32 receives the value and turns the MOSFET output ON or OFF.
The firmware still checks safety conditions before enabling the output. If there is a fault, no charger, or the board is still detecting PD, the output stays OFF.
Add Adafruit IO Details in the CodeAfter setting up the feeds and dashboard, copy your Adafruit IO username and key.
Go to:
View Adafruit IO KeyThen update this part in the ESP32 code:
#define WIFI_SSID "your_ssid"
#define WIFI_PASSWORD "your_password"
#define AIO_SERVER "io.adafruit.com"
#define AIO_PORT 1883
#define AIO_USERNAME "your_aio_username"
#define AIO_KEY "your_aio_key"Replace it with your own Wi-Fi and Adafruit IO details.
Step 7: Uploading FirmwareFolder setup
Create a folder named PowerPD and place all three files inside it:
PowerPD/
- PowerPD.ino
- AP33772S.h
- AP33772S.cpp
Open PowerPD.ino in Arduino IDE. Before compiling, update your Wi-Fi and Adafruit IO credentials near the top of the file:
#define WIFI_SSID "Your_WiFi_Name"
#define WIFI_PASSWORD "Your_WiFi_Password"
#define AIO_SERVER "io.adafruit.com"
#define AIO_PORT 1883
#define AIO_USERNAME "Your_Adafruit_IO_Username"
#define AIO_KEY "Your_Adafruit_IO_Key"If you are not using Adafruit IO, you can leave these as dummy text. The local display and controls will still work normally.
Wiring the USB-to-UART converter
⚠️ Use a 3.3V logic level USB-to-UART converter. A 5V adapter will damage the ESP32.
USB-to-UARTPowerPD programming header
- TX RX
- RX TX
- GND GND
- 3V3 3V3
Entering download mode
The PCB does not have onboard BOOT and EN buttons. Use two small momentary push buttons connected with jumper wires:
- One button: BOOT pin → GND
- One button: EN pin → GND
Entering download mode
The PCB does not have onboard BOOT and EN buttons. Use two small momentary push buttons connected with jumper wires:
- One button: BOOT pin → GND
- One button: EN pin → GND
To enter download mode:
- Press and hold the BOOT button
- Press and release the EN button
- Release the BOOT button
- Click Upload in Arduino IDE immediately
After upload
Once the upload completes, press the EN button once to restart the ESP32. The OLED should show the PowerPD startup screen within 2–3 seconds.
Open the Serial Monitor at 115200 baud to see startup messages — this is the fastest way to confirm whether the AP33772S and INA226 were detected correctly.
Step 8: USB-C PD Chargers and CablesThe charger and cable you use with PowerPD matter more than you might expect.
Any USB-C PD charger starts at 5V by default. The AP33772S chip negotiates higher voltages by communicating with the charger over the CC lines — but it can only request what the charger actually advertises.
Before using any charger, check the label on the back. It should list the supported voltage and current profiles, something like: 5V/3A, 9V/3A, 12V/3A, 15V/3A, 20V/3A. A charger claiming 65W but only showing 5V/3A on the label will not give you 20V no matter what you request.
If you want to test PPS, specifically look for "PPS" printed on the charger or in its specifications. Not all high-wattage chargers support it.
The cable matters too. A poor quality USB-C cable can cause voltage drop, connection instability, or failed PD negotiation — making the board look faulty even when it is working correctly. For most testing, any USB-C to USB-C cable rated for 3A and PD is fine. For higher power loads near 20V and 5A, use an e-marked 5A cable.
Avoid USB-A to USB-C adapters, magnetic connectors, and unknown extension cables. Keep it simple:
USB-C PD Charger → USB-C to USB-C cable → PowerPD
Before connecting any load, always verify the output voltage with a multimeter first. This takes 30 seconds and rules out a lot of potential confusion.
Step 9: First Power-UpConnect a USB-C PD charger using a quality cable. Do not connect anything to the V_OUT terminals yet.
When the charger is connected:
- The status LED should light up — this confirms VBUS is present
- The OLED should display the PowerPD startup screen within a few seconds
- The board reads the available PD profiles from the charger
- The output stays OFF
If the OLED stays blank, check your firmware upload. If the LED does not light up, check the USB-C cable and charger.
Once the startup screen appears, open the Serial Monitor at 115200 baud and confirm that the AP33772S and INA226 are both detected. Then check that at least 5V appears as a selectable profile on the OLED.
At this point the board is running on 5V (default). The output is OFF. Nothing is connected to V_OUT. This is exactly the right state to be in before moving to voltage testing.
Step 10: CAD DesignMy Friend Mukesh designed the complete PowerPD enclosure in Autodesk Fusion with a focus on compact size, clean appearance, and easy assembly around the custom PCB.
The entire design consists of 4 main parts:
1. Front_Panel:This is the top cover/front section of the enclosure.
- Includes cutouts for the OLED display
- Holds the rotary encoder shaft and push buttons
- Provides openings for the USB-C connector and output terminals
- Also acts as the main top lid for the complete enclosure
The bottom housing securely holds the fabricated PowerPD PCB.
- Designed around the exact PCB dimensions
- Includes PCB mounting supports and screw points
- Provides access for the USB-C port and programming header
- Keeps the internal electronics protected and aligned properly
A custom-designed rotary encoder knob made specifically for PowerPD.
- Easy to grip while adjusting voltage and navigating menus
- Compact design matching the enclosure style
- Push-fit mounting onto the rotary encoder shaft
The enclosure is designed so the assembled PCB can be mounted directly inside without extra brackets or wiring complexity.
- OLED header already aligns with the front panel window
- Rotary encoder position matches the knob opening
- Compact internal arrangement keeps the build clean and simple
I have attached:
- The original Fusion 360 design files
- STL files for all printable parts
You can:
- View and modify the CAD model in Fusion 360
- Adjust the enclosure dimensions if needed
- Directly slice and 3D print the provided STL files for your own build
With the board powered on and the output disabled, I used the rotary encoder to cycle through the available USB-C PD voltage profiles. The OLED display showed the supported profiles from the charger, including 5V, 9V, 15V, and 20V.
After selecting a voltage, I enabled the output and verified the actual V_OUT using a Fluke multimeter. The measured voltage matched the OLED reading very closely:
- 5V profile measured around 4.98V
- 16V PPS setting measured around 15.96V
- 20V profile measured around 20.07V
This confirmed that the AP33772S was correctly negotiating the selected PD profile and that the INA226 voltage monitoring was properly calibrated.
I also tested PPS mode by selecting adjustable voltage levels through the rotary encoder. The output voltage changed correctly and the multimeter readings matched the requested values shown on the OLED display.
Step 12: Load TestingAfter confirming the voltage profiles were working correctly, I connected a few real loads to the PowerPD output for testing. Instead of using an electronic load, I tested the board with a 12V cooling fan and a high-power BLDC motor running from the selected USB-C PD voltage.
With the output enabled, the OLED display showed live voltage, current, and calculated power in real time. The Adafruit IO dashboard also updated wirelessly over Wi-Fi, showing the same live voltage, current, power, and temperature data remotely.
PD analyzer mode to monitor the charger negotiation process. The OLED can display the detected PD profiles, active voltage, PPS status, and real-time output information directly from the connected USB-C charger. I have attached a GIF below showing the live PD negotiation and analyzer interface in action.
After confirming the voltage profiles were working correctly, I connected a few real loads to the PowerPD output for testing. Instead of using an electronic load, I tested the board with a 12V cooling fan and a high-power BLDC motor running from the selected USB-C PD voltage.With the output enabled, the OLED display showed live voltage, current, and calculated power in real time. The Adafruit IO dashboard also updated wirelessly over Wi-Fi, showing the same live voltage, current, power, and temperature data remotely.I also added a built-in PD analyzer mode to monitor the charger negotiation process. The OLED can display the detected PD profiles, active voltage, PPS status, and real-time output information directly from the connected USB-C charger. I have attached a GIF below showing the live PD negotiation and analyzer interface in action.




_ztBMuBhMHo.jpg?auto=compress%2Cformat&w=48&h=48&fit=fill&bg=ffffff)





_t9PF3orMPd.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)




Comments