Help programming 2 quad shaft encoders


I need help programming 2 quad shaft encoders. I have one on each wheel. I need to understand how to use both encoders at the same time.

My current program, which does not work, runs one side until its quad shaft encoder is equal to the value I set. And then it stops. Then the other side does the same. Sometimes one motor is faster than the other, making it so that one motor stops while the other is running. This messes up the turn. :frowning:

How do I fix it?


If you are using robotC, then there are a whole host of basic motions with encoders in the sample programs under shaft encoders.

Better questions generate better results…

  • no description of what programming environment (easyCv2/V4/RobotC)
  • no program posted, to show what you have, what your pgming level is
  • no better failure description than “messed up turns”
  • try also searching the forum for “drive straight”

Classic Robot Autonomous theory is “Sense, Plan, Act”:
If you are able to get good readings from both sensor, then you have Sense.
Act is just setting motors, except dont update more frequently than 20ms
So most deficiencies are in the Plan.

You need to know your current speed on each side, then speed up or slow down the motors to make the speeds equal, (to drive straight).

We are using EasyCv4 with a 2 motor drive.
In the past when we posted all kinds of details on our question we didn’t get any response, so I wondered if simpler questions were better to get help started.

I looked through all the samples in EasyCv4 and I didn’t find anything on 2 shaft encoders to turn. I found how to sense the value of shaft encoders, which I already knew.

When we are turning, sometimes one motor will spin faster than the other. Thus completing its rotations sooner. Then one motor stops and the other motor continues on for a little bit. Thus making our turn go a little less or a little more than we want it to.

I used the program for our autonomous mode. I just deleted the part about the second shaft encoder because it wasn’t working. I can describe it. The step of the program where the robot turns is in a “while step 1 is equal to 1” loop. The while loop has 2 "if"s in it both with “else” attached to them. The first “if” asks if the left motor has completed its rotations. If it has, it stops its motor it is connected to. The right shaft encoder asks if it’s motor has completed its rotations, if it has, it stops its motor. I didn’t know how to add to variables, I only know how to set them to a value, so I used a complicated part using a bunch of “ifs” and variables to make it so the while loop would stop when both motors had reached their value.

Is there a more accurate way to use two shaft encoders to turn?


Interesting use of the experimental method, trial and error…
Here is a long response full of details, don’t let it give you the wrong idea about simpler questions.

Here is how to add to variables:
Use assignment statement pulldown: insert var, insert operator +=, insert value to add.
or type directly in the assignment statement block window like these examples:
var = var + 27; // increment by 27
var += var2; // increment by var2, same as var = var + var2;
var++; // increment by 1 after using var
++var; // increment by 1 before using var
var= var++; // illegal operation, multiple results for var both before and after.

Yes, use encoder feedback to change the speed of the motors so they spin at the same speeds.

Here is some calculus/physics:
position = x; // this is what your encoder returns.
velocity = prev_x - this_x ; // rate of change is delta since you last checked
speed = abs( velocity ); // velocity knows direction, speed doesn’t

Doing a ztr turn is really nearly exactly the same as driving straight for some distance, except one of the motor speeds is inverted.
It might be easier to start with drive-straight routine.

untested pseudo code outline for driving straight or turning.

// previous step in autonomous routine   
while(1) { // do this step in autonomos routine   
  wait(20);  // motors dont update faster than this anyway
  prev_enc1 = enc1;  // save previous values
  prev_enc2 = enc2;
  enc1 = GetEncoder(1); // get current values
  enc2 = GenEncoder(2);
  speed1 = enc1-prev_enc1;  // calculate current speeds
  speed2 = enc2-prev_enc2;
   if (speed1 > speed2 ) { motor1 -= 10; motor2 += 10; }
   if (speed2 > speed1 ) { motor2 -= 10; motor1 += 10; }
   stop_me = 0; // clear
   if (enc1 > enc1_limit)  { set_motor(1,0); ++stop_me} //stop it 
    else {set_motor(1,motor1); } // else set speed
   if (enc2 > enc2_limit)  { set_motor(2,0); ++stop_me} //stop it 
    else {set_motor(2,motor2); } // else set speed
   if (stop_me >= 2) { break; }  // get out of while() loop, go to next step.
} //wend
// next step in autonomous routine   

Details for you to work out, if you cant find a previously posted drive straight code to start with;

  • create and initialize all the variables, fix all the syntax;
  • Keep the motor variable from going outside +/- 127.
  • If motor was set to 100, and you want to speed it up, add more.
    If motor was set to -100, and you want to speed it up, subtract more.
    figure out how to do which one.
  • Depending on how your encoders are mounted and plugged in, they may be counting in opposite directions, and which is increasing depends on turning left or right. How will you figure that out to calculate speeds correctly?
  • This is simple feedback; to do the P part of PID, change from +/- 10 to +/- N, where N is proportional to the difference in the speed.

Eventually, you’ll want to make this a subroutine, so you can make a stack of subroutine calls to replaced timed driving in your autonomous. If you think about what parameters you need to call the subroutines in advance of writing them, it will help you write them. This is called “top down design”.

A example of simple set of subroutine calls might be:
DriveStraight( distance );
TurnLeft ( distance );
TurnRight( distance );

These could be coded independently, or eventually be combined into one;
Drive( direction, speed, distance );

I wonder if long answers will be more effective. The short answer is “Yes”

Thanks so much jgraber! It works great! We were able to get 20 points in autonomous mode because of you!!!


Thats Terrific, Congratulations, I couldn’t have done it without your help. :wink:

You could pay it forward by posting your code, as a zip of the two EasyC files.