Timing events across 2 Arduino controllers

Hello everybody,

I am very new to Arduino world and I have only just started learning it for a rather specific reason. I am wanting to create a sketch that will operate Drag racing staging lights. I have so far written below sketch and have a little prototype working on tinkercad circuit whilst I'm waiting for Arduino controller to come in mail.

Now, I would like to expand this sketch in a way where I will have a second Arduino with 2 more sonar sensors connected to my first Arduino. I would like it to capture time from when green lights light up on Arduino 1 and trigger the sonar sensors on Arduino 2. In effect showing me time spent of an object traveling between Arduino 1 and 2.

From what I understand I could somehow use Millis() for this, however I am unsure how to get Millis() synced over 2 Arduino controllers?

Any help you could provide me would be greatly appreciated and needed as I am currently out of ideas and am unsure of what to research to get the right answers.


!

/* Pin allocation */

#define stageLEDL  A5 //Left staging light
#define stageLEDR  5 //Right staging light
#define yellow1  A4 //first yellow row
#define yellow2  2 //second yellow row
#define yellow3  3 //third yellow row
#define greenLEDR  4 //green left go light
#define greenLEDL  A3 //green right go light
#define TRIGGERLS_PIN   8  //for left staging sensor
#define ECHOLS_PIN      9  //for left staging sensor 
#define TRIGGERRS_PIN   12 //for left staging sensor 
#define ECHORS_PIN      13 //for left staging sensor
#define SWITCH_PIN 		11 //switch pic alocation

int echoTimeLS;             //time in us
int distanceLS;           //distance in mms

int echoTimeRS;				//time in us
int distanceRS;			  //distance in mms


void setup()
{
  /* Pin I/O allocation */
  
  //Serial.begin(9600);
  pinMode(SWITCH_PIN, INPUT);
  
  //LEDS
  
  pinMode(stageLEDL, OUTPUT);
  pinMode(stageLEDR, OUTPUT);
  pinMode(yellow1, OUTPUT);
  pinMode(yellow2, OUTPUT);
  pinMode(yellow3, OUTPUT);
  pinMode(greenLEDR, OUTPUT);
  pinMode(greenLEDL, OUTPUT);
  
  //Staging Sensors
  
  pinMode(TRIGGERLS_PIN, OUTPUT);
  pinMode(ECHOLS_PIN, INPUT);
  digitalWrite(TRIGGERLS_PIN, LOW);     //set trigger pin LOW - idle state
  
  pinMode(TRIGGERRS_PIN, OUTPUT);		//same as above but for right staing sensor
  pinMode(ECHORS_PIN, INPUT);
  digitalWrite(TRIGGERRS_PIN, LOW);
}

void loop()
{
 
  stagingSensors();
  
  if (digitalRead(SWITCH_PIN) == HIGH)
  {
             
         
            //LEDS
            if (digitalRead(stageLEDL) == HIGH && (digitalRead(stageLEDR) == HIGH)) 
            {
            delay(3000);						 //staging lights delay
            digitalWrite(yellow1, HIGH);  	 //first yellow row on and off
            delay(1000);
            digitalWrite(yellow1, LOW);
            digitalWrite(yellow2, HIGH); 	 	 //second yellow row on and off
            delay(1000);
            digitalWrite(yellow2, LOW);
            digitalWrite(yellow3, HIGH); 		 //third yellow row on and off
            delay(1000);
            digitalWrite(yellow3, LOW);
 			stagingSensors();
                if (digitalRead(stageLEDL) == HIGH )
                {  
                digitalWrite(greenLEDL, HIGH); 	 //green left go lights on
                }

                if (digitalRead(stageLEDR) == HIGH )
                {  
                digitalWrite(greenLEDR, HIGH); 	 //green left go lights on  
                }
            delay(2000);  
            digitalWrite(greenLEDL, LOW);
            digitalWrite(greenLEDR, LOW);
            digitalWrite(stageLEDL, LOW);
            digitalWrite(stageLEDR, LOW);
            }  
  }
}
/* This is staging sensors left and right constant check function */

void stagingSensors()
{
  /* Left lane staging sensor */
  digitalWrite(TRIGGERLS_PIN, HIGH);    //send trigger pulse
  delayMicroseconds(10);
  digitalWrite(TRIGGERLS_PIN, LOW);
  echoTimeLS = pulseIn(ECHOLS_PIN, HIGH); //capture the echo signal and determine duration of pulse when HIGH
  distanceLS = (echoTimeLS*0.034*10)/2;    //obtain distance (in mm), from time
  
  /* Right lane staging sensor */
  digitalWrite(TRIGGERRS_PIN, HIGH);    //send trigger pulse
  delayMicroseconds(10);
  digitalWrite(TRIGGERRS_PIN, LOW);
  echoTimeRS = pulseIn(ECHORS_PIN, HIGH); //capture the echo signal and determine duration of pulse when HIGH
  distanceRS = (echoTimeRS*0.034*10)/2;    //obtain distance (in mm), from time
  
  /* Distance sensitivity of the sonar sensors in mm */
  
  if (distanceLS >= 200 &&  distanceLS <=2000)
  {
    digitalWrite(stageLEDL, HIGH);
  } else {
    digitalWrite(stageLEDL, LOW);
  }
  
  if (distanceRS >= 200 &&  distanceRS <=2000)
  {
    digitalWrite(stageLEDR, HIGH);
  } else {
    digitalWrite(stageLEDR, LOW);
  }   
}

Make the second Arduino respond with its "local time" millis() on the start message. Then calculate the time difference and use it to translate all subsequent times.

If you suspect a considerable time lag in transmissions then determine the travel time by sending a message and check how many millis it takes until the answer arrives. This will give the time for 2 transmissions, hence and forth, so that the delay between an event and the arrival of the event message on the other system is half that measured delay.

How far apart will the two Arduinos be?

For the testing purposes I am just connecting them through wire.h library and they will only be about a meter apart until I get the sketch to perform the timing. In the long run I was hoping to use wifi modules on both Arduinos to talk to each other.

When the light goes green, send something, anything over the wire/wifi to Arduino2. Have it be looping waiting for that message and when it arrives, store millis. Store millis in another variable when the sonar sees something.

There's the means to calculate your elapsed time. It can be transmitted back to Arduino1 if necessary.

I will start experimenting with this right away! So to dumb it down for myself; I would run millis on Arduino2 then send it to Arduino1 where I would grab the remote millis and take away from Arduino1 millis. Which in turn would leave me with time difference between the two? then depending if its positive or negative I would plus or minus this difference from all subsequent times?

Understood about testing 1 metre apart but how far apart will they be in practice ? If nothing else it will influence which wireless technology you use

You mention WiFi. Will both of the Arduinos be in range of the same WiFi router ?

Just go the easy way. Sync each Arduino to a good time source (such as connecting a GPS module to each Arduino). Then, at the start of the race, capture the current time at Arduino 1. At the end of the race, capture the current time at Arduino 2. Subtract the two times and you got travel time between A and B. This works with Arduinos that are a meter apart, or 10 kms apart.

Its a valid approach if the 'race' less than one second, you can use the GPS PPS output to start a timer.

For longer races, appreciate that two GPSs even 1M apart can report times (as in hours\mins\seconds) that are different by 1 - 2 seconds, possibly more.

Yes :slight_smile:

I was thinking of utilizing NRF24L01 modules for both Arduinos, in the perfect world I would like them to be 40m apart and hopefully still be in signal range of each other. As it will be in an open environment with no buildings to interfere

if (digitalRead(stageLEDL) == HIGH )
                {  
                digitalWrite(greenLEDL, HIGH); 	 //green left go lights on
                Wire.beginTransmission(4); // transmit to device #8
                Wire.write("GLedL");        // sends five bytes
                Wire.endTransmission();    // stop transmitting  
                }

so far I am able to send this to the Arduino2, and receive and print to serial using

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop(){
}

void receiveEvent(int howMany){
  while(Wire.available() > 0) // loop through all but the last
  {
       char a = Wire.read(); // receive byte as a character
    	Serial.print(a);
    delay(10);
  }
delay(500);
}

Now, i am struggling to assign anything i send to the slave to a variable where I could use it in an IF statement.. for example if led = "GLedL" then capture millis. How would i go about that?

No need to be so complicated. Just send 'G'. Then you can test it with:

if(a=='G')