Another Ambassador Moment: Closed-Loop DC Motor Control
2021-05-21 | By Robby Huang
License: None
This project was designed by one of Digi-Key’s own university ambassador students. Check out how it works in the video below!
There are many different kinds of DC motors out there, and they all offer a range of costs, benefits, and challenges for new designers. In this short article, we’ll cover the different types of DC motors that are out there (and why you might want to use them) before examining what closed-loop control is and why you might want to include it in your designs (or not!). Finally, we’ll turn to PID (Proportional, Integral, Derivative) controllers, how they work, and an example batch of code that you can use in your own project!
Different Types of DC Motors
Brushed:
Servo Motors
A servo motor is a rotary actuator or linear actuator that allows for precise control of angular or linear position, velocity, and acceleration. It achieves this by having a feedback system embedded in the motor. It is widely used in robotics and CNC machinery, since it can provide real-time position.
Stepper Motors
Stepper motors have slow, precise rotation and easy setup/control. They are suited for 3D printers and similar devices where the position is fundamental.
DC Motors
These are fast, continuous rotation motors -- while they can’t track position, they are still a cheap and flexible option. DC motors are among the most common/popular choices in the market.
Brushless:
BLDC (Brushless DC Motor)
For this kind of motor, an electric current through the stator windings generates a magnetic field that rotates the permanent magnet of the rotor. It is much more efficient and reliable than the brushed counterparts, but it is much harder to control.
What is Closed-Loop Control?
A closed-loop control system is a set of mechanical or electronic devices that automatically regulates a process variable to the desired state or setpoint without human interaction. This is used in thermostats, smart lighting, or even, arguably, human beings ourselves!
Why do we use closed looped control for a motor?
We don’t have to use a closed-loop control system all the time. In some cases, closed-loop control may do more harm than good.
For example, it would be a bad idea for a traditional fan to use closed-loop control because we want the blades to stop spinning when it hits some obstacles, instead of spinning even harder. Alternatively, consider that you’re sitting in a Tesla without an open-loop control motor. Even if you press the throttle to the same level all the time, you will achieve different speeds when driving on different kinds of surfaces, due to their differences in friction.
In short, closed-loop control helps to maintain the desired state.
PID Control
A PID controller continuously calculates an error value as the difference between a desired setpoint and a measured process variable (output), and it applies a correction based on proportional (P), integral (I), and derivative (D) terms.
Here is the equation that makes all of this work:
Key Variables and Definitions
Kp: The bigger it is, the harder the controller pushes.
Ki: The smaller it is, the quicker the controller reacts to load changes, but the greater risk of oscillations.
Kd: The bigger it is, the more the controller dampens oscillations.
PID Model Tuning Method
- Set all gains to zero.
- Increase the Kp until the response to a disturbance is steady oscillation.
- Increase the Kd gain until the oscillations go away.
- Repeat steps 2 and 3 until increasing the Kd gain does not stop the oscillations.
- Set Kp and Kd to the last stable values.
- Increase the I gain until it brings you to the setpoint with the number of oscillations desired (usually zero).
BOM
Component/Digi-Key Link
- 380:1 Micro Metal Gearmotor HP 6V with Extended Motor Shaft
- Magnetic Encoder Pair Kit for Micro Metal Gearmotors, 12 CPR, 2.7-18V
- DRV8838 Single Brushed DC Motor Driver Carrier
- Adafruit Trinket M0 - for use with CircuitPython & Arduino IDE
PID Control Sample Code
#Author: Robby Huang
#define encoder0PinA 1
#define encoder0PinB 2
#define phase 3
int Speed;
int encoder0Pos = 0;
int i;
int previousTime;
double Setpoint;
double KP = 0.2;
double presentErr;
double Input;
double Output;
void setup() {
Serial.begin(9600);
pinMode(encoder0PinA, INPUT);
pinMode(encoder0PinB, INPUT);
pinMode(phase, OUTPUT);
Setpoint = 40;
attachInterrupt(digitalPinToInterrupt(1),doEncode, RISING);
}
void loop() {
if (i0000 == 0) {
presentErr = Setpoint - Input;
Output += KP * presentErr;
analogWrite(A4, Output);//motor spin, duty cycle (0-255)
digitalWrite(phase, HIGH);//forward = HIGH, backward=LOW
Serial.print("RPM:");
int currentTime = (int)millis();
//Serial.println(currentTime-previousTime);
float Speed = ((60 * 1000 * 3.94 * encoder0Pos/(12*379.17)) /(currentTime-previousTime));
Serial.println(Speed);
Input = abs(Speed);
previousTime = (int)millis();
encoder0Pos = 0;
Serial.print(Input);
Serial.print(" ");
Serial.println(Output);
Serial.print(" ");
Serial.println(Setpoint);
}
i++;
}
void doEncode()
{
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB))
{
encoder0Pos++;
}
else
{
encoder0Pos--;
}
}
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum