Back to Embedded Systems Hardware Engineering Series

Capstone 2: AI Smart Power Supply

April 17, 2026 Wasil Zafar 45 min read

Design a digitally-controlled bench power supply with USB-PD negotiation, precision current sensing, and intelligent load management.

Table of Contents

  1. Specifications
  2. Power Architecture
  3. Digital Control Loop
  4. Protection Circuits
  5. Spec Sheet Tool
  6. Conclusion

Specifications

ParameterSpecificationImplementation
Output voltage0–30V, 10mV resolutionDAC → op-amp → buck converter
Output current0–5A, 1mA resolutionINA219 high-side sensing
Input36V / 6A (USB-PD or barrel jack)FUSB302 PD controller
Display2.8" TFT (320×240)ILI9341 via SPI
InterfaceRotary encoder + USB serialSCPI command protocol
ProtectionOVP, OCP, OTP, reverse polarityHardware + firmware
Efficiency>85% at full loadSynchronous buck topology

Power Architecture

Smart Power Supply Block Diagram
flowchart LR
    A["USB-PD Input
20V/3A"] --> B["FUSB302
PD Negotiation"] B --> C["Input Protection
TVS + Fuse"] C --> D["Sync Buck
LM5166"] D --> E["Output Stage
LC Filter"] E --> F["Output
Terminals"] G["STM32G4
MCU"] -->|DAC| D G -->|I2C| H["INA219
V/I Sense"] H --> F G -->|SPI| I["ILI9341
Display"] G --> J["Encoder
+ Buttons"] style G fill:#3B9797,color:#fff style F fill:#BF092F,color:#fff
# Buck converter component selection calculator
# Synchronous buck: LM5166 or TPS54360

# Requirements
V_in_max = 36.0     # Max input voltage (V)
V_out = 12.0        # Target output voltage (V)
I_out = 5.0         # Max output current (A)
f_sw = 500e3        # Switching frequency (Hz)
V_ripple = 0.050    # Max output ripple (V, peak-to-peak)

# Duty cycle
D = V_out / V_in_max

# Inductor selection
delta_IL = 0.3 * I_out  # 30% ripple current
L_min = (V_out * (1 - D)) / (f_sw * delta_IL)

# Output capacitor
C_out_min = delta_IL / (8 * f_sw * V_ripple)

# Input capacitor (RMS current)
I_cin_rms = I_out * (D * (1 - D)) ** 0.5

print("Synchronous Buck Converter Design")
print("=" * 50)
print(f"Input:  {V_in_max}V max")
print(f"Output: {V_out}V @ {I_out}A")
print(f"Freq:   {f_sw/1e3:.0f} kHz")
print(f"\nDuty cycle:     {D:.2%}")
print(f"Inductor:       {L_min*1e6:.1f} µH min (use {round(L_min*1e6/2.2)*2.2:.1f} µH)")
print(f"Ripple current: {delta_IL:.2f} A ({delta_IL/I_out:.0%} of Iout)")
print(f"Output cap:     {C_out_min*1e6:.1f} µF min (use {max(22, round(C_out_min*1e6/10)*10)} µF)")
print(f"Input cap RMS:  {I_cin_rms:.2f} A (use X5R/X7R rated)")
print(f"\nPower: {V_out * I_out:.0f}W, Efficiency est: ~{90 if D > 0.3 else 85}%")
print(f"Loss:  ~{V_out * I_out * 0.1:.1f}W → heat sink required")

Digital Control Loop

/* PID voltage control loop — runs in ADC interrupt
   DAC output adjusts buck converter reference voltage */

#include <stdint.h>

typedef struct {
    float Kp;          /* Proportional gain */
    float Ki;          /* Integral gain */
    float Kd;          /* Derivative gain */
    float setpoint;    /* Target voltage (mV) */
    float integral;    /* Accumulated error */
    float prev_error;  /* Previous error for derivative */
    float output_min;  /* DAC minimum (0) */
    float output_max;  /* DAC maximum (4095 for 12-bit) */
} pid_controller_t;

/* Initialize PID with tuned gains */
pid_controller_t voltage_pid = {
    .Kp = 2.5f,
    .Ki = 0.8f,
    .Kd = 0.1f,
    .setpoint = 5000.0f,  /* 5.000V in mV */
    .integral = 0.0f,
    .prev_error = 0.0f,
    .output_min = 0.0f,
    .output_max = 4095.0f,
};

float pid_update(pid_controller_t *pid, float measurement) {
    float error = pid->setpoint - measurement;

    /* Anti-windup: only integrate if output not saturated */
    pid->integral += error;
    if (pid->integral > pid->output_max) pid->integral = pid->output_max;
    if (pid->integral < pid->output_min) pid->integral = pid->output_min;

    float derivative = error - pid->prev_error;
    pid->prev_error = error;

    float output = pid->Kp * error
                  + pid->Ki * pid->integral
                  + pid->Kd * derivative;

    /* Clamp output to DAC range */
    if (output > pid->output_max) output = pid->output_max;
    if (output < pid->output_min) output = pid->output_min;

    return output;
}

/* Called from ADC interrupt at 100 kHz sample rate */
/*
 * void ADC1_IRQHandler(void) {
 *     float v_sense = adc_read_mv(ADC_CH_VOUT);
 *     float dac_val = pid_update(&voltage_pid, v_sense);
 *     DAC1->DHR12R1 = (uint32_t)dac_val;
 * }
 */

Protection Circuits

Safety Critical: All protection circuits use hardware comparators with <1µs response time, independent of firmware. The MCU monitors but does not control the fast trip — a firmware hang must never disable protection.
ProtectionTriggerMethodResponse Time
Over-voltage (OVP)Vout > Vset + 0.5VComparator → MOSFET gate driver disable<500 ns
Over-current (OCP)Iout > IlimitINA219 alert → MCU → shutdown<100 µs
Over-temperature (OTP)TMOSFET > 100°CNTC → comparator → current foldback<1 ms
Reverse polarityVin < 0P-ch MOSFET body diode blockInstantaneous
Short circuitVout < 0.5V & I > limitHiccup mode (try every 500ms)<1 µs

Power Supply Spec Sheet Tool

Power Supply Specification Generator

Document your power supply design specifications. Download as Word, Excel, or PDF.

Draft auto-saved

Conclusion

The smart power supply capstone combines analog power electronics (buck converter), precision measurement (INA219), digital control (PID loop), and user interface design into a complete bench instrument. The USB-PD input makes it portable and compatible with modern laptop chargers.

Next Capstone

In Capstone 3: Edge AI Camera, we’ll design a camera module with on-device ML inference for object detection and classification.