Motor Control from Scratch! Pt1

    I've had a hobby project sitting in the background for years. A long time ago, I think when I was still in undergrad, I decided I wanted to build a BLDC motor driver from scratch. "From scratch" meaning using only discrete semiconductors that I select and assemble myself. The main reason for this, aside from pure curiosity, is that long ago I identified power electronics as a personal weak area. I don't like working with black boxes. The margins in robotics are incredibly thin. And whatever part of the system you don't understand, that's the part that's going to limit you. So I figured building my own BLDC driver would be a good way to learn and prove that I know a useful amount about this topic.

    Several years ago I bought a bunch of inexpensive BLDC motors and a bunch of generic MOSFETs and tried to build a BLDC driver. It's harder than I expected. Every little tiny detail matters. I honestly don't remember how far I got, and I don't seem to have any records aside from the earlier blog posts that are still visible on this site. So I'm more or less starting over clean.

    In a nutshell, a BLDC driver isn't much more than a three-phase bridge with a few control loops wrapped around it. But every part of that system is complicated and touchy. To keep things manageable, I'm planning on building the driver in several parts or modules. I need a bridge module that will distribute power to the motor windings, a current sensing and current control module, and a motion control module.


    The bridge itself is pretty straight forward. I have three complimentary N/P MOSFET pairs driven by six NPN BJTs driven by six PWM signals from a Tiva board. The PWMs are running at 25kHz, just above the limit of human hearing. I spent several hours trying to figure out why my motor was drawing more than 2A but was only vibrating slightly and not turning before I realized that 1) I hooked up the BJTs incorrectly and 2) the incorrectly wired BJTs were only partially saturating the MOSFETs, causing them to run inefficiently and produce tons of heat, in turn pulling my power supply voltage down (because it was current limited), further reducing the BJT's ability to drive the MOSFETs. After fixing the BJTs, everything worked much better. I could actually drive the motor with speed control with ~0.6A.

    That's great. This is already farther than I got the last time I tried to build this thing. I'm doing open loop speed control and none of the chips have popped so far (though I did burn up one Tiva board). However, the speed control that I'm doing is really, really ugly. The motor is turning at the desired speed, but it's vibrating all over the place. Something's seriously wrong there.


    At first I thought simply increasing the PWM frequency might fix the problem. I tried 50kHz and 100kHz, but the motor was still very jerky. I tried inductors and capacitors to smooth the voltage on the motor side, no change there. So I got out the oscilloscope.

    Looking at the signals, I can see that the BJTs aren't saturating completely at low duties. I'm putting trapezoidal PWM waves in on the GPIO side and I'm getting something decidedly different out on the motor side.

Two complimentary switching signals traveling from BJTs to MOSFETs. These look pretty decent.

One BJT-to-MOSFET signal, the rising phase of a trapezoidal wave. The MOSFET doesn't saturate at duties below ~1/3.

Teal is motor winding voltage. Should be clean trapezoidal PWM. It's not.

    Changing the resistance values connected to the BJTs was the only thing that delivered an improvement that I could see. That did allow the BJTs and MOSFETs to saturate more fully, producing noticeably smoother motion than before. But I'm still getting large, sharp steps in winding voltage as it shifts between phases. And that's what causing all of the jitter I'm seeing in motor motion. When I slow the motor down to 1phase/second, it becomes very obvious. The PWM has no effect at all. The motor jerks from the center of one phase to the center of the next. I'm thinking the BJTs are still the biggest problem, so I'm going to replace my NPNs with NPN/PNP pairs.

    After I get smooth switching figured out, I need to implement current control for safety and control purposes. I already threw together a shunt resistor + op amp current sensor, but as is the case with all op amps, it was very noisy and finicky. I'll probably complete that as a proof of concept, then immediately replace it with a pre-calibrated hall effect current sensor IC.

Update 2020-04-02:

    More analysis on MOSFET driving. Driving with low-side BJTs just isn't fast enough. I need to use 100Ω pull-ups to get adequate response, and then I'm burning a full amp just to drive them all. The N-channel MOSFETs are doing fine even at low duties, but the P-channels take 25% duty just to switch. Which explains the weird motor voltage graphs, shown above.


N-channel MOSFETs are working fine
Yellow is PWM signal
Teal is BJT output
Magenta is N-channel MOSFET output

P-channel MOSFETs aren't working at all
Yellow is PWM signal
Teal is BJT output
Magenta is P-channel MOSFET output

For comparison, N's (magenta) are switching almost instantly and P's (blue) won't switch at all below 25% duty

I might give in and buy driver ICs.

Update 2020-04-03:

    I still haven't figured out proper switching. I tried changing drivers for P-channel MOSFETS, using NPN BJTs to drive PNP BJTs which then drive P-channel MOSFETS. It looked almost perfect when the motor was disconnected, but then had major, major problems with excessive current drain when motor was connected. I shouldn't be having problems with dead time, as trapezoidal commutation ensures we only ever have a single MOSFET PWMing at any given time, but I'm having some serious problems with noise in the BJTs that are supposed to be full-high and full-low. I think it's still an issue of inadequate driving for the MOSFETs.


Reasonably clean MOSFET drive signals
(magenta is P-channel, blue is N-channel for the same motor phase)

Really, really ugly voltage coming out of the MOSFETs when the motor is connected

I think this is still an issue of the BJTs just not driving the MOSFETs hard enough, so I've ordered driver ICs. While I'm waiting for those to arrive, I might also try N-channel MOSFETs as drivers.