Driving a BLDC motor from zero to slow-and-janky in Python

Motor and Pico, ready for battle…

One of my personal goals for PiWars this year was to try to build a BLDC motor controller. Mainly because I find that kind of thing a fun challenge…

Why is controlling a BrushLess DC motor a challenge? It has no brushes(!) the brushes in a brushed motor physically implement the control algorithm for the coils, energising each coil in the motor in correct sequence in lockstep with the rotation of the motor. Controlling a brushless motor requires the controller to correctly energise the coils in lockstep with the rotation of the motor. This gives great flexibility (but also allows for easily burning out a motor!).

Of course, we could buy a controller off the shelf, but the Pico is out and I wanted to use one in anger. It has been done before by the SimpleFOC project and my plan B was to “just use SimpleFOC” (but there’s less fun in using a library)!

Hello world

At the most basic level, I had the idea that field-oriented control (FOC) was about driving sine wave signals into the three terminals of the motor at 120-degrees out of phase with each other and then rotating those sine waves through 360 degrees in lock-step. In turn that rotates the magnetic field smoothly through 360 degrees and motor’s rotor turns with it. There’s a lot more to it than that, but I didn’t have have a rotary encoder when my motor arrived so I thought “let’s just give that a try in MicroPython”:

  • Assign 3 GPIO pins to the 3 phases of the motor.
  • Make them all PWM outputs at say, 20KHz and connect to motor through a (half bridge) motor driver per pin.
  • Loop, incrementing x each PWM cycle…
    • Set PWM 1 to sin(x)
    • Set PWM 2 to sin(x+120 degrees)
    • Set PWM 3 to sin(x+240 degrees)

And… after some fiddling (and lots of debug prints to the console) something happened!

Writing this now that I’m a bit further on in the project I now know that controlling a motor like this is really bad(TM) because the rotor in the motor “catches up” to the magnetic field, which means that the field stops doing as much work on the rotor and it dumps all that electrical energy we’re feeding it into heat instead :-/ Still, as a hello world, it felt great!

If you’re going to try anything like this and you want to keep the magic smoke inside the motor, you’ll want a benchtop power supply with current limiter and an oscilloscope!

One thought on “Driving a BLDC motor from zero to slow-and-janky in Python”

Leave a Reply

Your email address will not be published. Required fields are marked *