synchronizing 2 or 3 Arduinos

I have two Christmas displays with 128 pixels each (RGB pixels: 364 LEDs) that flash different patterns. One is called “Snowflake” and the other is “Star”. Both run on their own Arduino UNOs and both have 8 port expanders attached running on I2C. Everything works well…tonight is last night the display is up so now I have to do upgrades.

I’m going to make another snowflake so that the two of them frame the star. I want the functions, about 50 in each UNO, to be in sync with each other, so that both snowflakes display in real time the exact same light pattern. see attached.

How should I proceed? Should I use serial communication from one to the other? How about using I2C? Since both Snowflakes have the same I2C addresses, I’ll have to use an I2C multiplexer, which I have in “stock”. Will that work? Could the “master” Arduino run the snowflake code and send out the signals via the multiplexer to each snowflake?

The Star can just run it’s own functions but eventually I would want to control it’s display in conjunction with the snowflakes.

I’ve read a number of methods on this forum from a few years ago…some good info but not exactly what I’m looking for. I’d rather not use interrupts, probably can’t in this situation anyway.

Suppose one Arduino is used as a kind of master sending out a sync signal. The "slave" is waiting in a tight while loop waiting for the sync. The "sync" could be a digital signal from the "matser" to the "slave". After sending the sync both controllers run the same game and the master run a short delay before next turn in the loop, making sure that the "slave" has finished.

It’s not necessary to have an extra Arduino as master (as suggested in your image); surely one of the three can do that as well.

Use one output for a “clock” signal. Pulse it HIGH the moment you want a new display to start. A few ms should be enough for the other Arduinos (which have nothing to do but waiting for that signal) to react.

If the time it takes the other Arduinos to process their thing you need a response: both set an output LOW, can be connected via diodes to a single input of the master, then when they’re done with their thing they set that output HIGH again. Master waits for the response input to go HIGH knowing all slaves are finished,.

If you want more than a fixed order, and want to start sending commands to the other Arduinos to say display specific images, it’s getting more complicated. You could use serial communcations for this - Tx of the master to the Rx of all slaves; send messages with address so the slaves know whether it’s for them. Can’t send messages back that way; don’t connect two or more Tx to one another.

First you connect all the Uno grounds then find one pin they all have open and connect those pins to one wire.

One Uno holds the signal pin HIGH until the button is pressed, then it pulls it LOW.
The other Unos watch the signal pin until it goes LOW.

Serial is a slow train moving through a crossing while your life ticks away by comparison.

Thank you all, some good places to start. I’ll update as I get the project going.

I’m using I2C for my devices. I read a bit about I2C used for two way comm. Is this feasible (considering I wll have 16 I2C devices)?

I2C is master/slave type of bidirectional communication. One bus supports up to 127 slaves, provided they all have different addresses.

I2C is send request, wait, get reply but good data rate possible and very flexible.

SPI is way faster but only one selected device transmits back to the master at a time, though many can read.

Using pins to transmit/receive single or group states using port manipulation, in a fraction of a microsecond. Unos can read/set 6 pin groups on 3 ports while Mega2560 has many ports with 8 pins open.

How fast can your Arduinos synchronize? How close do they need to be?
A loop in software that watches for that pin to change could take about 1 micro to run. It would be good in void setup().
A fast non-blocking void loop() could take 20 to 100 micros, the check would run 10 to 50 times a millisecond.

Arduino micros() low 2 bits are always 0. That 4 byte value gets updated every 4 microseconds, not every 1.

Arduino millis() skips 6 values out of every 256 to make the low 8 bits count 1/4 second. The low 8 bits will never == 0xFF or 5 other values. What that comes down to is that the (end - start) subtraction to get interval may be off depending on how many skipped steps both end and start have in their low 8 bits that still add up to 256.

If the interval matters, use micros(). Unsigned long micros() can time over 70 minutes to 4 usec ticks.

The “snowflakes” will be about 10 feet apart so real close sync is not necessary 100 uSec should be well within the range since a eye blink is something like 250 uSec. We shall see. This is all visual stuff so I have lots of leeway when it comes to synchronization.

It gets more possible. Try and keep the synch to within 10 millis which is still pretty wide in Arduino terms but much shorter than a sixteenth note.