Synchronizing Motor Position with Encoders, PID Control and Arduino

Поделиться
HTML-код
  • Опубликовано: 7 июл 2024
  • 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
    @noah7164 7 месяцев назад +4

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

  • @arduinomaquinas
    @arduinomaquinas 5 месяцев назад +1

    Very cool video ❤😉👍 👏👏👏

  • @ffsscorpion6940
    @ffsscorpion6940 8 месяцев назад +10

    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 месяцев назад +5

      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 месяцев назад +2

      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 месяцев назад +2

      @@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
    @Rolandvanroy 3 месяца назад

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

    • @TheBoredRobotLLC
      @TheBoredRobotLLC  3 месяца назад +3

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

  • @GaBut-wo8nr
    @GaBut-wo8nr 5 месяцев назад +5

    #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 < 0){
    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

  • @sampamnl.8964
    @sampamnl.8964 Месяц назад +1

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

  • @MukeshPatel-tw5ge
    @MukeshPatel-tw5ge 5 месяцев назад +3

    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 месяцев назад +1

      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-hl2tn 6 месяцев назад +1

    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 месяцев назад +1

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

  • @jameslin3841
    @jameslin3841 5 месяцев назад

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

    • @TheBoredRobotLLC
      @TheBoredRobotLLC  5 месяцев назад +1

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

    • @jameslin3841
      @jameslin3841 4 месяца назад

      @@TheBoredRobotLLC Thank you so much!!

  • @gutgutia
    @gutgutia 5 месяцев назад +1

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

  • @roh5768
    @roh5768 6 месяцев назад +2

    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 месяцев назад +1

      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.

  • @omarsalem5832
    @omarsalem5832 6 месяцев назад +2

    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.

  • @sarinashahhosseini
    @sarinashahhosseini 2 месяца назад

    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.

  • @khalmaxroboticsgh3176
    @khalmaxroboticsgh3176 4 месяца назад +1

    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

  • @joshuacain485
    @joshuacain485 5 месяцев назад

    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.

  • @siddharthtata
    @siddharthtata 5 месяцев назад +1

    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 месяцев назад +1

      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.

  • @memocool4279
    @memocool4279 3 месяца назад

    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.

  • @blibberblabber756
    @blibberblabber756 3 месяца назад

    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.

  • @abekiri
    @abekiri 5 месяцев назад +1

    Thank you for this video, can you share the 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.

  • @User-Tal1951
    @User-Tal1951 3 месяца назад

    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.

  • @user-vl6nu2tn5j
    @user-vl6nu2tn5j 2 месяца назад

    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.

  • @deksis8519
    @deksis8519 5 месяцев назад

    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!

  • @shivpat6522
    @shivpat6522 4 месяца назад

    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.

  • @drotalion620
    @drotalion620 7 месяцев назад +1

    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
    @shivpat6522 4 месяца назад

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

  • @abdotsouri9432
    @abdotsouri9432 Месяц назад +1

    link of the code !

  • @christiandelacruz6796
    @christiandelacruz6796 4 месяца назад

    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!

  • @hichamgrinda7869
    @hichamgrinda7869 3 месяца назад

    where is the code?

  • @mbenj2023
    @mbenj2023 Месяц назад

    Outputs were visibly not synchronised.

    • @TheBoredRobotLLC
      @TheBoredRobotLLC  Месяц назад +1

      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 2 месяца назад

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

    • @TheBoredRobotLLC
      @TheBoredRobotLLC  2 месяца назад

      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.