Open ESC
Breadboarded inverter driven by a Raspberry Pi Pico
![]()
Overview
Open ESC is my attempt at building an electronic speed controller (ESC) for brushless motors from scratch. It's a three-phase inverter built out of discrete MOSFETs and transistors on a breadboard, controlled by a Raspberry Pi Pico running firmware I wrote in Rust.
I focused on:
- The gate drive for the high side MOSFETs
- Firmware to step through the six-step commutation sequence
- Complementary PWM with dead time, so the two MOSFETs in a phase are never on at the same time
Motivation
- Build an ESC to drive sensorless brushless dc motors.
- Learn embedded Rust.
Architecture
Each of the three motor phases is a half bridge, one MOSFET to the supply and one to ground. The Pico drives each half bridge from its own PWM slice, and the firmware decides whether each phase is pulled high, pulled low, or left floating.
The high side MOSFETs are N-channel, so their gates have to be driven above the supply voltage to turn on. My first version made that higher voltage with a separate 555 boost converter, based on a design from Greg. The current version uses a bootstrap drive instead, where a capacitor charges up while the phase is low and then lifts the gate above the supply when the phase switches high.
For testing I put LEDs between the phases in place of a motor, so I could see the commutation sequence without risking a motor.
Implementation
Bootstrap drive
I simulated the bootstrap circuit in Falstad before building it. On the bench the gate sits above the phase voltage while the high side is on and slowly sags as the capacitor discharges, which is why a bootstrap drive only works as long as the phase keeps switching.
Gate (orange) and phase A (blue) with the high side switched on by hand, Vcc = 8 V

Firmware
I wrote the firmware in Rust with Embassy on the RP2040, since learning embedded Rust was half the point of the project. It has a small half bridge driver that can set a phase to a PWM duty cycle, to low, or to floating, and a task that walks through a six-step commutation table slowly enough to follow on the LEDs and the scope.
I also tried a sinusoidal drive on a separate branch, where each phase's duty cycle follows a sine wave 120° apart from the others.
Commutation with the LEDs standing in for the motor
Complementary PWM
Next I changed each half bridge to switch its high and low side opposite each other from the same PWM slice, with about 1 µs of dead time between them, so the two MOSFETs in a phase are never on together and never short the supply to ground.
High and low side PWM with dead time from the Pico (left), and the gate voltages on the inverter (right)

Challenges
-
The boost converter version kept killing the high side MOSFETs
- Solution: I didn't track down exactly why they were dying. Instead I moved to a bootstrap high side drive, which doesn't need a separate supply at all.
Dead high side MOSFETs (left) and the bootstrap drive that replaced the boost converter (right)

-
Commutation that worked with the boost converter came out wrong with the bootstrap drive
- Solution: I first assumed it was a logic bug, but PWM slices 3, 4, and 5 on the Pico seemed to be fried. I moved the phases onto other slices and dropped the bootstrap capacitor from 10 µF to 100 nF, and after that phases A and B commutated cleanly.
Phase A (orange) and phase B (blue) before (left) and after (right) the fix, Vcc = 8 V

Next steps
The ESC hasn't spun a motor yet, and there's no back EMF sensing, so it can't run sensorless yet either. The plan from here is:
- Run a motor
- Add shunt resistors and start measuring back EMF
- Look at a totem pole gate driver
- Move the circuit off the breadboard onto a dev PCB
- Try out different control approaches, from a simple PID to a linear quadratic regulator
Repositories
- Hardware: github.com/georgesleen/open-esc-hardware
- Firmware: github.com/georgesleen/open-esc-firmware