How to control a DC motor with an encoder

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Awesome! I've been doing this recently using DC motors with encoders for a more "professional" linear motion system. For others looking into this sort of thing, I have some more tips.

Most importantly is to actually verify you aren't losing counts from your encoder. Higher speed motors can very easily start losing counts early on. I have a 1000 rpm motor, and I start losing counts around 250 rpm, which is why I am replacing the Arduino with an ESP32. Physically, the motor appeared to be fine keeping track of counts setting a PWM of 160, however, it was still losing about 10 counts out of 12800 at that speed. Only when it was down to about 125 in the PWM did it stop skipping.

To be honest, it is most likely best to have a controller dedicated exclusively towards the counts for the encoder and nothing else. The only thing it does is count using the interrupts and send the current counts when requested. Arduinos are just not good enough for DC motor encoders.

Another thing I would recommend too is to access the pins directly to read the state inside the interrupts using port manipulation. PIN is faster than digitalRead. I was able to increase my PWM value before losing counts by about 20.

👍︎︎ 10 👤︎︎ u/Kobayakawamiyuki 📅︎︎ Feb 16 2021 🗫︎ replies

Very Nicely explained!

👍︎︎ 3 👤︎︎ u/abhijelly 📅︎︎ Feb 16 2021 🗫︎ replies
👍︎︎ 1 👤︎︎ u/AgAero 📅︎︎ Feb 16 2021 🗫︎ replies

Clear development of concepts. Good use of visuals. Excellent code breakdown. all-around fantastic presentation. Well done!

👍︎︎ 1 👤︎︎ u/vosper 📅︎︎ Feb 17 2021 🗫︎ replies
Captions
by itself a dc motor can't be controlled like a servo or stepper but add an encoder and it can with this approach you can harness the simplicity even torque and lightweight profile of a dc motor for your controlled application for this build you'll need a microcontroller a dc motor with an encoder and a motor driver i'm using an arduino uno and a polulu motor and driver to read from the encoder connect the encoder output pins to digital pins with interrupts for an uno that means pins two and three you also need to connect the encoder to the arduino ground and five-volt regulator an encoder works by observing changes to the magnetic field created by a magnet attached to the motor shaft as the motor rotates the encoder outputs will trigger periodically when the magnet spins clockwise output a will trigger first when rotated counterclockwise on the other hand output b will trigger first let's observe how an encoder works by reading from the encoder outputs define the pins connected to the encoder outputs and set them to input mode in the loop function read from the encoder write the output to the serial line i multiplied by 5 to make the plot easier to read try rotating the encoder magnet the encoder signals will change rapidly it's easier to understand the output with the serial plotter so let's open that notice that when i rotate the magnet clockwise output a is triggered first counterclockwise rotations cause output b to trigger first now let's measure the position of the motor shaft first create a global variable for the position instead of reading from the encoder inside the loop function you'll want to attach an interrupt that triggers each time output a rises the attach interrupt function has three inputs the interrupt which is found using the digital pin to interrupt function the name of a function to call when the interrupt happens which i've named read encoder and the trigger type inside the loop function report the current position the most important piece of this code is the read encoder function which is called whenever output a triggers an interrupt inside the function read from the other output encoder b if the magnet rotates clockwise then the signal b is already high when interrupt triggers in this case add 1 to the position in the case where the magnet rotates counterclockwise signal b is low in this case subtract one try testing your position measurements by rotating the motor shaft and viewing the output on the serial monitor or plotter now that you're reading position measurements from the encoder you're ready to connect the motor driver start by connecting the motor leads to the outputs of the motor driver the motor driver also needs an appropriate power supply next connect the driver ground to the arduino ground the pwm input of the motor driver should be connected to an arduino pwm pin here i've used pin 5. the other two motor driver pins can be connected to any of the remaining arduino digital pins before writing the control algorithm let's test the motor driver start by defining the pins that you connected to the motor driver it's useful to define a function that will set the motor direction and speed the interface for the set motor function i've written here sets the direction and speed of a motor with the pins defined in the last three inputs inside the function i've set the speed with an analog write command if the direction integer is 1 then the motor will rotate one way by writing a high low combination to the input pins of the driver if you reverse the order to a low high combination the motor will rotate the other direction inside the loop function you can call the set motor function to drive the motor also write the position to the serial line so you can observe the motion as the motor spins the position variable will update using the encoder readings so far we've connected the controller motor driver and motor in a loop but we haven't used the position signal from the encoder to control the motor to control the motor position we'll use a feedback loop in a feedback loop the control components are often referred to as the plant here that's the motor and the motor driver the sensor that we're using to measure position is the encoder in order to actually control the position of the motor you need to provide it with a target position then you take the difference between the target position and the measured position the result is the error usually written as e of t now that the error has been computed you can use a controller to compute a control signal that is sent to the plant the control signal is configured so that it will attempt to reduce the error the control signal is typically written as u of t in this project we'll use the pid control algorithm to generate the control signal u of t the pid control signal is constructed using a sum of three terms a proportional derivative and integral term that's what pid stands for the proportional term is the most important as it is directly responsible for reducing the error the derivative and integral terms are typically used to smooth out the control system response the three constants kp ki and kd determine how strongly each term is represented in the control loop you can adjust these constants to tune your response you can estimate the integral and derivative of the error using the simple finite difference approximation shown here the integral term accumulates the error over time and the derivative computes how quickly the error is changing with the feedback control loop complete you're ready to write code to control the position of the motor start by defining global storage variables that can be used to save values between time steps these are used in the finite difference estimates for the integral and derivative the first thing that you need to do in the loop function is set a target for the control loop the control signal will be adjusted over time as the measured position becomes closer to the target next define the constants used in the pid control algorithm start by setting kp to 1 and kd and ki to 0. you can come back and adjust these later to compute the finite difference approximations we need to compute the time difference delta t start by recording the current time in microseconds using the micros function then compute delta t in seconds by taking the difference between the current time and the previous time be careful that you're performing floating point arithmetic not integer arithmetic complete the calculation by storing the current time in the previous time variable for use in the next iteration of the loop the error is computed as the difference between the target and measured positions here i've reversed the order because of the way that i wired the motor leads if you find that your control algorithm isn't working you can try switching the sign of the error term as i did here now compute the derivative and integral of the arrow signal using the finite difference approximations with all that work done you're finally ready to compute your control signal it's surprisingly simple isn't it this signal will tell the plant the direction and speed to turn the motor to send the signal to the motor we need to convert it into a speed and direction start by computing the pwm signal as the floating point absolute value of the control signal u you also need to cap the pwm signal at 255 as that is the maximum value we can write next determine the direction by computing the sign of the control signal u with the motor speed and direction computed from the control signal call the set motor function to write to the motor driver to complete the loop function store the previous value of the error also print your target and measure positions to the serial com so you can test how well your control algorithm is performing with these parameters i'm seeing a little overshoot after reaching the target in other words the motor spins too far and has to reverse directions to achieve the target position one way to reduce overshoot is to increase the derivative term here i've set kd equal to 0.025 this is enough to completely remove the overshoot for this system once your system works to achieve a constant target try setting a target that changes with time here i've set a sinusoidal target depending on your target and loading conditions you will need to further tune your pid parameters i hope this video helped you to understand encoders and control loops let me know if it did and be sure to tell me how you're using pid control in your project in the comments below
Info
Channel: Curio Res
Views: 276,106
Rating: undefined out of 5
Keywords:
Id: dTGITLnYAY0
Channel Id: undefined
Length: 9min 30sec (570 seconds)
Published: Tue Feb 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.