Master/slave arduino nano's


I'm new to arduino, but having a lot of success working through the tutorials and examples.

I have a project I would like to do, which is basically a model level crossing controller.

I would have two Nano's, one as the master, controlling the light and motor sequence, and another Nano as a slave to provide alternating flashing of red LED's.

The slave Nano would have to respond to start and finish signals from the master nano.

Both Nano's would have common pos. and neg. supply.

How can I trigger the second (slave) nano to start and stop, as part of the sequence in the master Nano ?

(Could we keep it as simple as possible ? I'm still a novice)

Many thanks

P.S. Could I/Should I use an opto-coupler maybe ?

Hi Keith

I don’t see that you’ve run out of IO yet - so a single nano to do this entire task.

In crossings I see, there are lights in only 3 states - solid on (end of boomgates), and alternating flash (one of each type on the boomgates, one of each type on the road signals.

So while there are many LEDs potentially to flash, as you say they’re just alternating so you could control them all from three* digital IO pins on the nano, using a transistor or MOSFET such that the Arduino will be controlling them, but not powering them. You’ll then need other pins to control the servos for the boomgates and some kind of sensor for the oncoming train detection.

(Could we keep it as simple as possible ? I’m still a novice)

So yes I think you can simplify this down to one Nano, and maybe 3 transistors and resistors.

There’s lots of tutorials about using MOSFETs and transistors with Arduino - Nick Gammon’s page is informative. There’s a motor in those examples as the load but just replace that with your LEDs in parallel (with current limiting resistors) and remove the protection diode and you’ll have what you need.


  • Even two, but let’s keep it simple

Thanks for your input Geoff.

I have to be careful here. I must take into account that people on the forum are from many different nationalities.

The sequence for the British railway crossing is :

  1. Train initiates crossing operation.
  2. Amber light on. (A single amber light in each direction for road traffic)
  3. Pause 5 seconds.
  4. Amber light off.
  5. Alternating red lights flash.( Two, alternating, flashing reds in each direction to stop traffic)
  6. Pause 5 seconds.
  7. Barriers down (servo)

  8. Train clear of crossing.

  9. Barriers up.

  10. Pause 2 seconds.

  11. Red lights off.

I'm OK with everything here, from the point of view of writing the code..... fairly simple (famous last words !)

What I don't understand is how to maintain the red lights flashing whilst the same Nano is doing everything else ?

The red lights start flashing fairly early on in the sequence, and if they aren't able to remain flashing of their own accord, once we arrive at "6. Pause 5 seconds" they'll stop, because the code has moved to the next step.

I need some way of, for example, taking a pin high or low to initiate the red flashing lights, they continue doing that until I take the pin high or low again to stop the red lights at the end.

This is why I thought of having another Nano doing the flashing reds...... a waste of a Nano if there is another way.

For the simple Arduino boards, we use millis(). The function millis() returns the number of milliseconds that have been elapsed, but it can also be used to do several things at the same time as well. It requires that your sketch is specifically written for the use of millis().

There are more than ten ways to keep the red lights flashing. You should choose what you understand best.

A function that produces a tone with alternating pins is toneAC(). It can go as low as 1Hz. The leds can be connected to those pins instead of a speaker.

An interrupt could be used for the leds.

A preemtive schedular could be used. I'm testing at the moment, and it is awesome.

A state machine could be used.

Maintaining two sketches for two Arduino boards can be confusing as well. I agree with strykeroz of course, use one Nano and one sketch.

The best way to do this is with a state machine and millis(). That will be very straight forward, and can easily be changed and new things can be added. But if you want to try a shortcut with the toneAC(), then the sketch will be simple and small.

Hi again,

Many apologies on the interpretation of train crossings. I shouldn’t presume either :slight_smile: But the good news is nothing you’ve said here expands the project to need two microcontrollers.

To expand on the good advice already posted above, granted your alternating flashes don’t have to be synchronised with any external time, you can very simply get two LEDs alternately using modulo maths on the millis() value, doing something like this:

digitalWrite(LEDpin1, (millis() % 2000 > 1000));
digitalWrite(LEDpin2, (millis() % 2000 < 1000));

In this example if this code was in the loop() of your sketch they’d alternate every second (ie 1000 milliseconds).

A state machine could be used.

Agreed. Since you were able to explain the sequence of events in a list, that can be as simple as an integer value that keeps track of what step number (or, state) you are presently at. Each step in your list changes based either on the time since the sequence started, or the train clearing the crossing. At those intervals you’d increment that value. Your loop() part of the sketch will determine what the crossings should do now based on the present state and the millis() timer and the train trigger. Just add another state for “step 0, no train, do nothing” and you’ve got a defined thing for the code to be doing at every possible state.

Bottom line is this is very achieveable. All the best!

Many thanks guys.

I will go away and inwardly digest what you have said, and decide on the way to approach this.

Thanks again.


Keith_W: What I don't understand is how to maintain the red lights flashing whilst the same Nano is doing everything else?

But in fact the Nano is not "doing everything else".

You need to understand for one, that it is executing well over a million steps per second (where a "step" may itself include a number of things as it is clocked at 16 million steps per second). What proper code does not do is to "busy wait" on only one event at a time.

This means that it can sample many things, one after another, and take an action (or not) according to what it finds in each case. That is what the "loop" is for - it is not for going through the sequence that you have described, though that sequence is cyclical.

In fact, your sequence is performed by a switch or "state variable" which determines which step is in progress at any one time. So this actually enumerates your eleven steps - the state variable starts at step zero (the one you missed, waiting for a train) and counts through to eleven as each is completed.

And you have a second state variable which is the flashing step of the lights left or right, alternating. It steps from 0 to 1 and back again. A third switch variable determines whether they are flashing or not.

So your main loop() now begins by looking at the first state variable, let's call it "cross1". If it is zero, it checks to see whether a train is in section. If it is, it sets the variable to 1, if not it does nothing and in either case, it moves immediately on to the next section of the loop().

The loop now looks at the "flashes" state to see whether the lights should be flashing. If not, it moves on to the next section of the loop() but if that determines that they should, it then looks to see if a time has elapsed (by comparing the present millis() to that saved the last time the reds were alternated) to see whether to swap over the reds.

Since all this has taken only a few microseconds, the loop() is free to perform any number of other checks provided that whatever it does, can be completed within a few microseconds.

And then it cycles back to the beginning and at that point, the first step being to check "cross1". If it is now 1, then it sets it to 2, turns on the yellow light and makes a note of the present millis() value. The loop then proceeds through each of the other steps as before.

The next pass through the loop, it finds "cross1" to be 2 so it checks millis() to see if that value is yet 5000 (a "UL" or Unsigned Long figure to match millis() ) more than the value saved back in step 1. If not, as before it passes on to the next step in the loop(). If it has exceeded the five seconds, it sets "cross1" to three and turns off the yellow light.

Can you see the pattern at this point?

Noted further comments as I typed this:

Keith_W: I will go away and inwardly digest what you have said, and decide on the way to approach this.

There is nothing to decide. This is the way to approach it, you just have to learn the paradigm and you can do everything with the (one) Arduino. It will be quite a while doing operations as simple as this, before you run out of program memory or processor capability.