As part of my 3D printer project, one of the big electronics hurdles to overcome was a motor controller for a BLDC (Brushless Direct Current) motor. Searching for a cheap, off the shelf controllers that would interface easily with a microcontroller turned up fruitless, so I took the opportunity to design my own circuit. It was a major project in itself, and while there’s still a few hardware tweaks to make I’m quite happy with how it has turned out.
Before starting any project it always goes smoother when you take the time to clearly define the features/requirements. After a lot of thought and conversations with others, I came up with the following list of features:
- A single input for motor direction
- A single input for PWM (motor speed/torque)
- Commutate the motor windings based on hall sensor feedback
- Keep track of position through hall sensor feedback and communicate position to external microcontroller
- Inputs for optional quadrature encoder
- A “sample and hold” input to save the position at an instant in time into a buffer (for synchronizing multiple motors/controllers)
- Some kind of communication protocol to communicate with external microcontroller
- Works with 3.3v or 5v control circuitry and 8-36v motor power
- As fast as possible using pin change interrupts and hardware communication
At the heart of this control board is an atmega328p microcontroller running at 16MHz, the same as used on the Arduino Uno, and programming is accomplished via an external ISP programmer. I played around with the idea of using a smaller/cheaper microcontroller, but after including all the features above I ended up using all but 3 of the available pins on the 328. Plus, going with the standard Arduino chip has the benefit of familiarity for me and many others.
Direction and PWM Inputs
A necessary part of any DC motor is that the current direction through the windings alternates as the motor rotates (commutation). The way a typical (brushed) DC motor handles this requirement is via brushes riding on a split ring on the shaft of the motor.
This design makes controlling the motor very easy. Simply apply voltage to the two wires and the motor spins. If you reverse the two wires the motor direction reverses. Then for speed control you add PWM to the motor power.
A BLDC motor has no brushes (by definition) and no split ring to do the commutating. Instead, the commutating is controlled by some kind of logic circuit. This circuit must know the position of the magnets relative to the windings in order to commutate correctly. Also, the majority of BLDC motors have 3 wires coming out of them (3 phase = 3 sets of windings in the motor). Voltage is applied across only 2 of the wires at any given time. Which 2 wires and the polarity of the voltage across them is always changing as the motor rotates. It is the job of the control circuit to do this correctly.
In the image above you can see that there are a total of 6 switches (3 phases * 2 polarities), and for this instant in time voltage is applied across coil A (positive) and coil B (negative). Replace the switches with MOSFETs and you have a basic driver circuit. To get variable speed control you would switch the MOSFETs on and off with a PWM signal at the gate. A total of 3 PWM signals are needed (only one for each coil), the other 3 MOSFETs are plain on or off
For my control board I wanted to have a single PWM input from an external microcontroller control all 3 coils. I accomplished this with some AND gates on board. The control circuit would set the 6 pins for the 6 MOSFETs, 3 of them are routed into one side of the AND gates (separate AND for each of the 3) and the PWM into the other side of the AND. The outputs from the AND gates are PWM modulated versions of what the control circuit is providing, and these signals are then routed to the MOSFETs.
Read More: BLDC motor control using Atmega328