Arduino controlled two servos based robot - achieving a straight line
Introduction
In this article I will discuss how I came close to syncing the rotation speed of two continuous rotation servo motors to allow movement in straight line and control the speed of the robot forwards and backwards.
The Problem
If you are making a robot and want it to move in a straight line, and assuming you are using two motors for the drive, you need them to rotate in the same speed.As most people know choosing the correct motor type for the job is important, but sometimes you don't have options and need to work with what you have.
Motor Types:
![]() |
Motor Types Source: https://backyardbrains.com/experiments/MuscleSpikerShield_GripperHand |
Hobbyists & makers usually choose one of these motor types to drive their robot. To achieve a straight line, stepper motors seems to be the right choice since they can be controlled in terms of speed and direction accurately without encoders or feedback circuit. In my case I was stuck with servo motors, and thought why not tackle this challenge, but couldn't find much help online.
No two motors are exactly the same, that means you will find slight differences in the rotation speed for each motor, which causes the robot to drift when trying to move in a straight line.
On top of this, mounting the servo motors on opposite sides of the robot means that one rotates in clockwise direction and the other in counter clockwise direction. Which adds to the difference in rotation speed, I don't believe servo motors rotation speed is symmetrical!
Solution suggestions
First thought was to add an encoder to the continuous rotation servos, but if you worked with servos before you'll find that there isn't much space for one! So my approach was to take an attempt at this statistically!Main idea:
Log the rotation speed of each motor individually at each pulse width speed signal and then map both motors results together.Which means:
- Set motor speed speed signal to 'X' microseconds
- Measure the time it requires to complete a rotation (I actually measured the time needed to rotate three times)
- Change X and measure again
- Do the same for the other motor
Steps:
- Measure time required to rotate at each speed setting
- Measurement
I started plotting data in the range 500 us to 2500 uS, but there was no significant changes in speed from 500 uS to 1200 and from 1800 uS to 2500 uS.
Consequently I used the data range 1200 - 1800 uS in 25 uS speed increments.
Measuring 9 readings and plotting the average time taken to complete 3 rotations:
Motor 1 - Time required (m sec) to complete three rotations at each motor speed signal (uS)
Motor 1 - Time required to complete three rotations VS. motor speed signal
I noted the minimum and maximum time deviations in each speed signal to log the error range:Motor 1 - Error range in ms for each speed signal.
Note: As the speed decreases, approaching motor stop @1500uS signal, error range increases
Did the same for Motor 2...Motor 2 - Time required (m sec) to complete three rotations at each motor speed signal (uS)
Motor 2 - Time required to complete three rotations VS. motor speed signal
Again, noted the minimum and maximum time deviations in each speed signal to log the error range:
Motor 2 - Error range in ms for each speed signal.Note: As the speed decreases, approaching motor stop @1500uS signal, error range increases - Compare the two motors performance
Note: Motor 1 sorted ascendingly and Motor 2 descendingly, as they will be mounted oppositely on the robot, each motor on one wheel.Motor 1 & 2 comparison. Time (sec) to rotate three rotations at each speed signal (uS)
It can be noticed that some of the values are close to each other, but we need to shift the use of motors speed signal.
From the above table, I eliminated the use of 1800uS speed signal (in dark gray) from both motors, as it added no significant speed change, and would allow both sides of the table to shift up to a closer values on both sides.
I also ignored the signals between 1400 - 1500 uS as the error range was already too high in the slow range near the stopping speed signal 1500uS.
The result table would then be:
Note A: Motor 1 sorted ascendingly and Motor 2 descendingly, as they will be mounted oppositely on the robot, each motor on one wheel.
Note B: Both Motors time is now closer in value. which brings us closer to moving in straight lineMotor 1 & 2 comparison at each speed signal after mapping the results
At this point, we could see that we have improved the matching in speed between the two motors. But it's still not quite accurate. We need as much as we can to use values for each motor that would bring them closer to rotating at the same speed.
- To be continued...
Using the Arduino millis() and an optocoupler as the encoder I was able to measure the time to complete three rotations (with a 2 spike arm, that means 6 counts)
Comments
Post a Comment