Connect two arduinos with minimal lag

Hi all,

I'm working on a prototype device that moves two servos approx 500 times per minute (8 times per sec = 125ms per 60° movement.)

The cheap servos are approx 160ms, helicopter tail servos are 60-80ms. Allowing 15-20ms for processing time, sometimes more, the device can be unreliable, especially when the 6V (4xAA) battery flattens to 5V and the servo response increases to 80-100ms.

To get the device to run, I'm using an arduino mega (I have approx 20 outputs - was using all digital pins and all analog pins on a nano, as well as A6 for an analog input, for the proof of concept, but need about 3 or 4 more outputs.

To improve cycle time for the critical movements, I've set up the mega that sends a pulse to a separate nano (acting as a coprocessor, for want of a better description.) The nano handles the non-critical functions such as display, background calcs, overload calculation, etc... The pulse from the mega triggers an interrupt on the nano to initiate calculations.

Question:
In your experience, is there a way that I can pass information from the mega to the nano in a way that won't drastically affect the processing speed of the mega (the nano's not time critical). Ideally, not in setup (easy - Connecting two arduino boards by SPI) but in operation?

I'd appreciate any guidance you can offer.

Regards,

A

Hi, this feels like a classic X-Y problem. You had problems getting your Arduino to do something (problem Y), and you have decided that the only way to solve this is to add a second Arduino to the circuit. Now you have a problem getting the two Arduinos to communicate (problem X) and you are asking for help with that.

Can you share details of problem Y? If that could be solved, wouldn't that be a better solution?

1 Like

Did you consider using shift registers to increase the amount of IO pins on your Arduino?

They work at nanosecond speeds, so you won't notice any delay.

Hi Paul,

Typing on a phone now, excuse typos.

Thx for response.

The issue is clock speed on an arduino - I've got 20-40ms to perform all calcs. Hence why I thought coprocessor, and leave the mega only driving servos.

Make sense? Happy to be corrected.

hmeijdam - yes, thought shift registers too.

Ideally, if I could pass a target time interval across to the nano, it would help as I could pass the last piece of info over and take load off the mega.

(The cycles per min varies from 30 to 500, time interval 2000ms - 120ms)

So, the coprocessor- can passing a time interval across be done with shift registers somehow? Unsure.

Regards,

A

I doubt that. 40ms is a huge amount of time for calculations on a 16MHz controller.

When you setup a communication to a second controller you will loose communication time. Why spend time on communication, when you are out for a fast processing?

As @PaulRB already pointed out, describe your current project, post a schematic, post the code and all dependencies (links to external libraries) and formulate, what should get faster. I bet there are people here, which can help you with that.

1 Like

Thanks noisca,

Will do.

A

What calcs? Forum members may know ways to speed up those calcs. But we can't help if you won't share details.

Thanks Paul,

I'll put everything together in the next couple of days.

8 interlinked components, 40 connections or so.

Working out finer details atm.

A

When you say the servos "are" 160ms, what do you mean? That's the time they take to respond and move to a new given position? What is the Mega doing during that time? delay(160)? If so, that's wasted time that could be used for the calcs.

Sorry Paul,

Been too close to the project.

The cheap Towerpro 9g servos take 160ms to rotate 60 degrees, helicopter tail rotor servos take 70ms for the same distance.

The arduino just sends a pulse between 500 and 2500 microseconds then continues on its merry way. The cheap servos bog down and are still rotating when the next pulse hits.

Helicopter servos work at 333Hz - signal updates every 3ms if I understand correctly.

Give me until after the new year please - I'll put together a schematic and code.

A

1 Like

If you are using the standard Servo library then the signal to the Servo runs at 50Hz no matter what type of servo it is

Faster servos are just that, ie they move faster. Digital servos may use brushless motors to achieve the faster speed and they may run at a higher frequency internally but the Arduino has no influence or knowledge of that

You already know the answer, it's SPI.

Thanks Bob,

Not using the servo library, using straight delayMicroseconds to circumvent it. Didn’t know the minutae of the Servo.h library, so went bare bones.

Thanks for sharing - its good to know

Using brushed tail rotor motors, metal gear, single/dual bearings for speed.

Please post a sketch illustrating how you are using it

Will do - im ironing out a separate bug - be after the new year if OK.

I'll post a circuit and code.

It doesn't have to be your full sketch. Something akin to the Servo Sweep example, or even a one time servo movement between two fixed angles in setup() would show the technique being used,

The reality of that design is your mega will have to be programmed to wait for the answer return so it can be stored in a variable. All mega processing must be done before the coprocessor completes the calculation. Can you ensure that?

Hi Paul,

Thanks, shouldn't be an issue.

Coprocessor might have been the wrong term. perhaps slave may be more accurate?

At the moment, the mega sends a pulse to the nano that initiates a loop through an interrupt which increments a counter on the nano (slave,) splits the value of the counter into digits and then drives a 4 digit, 7 segment LED display to show the value.

Hi Bob,

Typing on a phone, away from computer. Ignore dumb typos and autocorrect errors please.

Using a Spektrum H6060 servo, 0-180°

Datasheet gives 90° = 1520 microseconds pulse, 400 microseconds either way gives approx 45° -> 135° (datasheet says 1000-2000 microseconds).

Pulse lengths of 544 to 2500 microseconds (as per Servo.h library) give approx 190° range of movement.

void setup () {
...
pinMode (3,OUTPUT);
...
}

//Void loop calls subroutine to drive servo

void BottomServoPos (int BottDeg)
{
BottDeg = constrain (BottDeg,45,135);
BottDeg = map (BottDeg,45,135,1120,1920);
// map function allows fine tuning of position.
digitalWrite(3,HIGH);
delayMicroseconds(BottDeg);
digitalWrite(3,LOW);
}

// then loop continues

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.