Stopwatch for Pinewood Derby

Ok here’s some code that kind of works… lol. I think there may be an issue with the noInterrupts() / interrupts() functions. Or the way I’m implementing things… The first results seem good, but then the more you run it the more it flakes a bit. Some of the start/end times get very short like some bouncing of the inputs is re-triggering. I’m not seeing how unless interrupts are queuing up and firing again as soon as interrupts() is run… Not sure, but feel free to play. I’ll keep looking at it:

#include "application.h"

void lane1(void);
void lane2(void);
void lane3(void);
void lane4(void);
int ledPin = D7;
volatile int state = LOW;
volatile uint32_t timeStart1;
volatile uint32_t timeStart2;
volatile uint32_t timeStart3;
volatile uint32_t timeStart4;
volatile uint32_t timeEnd1;
volatile uint32_t timeEnd2;
volatile uint32_t timeEnd3;
volatile uint32_t timeEnd4;

void setup()
{
  Serial.begin(115200);
  while(!Serial.available()) SPARK_WLAN_Loop();

  Serial.println("Waiting for all four inputs to CHANGE...\n");
  timeStart1 = micros(); // reset!
  timeStart2 = timeStart1;
  timeStart3 = timeStart1;
  timeStart4 = timeStart1;
  timeEnd1 = timeStart1;
  timeEnd2 = timeStart1;
  timeEnd3 = timeStart1;
  timeEnd4 = timeStart1;

  // D0, D1, D2, D3, D4
  // A0, A1, A3, A4, A5, A6, A7
  pinMode(ledPin, OUTPUT);
  
  pinMode(D0, INPUT_PULLUP);
  pinMode(D1, INPUT_PULLUP);
  pinMode(D2, INPUT_PULLUP);
  pinMode(D3, INPUT_PULLUP);
  //pinMode(D4, INPUT_PULLUP);
  //pinMode(A0, INPUT_PULLUP);
  //pinMode(A1, INPUT_PULLUP);
  
  //pinMode(A3, INPUT_PULLUP);
  //pinMode(A4, INPUT_PULLUP);
  //pinMode(A5, INPUT_PULLUP);
  //pinMode(A6, INPUT_PULLUP);
  //pinMode(A7, INPUT_PULLUP);
  
  attachInterrupt(D0, lane1, FALLING);
  attachInterrupt(D1, lane2, FALLING);
  attachInterrupt(D2, lane3, FALLING);
  attachInterrupt(D3, lane4, FALLING);
  //attachInterrupt(D4, blink, CHANGE);
  //attachInterrupt(A0, blink, CHANGE);
  //attachInterrupt(A1, blink, CHANGE);
  
  //attachInterrupt(A3, blink, CHANGE);
  //attachInterrupt(A4, blink, CHANGE);
  //attachInterrupt(A5, blink, CHANGE);
  //attachInterrupt(A6, blink, CHANGE);
  //attachInterrupt(A7, blink, CHANGE);
}

void loop()
{
  digitalWrite(ledPin, state);

  // still needs a timeout...
  if(timeEnd1 != timeStart1 && timeEnd2 != timeStart2 && timeEnd3 != timeStart3 && timeEnd4 != timeStart4) {
  	
  	Serial.println("======= Lane Times in seconds =======");
  	Serial.print("Lane 1: "); 
  	Serial.print(timeEnd1); Serial.print(" "); 
  	Serial.print(timeStart1); Serial.print(" "); Serial.println((double)(timeEnd1 - timeStart1)/1000000.0,6);

  	Serial.print("Lane 2: "); 
  	Serial.print(timeEnd2); Serial.print(" "); 
  	Serial.print(timeStart2); Serial.print(" "); Serial.println((double)(timeEnd2 - timeStart2)/1000000.0,6);

  	Serial.print("Lane 3: "); 
  	Serial.print(timeEnd3); Serial.print(" "); 
  	Serial.print(timeStart3); Serial.print(" "); Serial.println((double)(timeEnd3 - timeStart3)/1000000.0,6);

  	Serial.print("Lane 4: "); 
  	Serial.print(timeEnd4); Serial.print(" "); 
  	Serial.print(timeStart4); Serial.print(" "); Serial.println((double)(timeEnd4 - timeStart4)/1000000.0,6);
  	
  	// prevent false triggering from last input bouncing while we reset
  	noInterrupts();
  	delay(5000); // this is much longer than it needs to be... 
  	timeStart1 = micros(); // reset!
  	timeStart2 = timeStart1;
  	timeStart3 = timeStart1;
  	timeStart4 = timeStart1;
  	timeEnd1 = timeStart1;
  	timeEnd2 = timeStart1;
  	timeEnd3 = timeStart1;
  	timeEnd4 = timeStart1;
  	interrupts(); // go!
  	Serial.println("\n\nWaiting for all four inputs to CHANGE...\n");
  	
  }
}

void lane1()
{
  // if not captured already, save time.
  // this inherently debounces the input.
  if(timeEnd1 == timeStart1) timeEnd1 = micros();
  state = !state;
}

void lane2()
{
  // if not captured already, save time.
  // this inherently debounces the input.
  if(timeEnd2 == timeStart2) timeEnd2 = micros();
  state = !state;
}

void lane3()
{
  // if not captured already, save time.
  // this inherently debounces the input.
  if(timeEnd3 == timeStart3) timeEnd3 = micros();
  state = !state;
}

void lane4()
{
  // if not captured already, save time.
  // this inherently debounces the input.
  if(timeEnd4 == timeStart4) timeEnd4 = micros();
  state = !state;
}

Just take a wire connected to GND and poke the D0, D1, D2, D3 holes on the breadboard to act as the trigger.