Synchronizing Motor Position with Encoders, PID Control and Arduino

Ғылым және технология

In this video, I demonstrate how to use PID Control to synch the positions of two motors with encoders by only using two interrupt pins on the Arduino.
Check out this Reference Desk Mat for Arduino:
amzn.to/3vO6QBl
Video Timestamps:
0:00 - Introduction
0:33 - PID Control for a single motor
0:40 - Parts needed
0:46 - Pin out for the motor and encoder
0:58 - Wiring the circuit
1:16 - Arduino code for one motor
4:40 - Selecting the gains
5:27 - Beginning of two motor example
5:32 - Updating the wiring for two motors
5:58 - Arduino code for two motors
7:29 - Selecting the gains for the two motor example
7:58 - Conclusion
The code for the section with PID control for a single motor was adapted from what was presented in this video below. I have no incentive to reference this video, but it's a great resource for other projects:
• How to control a DC mo...
👉Subscribe for more robotics and engineering tips:
/ @theboredrobotllc
Share this video with a friend:
• Synchronizing Motor Po...
Website:
www.theboredrobot.com/
Parts needed for this example:
Arduino Uno - amzn.to/3pGK6Am
Gear Motors with Encoder - amzn.to/3Fszeuj
Power Supply - amzn.to/3DKs2sF
Motor Shield - amzn.to/3Qtbeh6
(Note: This shield is a different one from the example. Make sure the pin assignments line up with the the documentation for the shield.)
Connect:
Instagram - /theboredrobot
Twitter - @theboredrobot
Facebook - / theboredrobot
Pinterest - /TheBoredRobot
Disclaimer: This video contains affiliate links, meaning that if you make a purchase from one of the product links, I'll receive a small commission.

Пікірлер: 78

  • @noah7164
    @noah71647 ай бұрын

    Just the video i needed for my project. Thank you!!!

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    7 ай бұрын

    Glad I could help!

  • @ffsscorpion6940
    @ffsscorpion69408 ай бұрын

    Just a quick note, you don't need 2 interrupt pins for each encoder, you need to attach an interrupt to just 1 and check the level of the other, so you could use that to allow both direction catch-up, maybe even use in of the motor as a very expensive encoder input and move it with your hand, great vid though ❤

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    8 ай бұрын

    That's a great idea and I should try out. I don't know why I didn't think to check for the status outside of the function called by the interrupts. Thank you for this!

  • @drotalion620

    @drotalion620

    7 ай бұрын

    I kinda don't get it. What do you mean with "level of the other"? Do you mean like: Rotation you provided first decides in interrupt if stepsCounter++ or stepsCounter--?

  • @peterlingas

    @peterlingas

    5 ай бұрын

    @@drotalion620 When the interrupt is triggered, you can check the voltage level of the other encoder pin. Depending on the state of it you can tell if it was triggered due to clockwise or counterclockwise rotation. So indeed, it will let you decide if you should do stepsCounter++ or stepsCounter--.

  • @khalmaxroboticsgh3176

    @khalmaxroboticsgh3176

    4 ай бұрын

    I'm working on a 4wd robot car using Arduino Mega. I am trying to synchronize the speed of all 4 wheels of the robot. I intend to read the motor speed from each motor using an AS5600 hall sensor. That means 4 hall sensors in all. I also realised the arduino mega has only one sda and scl pins so this tutorial is helpful. Can you also help me with more tips and advise on how to go about it? Thanks

  • @Rolandvanroy
    @Rolandvanroy3 ай бұрын

    Thanks for this interesting video. Any reason why you did not use the Arduino PID library?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    3 ай бұрын

    The PID library probably would have been less lines of code. This just happens to be more of an educational exercise.

  • @arduinomaquinas
    @arduinomaquinas5 ай бұрын

    Very cool video ❤😉👍 👏👏👏

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    5 ай бұрын

    Thank you!

  • @MukeshPatel-tw5ge
    @MukeshPatel-tw5ge5 ай бұрын

    Thanks for your video. It is great ! Which motor do you recommend for a robo vehicle project using 9v running by arduino ? The RPM requirement is 75-100 and goal is to have precision straight and angular move for a school competition. And if you can suggest best wheels/tires. Thanks for your help.

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    5 ай бұрын

    For a vehicle, I recommend using a brushed motor. There are some decent motor/wheel combos on Amazon. Otherwise, I often buy from Pololu or Servo City.

  • @MukeshPatel-tw5ge

    @MukeshPatel-tw5ge

    4 ай бұрын

    @edRobotLLC Thanks. My son got motor synchronization working after learning from your video. As you said in video that Arduino Uno has pin limitation so you used only one encoder output from each motor. Arduino Giga has so many pins available, can you suggest how can we use both encoder pins of two motors for synchronization ? Will that work better ? Thanks a lot.

  • @MUHAMMAD-hl2tn
    @MUHAMMAD-hl2tn6 ай бұрын

    The motor in video is different from one you mentioned in links. Could you tell what is the motor you have used in video?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    6 ай бұрын

    www.pololu.com/category/116/37d-metal-gearmotors

  • @jameslin3841
    @jameslin38414 ай бұрын

    Thank you so much for the content🙏 may I know which encoder did u use to control the motor?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    4 ай бұрын

    I used these: www.pololu.com/category/116/37d-metal-gearmotors

  • @jameslin3841

    @jameslin3841

    4 ай бұрын

    @@TheBoredRobotLLC Thank you so much!!

  • @omarsalem5832
    @omarsalem58326 ай бұрын

    What's 'target' variable? how do you set the angle/position?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    6 ай бұрын

    The 'target' is the desired value in the PID controller. This is the desired encoder count. You'll have what relationship the encoder count has with a specific angle or position in your system.

  • @roh5768
    @roh57686 ай бұрын

    Are you able to code the motors to allow for turning to be possible given the shortcomings of the interrupters?

  • @srinathnarayanan2585

    @srinathnarayanan2585

    6 ай бұрын

    Brilliant question! Looking forward to an answer as well.

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    6 ай бұрын

    Are referring to the fact that Arduino Uno only has 2 interrupt pins? I haven't worked on this problem yet, but you certainly gave me a new idea for another tutorial video.

  • @brendanowen7563

    @brendanowen7563

    4 ай бұрын

    @@TheBoredRobotLLC You could solve this problem, but wiring the second encoder pin of each motor to another input on the board. You do not need to use the interrupts on these pins. You can just use the original logic of comparing the encoder outputs from each motor.

  • @joshuacain485
    @joshuacain4855 ай бұрын

    I'm trying to get my motor to work, and so far so good (new at this) - I don't understand something - you're showing controlling the direction with pin 4 - but nothing is plugged into pin 4 in your circuit?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    5 ай бұрын

    That signal is coming from the motor shield.

  • @sarinashahhosseini
    @sarinashahhosseini2 ай бұрын

    Does synchronizing also depend on the initial position of the two motors? Since from the beginning we are counting encoder counts, then synchronization only can happen if the motors started at the same position.

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    2 ай бұрын

    For this simple example, it's assumed that the motors start at the same position. The motor positions are relative to the positions that the motors started at when the Arduino was powered up.

  • @sampamnl.8964
    @sampamnl.8964Ай бұрын

    ขอบคุณมากครับ

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    Ай бұрын

    You're welcome!

  • @memocool4279
    @memocool42793 ай бұрын

    Can you please tell me how to control 2 dc motors with different targets rather than following each other. Like what changes to the code should i do.

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    3 ай бұрын

    Instead of the set point to the PID controller being the position of one of the motor encoders, set it to your desired set point. You'll need the PID output signal to then go to both motors.

  • @khalmaxroboticsgh3176
    @khalmaxroboticsgh31764 ай бұрын

    I'm working on a 4wd robot car using Arduino Mega. I am trying to synchronize the speed of all 4 wheels of the robot. I intend to read the motor speed from each motor using an AS5600 hall sensor. That means 4 hall sensors in all. I also realised the arduino mega has only one sda and scl pins so this tutorial is helpful. Can you also help me with more tips and advise on how to go about it? Thanks

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    4 ай бұрын

    It's the same process, but you'll need the additional interrupt for the additional motors. For the mega, pins 2, 3, 18, 19, 20, and 21 will accomplish this for the sensors.

  • @khalmaxroboticsgh3176

    @khalmaxroboticsgh3176

    4 ай бұрын

    @@TheBoredRobotLLC that's the problem. Iam using four AS5600 hall sensors on each tire. Problem is I can only read from one hall sensor I.e sda and scl pins on arduino mega. How to I hall read sensor values from all tires on arduino

  • @blibberblabber756
    @blibberblabber7563 ай бұрын

    Both of my encoder counts go up by a lot, within just a second they are in the 1000s, is this supposed to be happening? I am asking this because I want to make my robot move the same distance no matter the speed of the motors, so I need to be able to count the motors rotations. Also, does this setup allow for the motors to be in sync going in reverse as they don't utilize the other encoder signal?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    3 ай бұрын

    It's hard to say what would cause the count to jump so much. Take a look at what is causing the interrupt to be triggered. This method doesn't allow for reverse.

  • @siddharthtata
    @siddharthtata5 ай бұрын

    I have a small query, what did you connect to pin 4 and 5 ? I am unable to see any more wires connected @ 1:10

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    5 ай бұрын

    Pins 4 and 5 have are assigned to the direction and speed values, as defined by this specific motor shield.

  • @siddharthtata

    @siddharthtata

    5 ай бұрын

    ​​@@TheBoredRobotLLCsorry for this silly question but how is the signal being given to the motor for speed and direction? I only see six wires and according to the pinout 2 are for encoder outputs, 2 for power and 2 for hall effect sensors. Wires for 4 and 5 are not visible in the video. Is there an internal connection which I am missing?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    5 ай бұрын

    @@siddharthtata There are signals coming directly from the motor shield.

  • @gutgutia
    @gutgutia5 ай бұрын

    This is a life saver - thank you! Would you mind uploading the code please?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    5 ай бұрын

    github.com/TheBoredRobot/KZread-Code

  • @gutgutia

    @gutgutia

    4 ай бұрын

    Thank you!

  • @User-Tal1951
    @User-Tal19513 ай бұрын

    Any advice for a motor that moves very fast 180 degrees?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    3 ай бұрын

    That's a pretty broad question. You'll probably have to really tune the gains carefully. Start with a slow motor speed, and then work your way up to a faster speed.

  • @deksis8519
    @deksis85195 ай бұрын

    I used the code in github (just changed the pin #'s) and motor 1 moves but motor 2 does not. I am using a l298n sheild and arduino uno for my 2 motors. Do you know what the issue could be?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    5 ай бұрын

    That's a pretty hard question to answer without knowing all the details of the project. My first steps would be to check the connections and the jumper selections on the shield. Then I would double check the pin assignments.

  • @deksis8519

    @deksis8519

    5 ай бұрын

    ​thx! I ended up adding a few lines of code under the moveMotor command and it works well enough for what I need. Great video, helped a ton!

  • @GaBut-wo8nr
    @GaBut-wo8nr5 ай бұрын

    #define DIR1 4 #define PWM1 5 #define encoderPinA 2 #define encoderPinB 3 volatile long encoderCount = 0; long previousTime = 0; float ePrevious = 0; float eIntegral = 0; void setup() { Serial.begin(9600); pinMode(DIR1, OUTPUT); pinMode(PWM1, OUTPUT); pinMode(encoderPinA, INPUT); pinMode(encoderPinB, INPUT); attachInterrupt(digitalPinToInterrupt(encoderPinA), handleEncoder. RISING); } void loop() { int target = 1000; float kp = 0,0; float kd = 0,0; float ki = 0,0; float u = pidController(target, kp, kd, ki); moveMotor(DIR1, PWM1, u); Serial.print(target); Serial.print(", "); Serial.print(encoderCount); } void handleEncoder() { if (digitalRad(encoderPinA) > digitalRead(encoderPinB)){ encoderCount++; } else{ encoderCount--; } } void moveMotor(int dirPin, int pwmPin, float u){ float speed = fabs(u); if(speed > 255){ speed = 255; } int direction = 1; if (u direction = 0; } digitalWrite(dirPin, direction); analogWrite(pwmPin, speed); } float pinController(int target, float kp, float kd, float ki) { long currentTime = micros(); float deltaT = ((float)(currentTime - previousTime)) / 1.0e6; int e = encoderCount - target; float eDerivative = (e - ePrevious) / deltaT; eIntegral = eIntegral + e * deltaT; float u = (kp * e) + (kd * eDerivative) + (ki * eIntegral); previousTime = currentTime; ePrevious = e: return u; }

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    5 ай бұрын

    Feel free to contact me if you have a specific question on this. theboredrobot.com/pages/contact

  • @abekiri
    @abekiri5 ай бұрын

    Thank you for this video, can you share the code

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    5 ай бұрын

    github.com/TheBoredRobot/KZread-Code

  • @shivpat6522
    @shivpat65224 ай бұрын

    Hi. I have a question regarding your code. I notice in my code, there isn't any identified osilations detected or at least what is shown on your serial plotter in 5:09 and my code is really generic to yours. Do you know what could be causing the issues. I think it has to do with my gains, speed, or encodercount.

  • @shivpat6522

    @shivpat6522

    4 ай бұрын

    Yea more likely encoder count because in serial plotter, my target looks fine at 1000, but my encoder count stays consistently at 0 even when the motor is running, leading to no change regardless of PID gains.

  • @shivpat6522

    @shivpat6522

    4 ай бұрын

    Another question. For the dual motor code, everything looks right except for PID controller. This is because for your "int e", your initial equation for 1 motor was "int e. = encoderCount - target;" but since there are 2 encoders coming into perspective right now, how are we supposed to write the code for this with 2 encoders, each from each motor.

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    4 ай бұрын

    If you're not seeing oscillations in your plot, your derivative gain may be high, or proportional gain might be low. It's hard to say without seeing all of the details.

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    4 ай бұрын

    In the code with 2 motors, one of the motors is just moving at a constant speed in one direction. This count is being tracked and being used as the target for the second motor. The PID controller is being implemented on the second motor. It's a simple example showing the limitations of only having two interrupt pins on the Arduino Uno.

  • @user-vl6nu2tn5j
    @user-vl6nu2tn5j2 ай бұрын

    Is it possible for the motor '1' to go around 10 times, and the motor '2' to go around 1 time?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    2 ай бұрын

    Yes that is possible. You would have to know the number of counts per revolution and then set that to be your desired position in your code.

  • @xanderyesilirmak956
    @xanderyesilirmak956Ай бұрын

    Out of interest, if one motor is moved by hand when stationary, does the other motor follow the other still?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    Ай бұрын

    Yes, it should still work. If you ever tried to take the back of one of these motors off to expose the encoder, you're count should still go up if you move the encoder by hand. However, the motor shafts in this video are pretty hard to move by hand because of the gear ratio.

  • @drotalion620
    @drotalion6207 ай бұрын

    What happens, when Motor 2 can't reach the speed of motor 1 because of unbalanced load for example? In this case, motor 1 will not get slower, I guess. Any idea, how to handle this problem? Else cool idea. Thank you

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    7 ай бұрын

    That is certainly a limitation of this approach under these constraints. If the second motor can't go faster than the first 1 one, then it won't work.

  • @shivpat6522
    @shivpat65224 ай бұрын

    Can you send a file or a link of the code for me to easily replicate

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    4 ай бұрын

    theboredrobot.com/pages/contact

  • @abdotsouri9432
    @abdotsouri943228 күн бұрын

    link of the code !

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    20 күн бұрын

    github.com/TheBoredRobot/KZread-Code

  • @christiandelacruz6796
    @christiandelacruz67964 ай бұрын

    Hello can i have a copy for the whole code? We are also conducting a robot sweeper for our capstone project, we will use 2 dc motor with encoder. Hope i can have Thanks!

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    4 ай бұрын

    github.com/TheBoredRobot

  • @hichamgrinda7869
    @hichamgrinda78693 ай бұрын

    where is the code?

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    3 ай бұрын

    github.com/TheBoredRobot/KZread-Code

  • @mbenj2023
    @mbenj2023Ай бұрын

    Outputs were visibly not synchronised.

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    Ай бұрын

    Arduino not synchronous in general, but this did approach did the job for the application of getting two walking legs to sync up for another project. I do agree there is still plenty of room for improvement with adjusting gains or even a completely different method.

  • @GeekDetour
    @GeekDetourАй бұрын

    Ok.... but... why? ha ha ha. I was expecting a particular practical reason for that.

  • @TheBoredRobotLLC

    @TheBoredRobotLLC

    Ай бұрын

    This video was made for a group of students who had built walking mechanisms that needed the linkages to be in sync. It was for a very specific project.

Келесі