Slot Car Timer with 2 interrupts - inserting LED problems

I have successfully completed my main goal, which was to build a 2 lane Slotcar Timer. I tried a few and learned quite a bit, but eventually realized the need for ISR and INPUT_PULLUP. I found one in German which was good because I translated it line for line and really got an idea of how things worked. I had to swap items around to get the declarations in right places for 2020. I was able to get a unique LED to flash for each lane when the car crossed the line, but I cheated, and left the variable world the OP had created to do this in newb fashion.

Where i am at is this. Each lane has 3 LEDs. I have initialized them in two arrays. I need to assign each array to a specific lane, so when lap calculations are being compiled it happens automatically in the variables. (I think). I made many efforts to flash an LED whenever a new fast lap was acheived, but any sort of digitalWrite in the middle of the calculation made results go whacky. I could get the light to come on, but the fast lap data would not process correctly. (I got a hint when the 1st car would pass, it would flash the fastlap light for both lanes the 1st time!)

 if (lapTime[i] < lapRecord[i])
      // led code here
      lapRecord[i] = lapTime[i];

seems easy enough but I have tried many things, and it just doesn't want me to put a function in there. I even tried splitting the code and removing * and replacing with the value, but that gets wonky if both lanes trigger. Can I make the LED array assignable? and can I do anything with that lap calculation?*
Thank you for any ideas in advance.
*Here is the entire sketch. *
```
*#include <Wire.h> // Library for I2C communication
#include <LiquidCrystal_I2C.h> // Library for LCD
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

int LEDPIN0[] = {9, 7, 8};
int LEDPIN1[] = {12, 10, 11};
//int ledGroup[] = {0,1} == {LEDPIN0, LEDPIN1} ?? how would I do this? THIS!!
int pinCount = 3;

#define SLOTS 2
// Minimum lap time in milliseconds, interpreting everything below as contact bouncing
#define MINROUNDTIME 3000

// Pins for connecting the laser sensors (D2, D3)
byte laserPins[] = {2, 3};
// Interrupt-Numbers for these pins
byte pinInterrupts[] = {0, 1};

// Start of the last round in milliseconds, volatile because access is also from ISR!
volatile long roundStart[] = {0, 0};
//Lap time of the last lap in milliseconds
long lapTime[] = {0, 0}; //lap time
// Lap time of the fastest lap in milliseconds
long lapRecord[] = {15000, 15000}; //lap time record
//  Lap Counter
int lapNumber[] = {0, 0};

// Interrupt (treatment routines)

void timing1()
{
  if (millis() - roundStart[0] > MINROUNDTIME)
    roundStart[0] = millis();
}

void timing2()
{
  if (millis() - roundStart[1] > MINROUNDTIME)
    roundStart[1] = millis();
}

void (*isrFunctions[])() = { timing1, timing2 };

void setup() {
  lcd.init();
  lcd.backlight();
  // Initialize laser sensor and ISR routines
  for (int i = 0; i < SLOTS; i++)
  {
    pinMode(laserPins[i], INPUT_PULLUP);
    attachInterrupt(pinInterrupts[i], isrFunctions[i], HIGH);
  }
  for (int thisPin = 0; thisPin < pinCount; thisPin++)
  {
    pinMode(LEDPIN0[thisPin], OUTPUT);
    pinMode(LEDPIN1[thisPin], OUTPUT);
  }

lcd.setCursor(4, 0);
  lcd.print("Suitcase");
  lcd.setCursor(4, 1);
  lcd.print("Speedway");
  delay(3000);
  lcd.clear();
}

//void ProcessLapTimes() //Process lap times

void NumberofLaps() //Show number of laps
{ static long lastUpdate;
  char lcdline[17];
  // Update display only every 500 ms
  if (millis() / 500 == lastUpdate) return;
  lastUpdate = millis() / 500;
  for (int i = 0; i < SLOTS; i++)
  {
    snprintf(lcdline, sizeof(lcdline), "Lane%d  Lap %5d  ", i + 1, lapNumber[i]);
    lcd.setCursor(0, i);
    lcd.print(lcdline);
  }
}

void ShowLapTimes() //Show lap times
{ static long lastUpdate;
  long thisLap, thisRecord;
  char lcdline[17];
  int ltime[4];
  // Update display only every 500 ms
  if (millis() / 500 == lastUpdate) return;
  lastUpdate = millis() / 500;
  for (int i = 0; i < SLOTS; i++)
  {

// Lap time and fastest lap time in hundredths of a lap
    thisLap = (lapTime[i] + 5) / 10;  // lap time
    thisRecord = (lapRecord[i] + 5) / 10;  // lap time record
    ltime[0] = thisLap / 100; // whole seconds
    ltime[1] = thisLap % 100; // hundredths of second
    ltime[2] = thisRecord / 100; // whole seconds
    ltime[3] = thisRecord % 100; // hundredths of second
    snprintf(lcdline, sizeof(lcdline), "%d%3d.%02d  %3d.%02d", i + 1, ltime[0], ltime[1], ltime[2], ltime[3]);
    lcd.setCursor(0, i);
    lcd.print(lcdline);
  }
}

void loop()
{
  //ProcessLapTimes(); // process lap times
  // Start of the penultimate round in milliseconds
  static long RoundProcessed[] = {0, 0};
  long curMillis;
  // Note the current status of the millis () function
  curMillis = millis();
  // Check all slots for changes in the round start time
  for (int i = 0; i < SLOTS; i++)
  {
    if  (RoundProcessed[i] != roundStart[i])
    { // New lap since the last loop run
      lapNumber[i]++; // Round counters high counts
      // Determine lap time
      lapTime[i] = roundStart[i] - RoundProcessed[i];

// Determine if it was the fastest lap
      if (lapTime[i] < lapRecord[i])
      // can I do anything here?  i need this calculation before next line!  THIS!
      lapRecord[i] = lapTime[i];

// In the end, mark this lap time as processed
      RoundProcessed[i] = roundStart[i];

}
  }

if ((millis() / 2000) % 2 == 1)
    ShowLapTimes(); // show lap times
  else
    NumberofLaps(); // show number of laps

//  flash the green led when you cross the line  (see how I cheated?)
  if (millis() - roundStart[0] < 200)
    digitalWrite(LEDPIN0[0], HIGH);
  else
    digitalWrite(LEDPIN0[0], LOW);
  if (millis() - roundStart[1] < 200)
    digitalWrite(LEDPIN1[0], HIGH);
  else
    digitalWrite(LEDPIN1[0], LOW);

//delay(50);
// digitalWrite(LEDPIN0[1], LOW);
// digitalWrite(LEDPIN1[1], LOW);
}*
```

Once I get this sorted out, I have plans for creating a Race Mode where you can select number of laps, etc. The entire project has been 3d printed, and soldered to a nano, and properly done! The switches are even wired (to 5 and 6). So if you are wondering what I was planning to do with the 3rd LEDs, they all will also be used in a start light sequence down the road. As i said, I am past the original goal, but the little things I need to add, are really just a few lines of code away. I AM really trying to solve it all myself, but this is the point where I can ask, and I might actually understand you.

One last thing, I even tried using math formulas from the variables at the very end of the loop, but unless there is a trick way to flag those variables while they are in their loops, I can't reliably use any of them in the main loop. Is this a job for * ??

Are you doing this?

if (lapTime[i] < lapRecord[i])
      // led code here
      lapRecord[i] = lapTime[i];

or this?

if (lapTime[i] < lapRecord[i])
{
   // led code here
   lapRecord[i] = lapTime[i];
}

How about this for your arrays?

const int SLOTS = 2;
const int pinCount = 3;
int ledGroup[SLOTS][pinCount] = {{9, 7, 8}, {12, 10, 11}};

Thank you Todd. Yes to the first two, neither worked. However, your last one looks like the ticket! I will not get to try it out just yet as there are some other steps to add now you have sent me in the direction I was after. I think now I will be able to include a digitalWrite in the calculation as the LED array will be part of the variable set... well I hope so anyway.

Thank you a bunch for the input, and i'll be sure to reply back with what I find.

Ben

Todd, your Array is perfect! Thank you for showing me how to do that!

As I expected, when I put the line in between the math, it still didn't work, but then this was now possible, and works like a charm. (I probably could have made this work the old way, too, but now the solution is evident, it seems much clearer now.

      if (lapTime[i] < lapRecord[i])
      lapRecord[i] = lapTime[i];
      if (lapRecord[i] == lapTime[i])
      digitalWrite(LEDGROUP[i][1], HIGH);

now onto "Race Mode"

Ben

bsuitcase:
Todd, your Array is perfect! Thank you for showing me how to do that!

As I expected, when I put the line in between the math, it still didn't work, but then this was now possible, and works like a charm. (I probably could have made this work the old way, too, but now the solution is evident, it seems much clearer now.

      if (lapTime[i] < lapRecord[i])

lapRecord[i] = lapTime[i];
      if (lapRecord[i] == lapTime[i])
      digitalWrite(LEDGROUP[i][1], HIGH);




now onto "Race Mode"

Ben

This is equivalent:

      if (lapTime[i] < lapRecord[i])
      {
         lapRecord[i] = lapTime[i];
         digitalWrite(LEDGROUP[i][1], HIGH);
      }

ToddL1962:
This is equivalent:

      if (lapTime[i] < lapRecord[i])

{
        lapRecord[i] = lapTime[i];
        digitalWrite(LEDGROUP[i][1], HIGH);
      }

Not quite. If lapRecord[ i ] is already equal to lapTime[ i ], the if statement is false, but you still want the output to go HIGH.

david_2018:
Not quite. If lapRecord[ i ] is already equal to lapTime[ i ], the if statement is false, but you still want the output to go HIGH.

True. Pardon my haste. Thanks for pointing that out.

It might be functionally equivalent depending on the logic for turning the LED off therefore it depends on how the code is structured.

I looked at this, thought I got it, then I thought about it for a bit, then my head started to hurt!


new question.

When I am planning "race mode" I (eventually)plan on creating a race calculation "void" and I assume, I use 'If' loops in the main loop, to differentiate between the current and racing modes?

Would I still be able to use most of the same timing variables, when doing race calculations? For example, the current run mode of logging laps and fast laps, will still be pertinent to racing, I would just need to put the two values at odds with each other and create booleen expressions for the winner I imagine.