Help with running two motors in sync


I am hoping some people might be able to help us with a challenge we have with our lift. We are using a scissor lift, powered be a motor around one of the X points. I know that makes no sense at all, but what I mean is this:

We have two scissors, one on each side, with one 393 motor and a potentiometer each. They are only connected at the top and bottom.

What we need to do, is make a program that controls the two to be in synchronization, and hold them at a height as well. We tried just putting the same power on each, but they’re quite a bit different due to friction and the like.

The programmers (I’m not one of them) tried making a P.I.D. control for it (overkill, much) and as expected it didn’t work at all…

Any help would be great!


Hi Kevin,

I wouldn’t say that PID is overkill for this - PID is great for this purpose. It would be handy if you or your programmers could post your code so we can help out with why your PID controller didn’t work properly. Also, EasyC/ROBOTC/PROS/ConVEX?

For keeping arms in sync, I generally am of the opinion that if you need code to keep your arms in sync, chances are there is a mechanical issue. Solve that first if you can. Then, consider just using a P controller to keep your arms in sync to start with, we’ve used that with great success in the past.

Something as simple as this: (using a P controller)

left motor = lift speed + right sensor - left sensor;
right motor = lift speed + left sensor - right sensor;

Should help keep your arms in sync. We used that code in Clean Sweep. You could then improve that to be something like:

lift difference error = right sensor - left sensor;
left motor = lift speed + lift difference error * kP;
right motor = lift speed - lift difference error * kP;

Here you can control the value of kP, tune it to be a more suitable value. In the first example, kP would have effectively been 1.0. For tuning kP, do a search on the forums (or Google) for tuning a P / PID controller, you will find some useful stuff from that. Basically, if 1.0 seems a bit “violent” and your arms are overcorrecting a lot, make it a bit smaller until it gets better.

As for holding the lift at a certain height, you could either just use trim (for a simple solution, that is where you just apply a power of 10-15 (some use values up to 25 though) to the motors when they aren’t moving), or you could go with a PID controller. If you are able to, you would be best just using rubber bands to counter the weight of your intake though.


Hi George,

Thanks for all the help!

We are using RobotC. I will see if I can get the code to post, as none of the programmers have an account here. The first few attempts the arm crept up, and then moved randomly and uncontrollably! We were able to get it to the point where the would move uncontrollably but in sync, so that would most likely mean they were way overcorrecting.

When the arms are put up at full power for the same time, when they get to about 35" there is a difference between the two of 4-5". I think that it’s because each joint (we use bearings and 1" screws with spacers) is a bit different tightness that each arm has different friction overall.

I will see if I can adjust them on Monday. I was thinking of switching them to shoulder screws, but we don’t have enough time. :frowning:

We will try that idea for the code out, seems much easier than a PID controller.

Elastics/tubing would definitely make it easier, but it’s on backorder for us:(. If we get it in time I’ll definitely play around with it and see how it works.

Thanks for all the help! :slight_smile:


I’ve decided to give the programmers after school today to work on it by themselves (no annoying builders telling them to hurry up!) and if they can’t get it working, we’ll post the code to see if we can get help. Although I’m pretty confident George’s idea will work well.

Ok, awesome, let us know how it goes!


We have seen physical sync shafts/gears work very well for scissor. They can get in the way of center game element holding things and require some serious bracing.

Sync shafts as well as having some supports between the two sides were the biggest bang for the buck we’ve seen.

I created lift synchronization code for 2 pots earlier this year and it worked quite well. I wrote tests to see what would work and what wouldn’t, and I found that Jij’s way is great, in theory and practice.

The GNU C compiler should compile the C file (RobotC will not).

If you take a look at the txt files, they show the expected output of the C code.
(2 parts; vexforum’s size limits.:frowning: Also note that it is best viewed at 8-space tabs, although the code is best viewed at 4.)
VexLiftSync.c (2.42 KB)
VexLiftSync_Output1.txt (12 KB)
VexLiftSync_Output2.txt (11.4 KB)

My school also uses robotC, and for anything requiring synchronization of two different motors (we often mix very old motors with very new ones, so this is required often) we use basically, a template, which looks a little like this (plus semicolons, proper parentheses, brackets, etc)(values are changeable):

If(Sensorvalue[pot1] = Sensorvalue[pot2]) //moving equal
{ motor[motor1] = 127
motor[motor2] = 127
If(Sensorvalue[pot1] > Sensorvalue[pot2]) //slows down 1 motor for other to catch up
{ motor[motor1] = 100
motor[motor2] = 127
If(sensorvalue[pot1] < sensorvalue[pot2])
{ motor[motor1] = 127
motor[motor2] = 100

My team has found that sometimes it works better if the equal if statement is formed as an if else statement below the others. Anyway, I hope you the best of luck with your lift!

Thanks for the help everyone! We were able to get a working program that keeps them in sync pretty well. They were still a tiny bit off, but we found out it was because of the slack in the gears. When we put a bar and our intake/bucky ball “tray” in it works very well.

We are going to put Latex tubing on it to help in the lifting and to hold it up.

Thank You!

I modified your code so it should compile with RobotC. Also, it has a range check built in, so the sensors do not have to be exactly equal to both travel max power. Note that with the range check, the [else if] statements are necessary.
If you do understand the proportional motor synchronization, it it better to use it, because it is more analog. (See PID Controller For Lego Mindstorms Robots for an explanation of proportional control.)

if (abs(SensorValue[pot1] - SensorValue[pot2]) < 20) {
	motor[motor1] = 127;
	motor[motor2] = 127;
} else if (SensorValue[pot1] > SensorValue[pot2]) {
	motor[motor1] = 100;
	motor[motor2] = 127;
} else if (SensorValue[pot1] < SensorValue[pot2]) {
	motor[motor1] = 127;
	motor[motor2] = 100;

Thank you as well. I tried this on a test robot we keep in the classroom and it works much better. With the compiling issue in what I wrote, I do not have RobotC and home and Im also just plain terrible with semicolons.