Syncing 4 motors using quadrature encoders and interrupts ???

I have four motors that I'm trying to get to move precisely together (within + or - 2 encoder ticks) I'm using a 2560 mega and 4 of its interrupt pins to trigger the interrupt example sketch found here: Arduino Playground - RotaryEncoders for each motor.
I've copied the code four times and changed the variables accordingly. The 1st motor encoder works as expected. The other 3 cycle between 0 and 1. If I hash out all but one motor and encoder set it works. Each motor and encoder work individually. It only fails when trying to run all four together. Can interrupts get in the way of each other?

Is there a better way to determine that four motors are moving together at the same rpm while keeping track of distance traveled?

yes, maybe you can combine the interrupts?

When you say in sync, do you mean speed or position, or both? Are they moving both forward and backward? Are these brushed or brushless motors?

What sort of interrupt frequency do you expect from all those encoders? If you're triggering interrupts faster than the handler can execute then you're going to start losing them.

each motor has a 144 position quadrature encoder. I'm only using the interrupt on the A encoder. So I believe I should be getting a resolution of around 72 for each rotation. The motor rpm that we are shooting for is quite slow. Shaft/encoder speed of about 60 rpm. All four motors need to be rotating at close to the same speed and move the same distance. The positions need to be repeatable going cw and ccw. I can get one motor to read correctly when I add even just one other motor, the second motors encoder isn't getting full resolution. Each motor is a gear motor set up as a continuous servo using a parallax motor controller.

That would produce a very low interrupt frequency and it seems unlikely that contention between interrupts is causing your problem.

I suggest you post your code - perhaps there's a copy/paste error that we can spot.

In what way do the second and subsequent motors misbehave? I don't know what you mean by the others cycling between 0 and 1.

Is it feasible to inhibit the motors independently and confirm that each motor works correctly on its own, if you haven't already done this? (I assume that so far you have run the first motor on its own and in combination with the other motors, but not run the other motors on their own.)

Each motor and encoder works individually. Confirmed by printing the counter value to serial from within the loop. This was confirmed within the full code just by hashing out the other motors systematically. This should rule out any copy and paste errors. When I upload the code with more than one motor activated the first one in order prints the same counter values as when it was tested individually. The next motors counter will stay between 0 and 1. The same values it gives with a wrong pin assignment/interrupt assignment. But as stated above, the code with all current pins works when each motor is tested individually.

I'll post the code when I get a chance, but it's basically just a copy and paste job from the tutorial. I moved the print function to the loop to try and minimize the time each interrupt program takes to process.

The code is definitely going to be needed to sort out your problem. When you do post it, you can attach it to your post since it is probably going to be too long to just post in the body.

(1) Did you consider stepper motors? As long as you stay well within torque limits, they can operate open loop accurately.

(2) With your CR servos & encoders, use only 1 hardware interrupt. The interrupt routine can sort out which encoder is the trigger. Handling 4 separate interrupts is like baby sitting for 4 hyperactive 3 year olds :slight_smile:

each motor has a 144 position quadrature encoder. I'm only using the interrupt on the A encoder. So I believe I should be getting a resolution of around 72 for each rotation.

An encoder 'step position' is four complete edge transitions of the A and B signals. So depending on what channels your using for interrupt sources (A or B or both) and if your interrupting on 'change' or just falling or raising the following will be the 'step counts Vs encoder position steps for an encoder rated as 144 positions per revolution:

If using just A or just B and using falling or raising interrupt then 144 counts per revolution.
If using just A or just B and using 'change' interrupt then 288 counts per revolution.
if using both A and B and using falling or raising interrupt then 288 counts per revolution.
if using both A and B and using 'change' interrupts then 576 counts per revolution.

Lefty