Arduino : DC Motor Position Control using PID
This post is the second installment of my Advanced Arduino Series, where I will be continuing the trend of applying real-life engineering concepts into an Arduino concept. You should check out my previous blog post regarding how to read an optical encoder since we will need that piece of code in order to run the feedback loop for this position control project.
The aim that I will be hoping to achieve is to show you guys how to program a DC Motor in order to move through any specified angle that we want relative to our current position and for it to stay there. We want to achieve this transition in the most efficient way as possible, which all depends on how we set the fixed terms in this PID Controller that I will be showing you. If you want to check out the previous post to this regarding how to read an incremental encoder, you can check it out right here , since you will need the exact same code to read and update angles of the DC motor.
What you will need:
Any Arduino board ( I used the Mega 2560 for this one)
DC Motor ( I used a 90W, 30V)
H-Bridge Motor Driver ( I used a 48V, 40A)
Optical Encoder ( I used 400 ppr)
Power supply ( I actually used my laptop as a default 5V power source w/ a USB cable)
Connector Wires etc.
So what is a PID Controller exactly?
Let's get on to some theory before we actually start implementing it onto a physical system..
The PID Controller basically means 'Proportional,Integral, Derivative Control'. Each of the three terms are sub elements of the total controller that are summed together (to calculate a control gain) in order to correct for an error in some measurement (angle, distance, temperature etc.) between a system's current position and the desired position. There are many linear controllers that can be used for this situation but the PID is actually the most commonly used. I won't go too deep into how the individual sub elements (tuning parameters) actually work but what I can tell you is what their basic functions do. The figure below is a more mathematical representation of this control algorithm.
Proportional term involves correcting a target proportional to the error (set point - actual). The target value is thus never achieved because as the error approaches zero, so too does the applied correction. Thus we need the other two terms to adjust the correction factor down as it approaches the target in order to achieve the target. The Integral term cumulates the error readings from the Proportional action over time to increase the correction factor as the error approaches zero. However, this can lead to overshoot. This is why the Derivative term is used to compensate for this overshoot by slowing down the correction factor applied as the target is approached, therefore counteracting the other two terms (this is why the Kd term in the code is negative) . All the adjustments of the three terms, for me come with trial and error since I don't have quite the experience with theoretical analysis and optimisation of this controller through software such as Matlab.
So now we can get to the fun part and actually implement the theory into an Arduino Mega 2560. What we need to do first is make a simple circuit of the components I listed above, where we connect the optical encoder and the H-bridge to pins of the Arduino. The DC Motor is then connected to the H-bridge (not to the actual Arduino itself) . Important note: Remember to connect the components to the PWM pins of the board. This can vary according to which Arduino board you have.
Finally, here is the code:
Comments are added beside each line for explanation.