Go Down

Topic: Ignoring repeated IR codes in switch case (Read 2471 times) previous topic - next topic

UKHeliBob

Looking at the RiCino GitHub page it looks like it simply uses multiple IR detectors connected to the same Arduino pin as suggested earlier in the thread.  If so then getting it to work with one pin would be an imprtant first step.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

xxxWALDOxxx

https://github.com/cdemetriadis/RiCino-Lap-Counter/commit/e3c0adaf67c1b8dda2ba94aa57ea285e851d1e8e



above is a link that directs you to a github member who wanted to do the same thing with the zones.  He helped me get the zones part of the code working with a change in library.  Worked slick and continues to work.  I had to change my transponders to 8bit HEX which also helped out with the speed at which it transmitted the IR codes to the receiver.  My idea is to take the receiver bridge and use it to work this counter you are helping me with as well.  I figured I would start slow and get one working now and then add the other zones in later.  Obviously this was a BAAAAD idea to think that without bringing it up.  It was pretty simple to make the zone change with the Ricino receiver so I thought it would be fairly simple to change this code to make it work as well.  that's what I get for thinking.  When I get the chance to sit in front of my breadboard with the proto-typed counter, I will send something to get me started to see what your thoughts are on what I think might be a possible start.  I got the last code you sent to work with my segment display.  Have not done extensive testing, but seems to work.  Thanks for not giving up on me.

UKHeliBob

Quote
He helped me get the zones part of the code working with a change in library. 
Where can this revised library be downloaded from ?

There seems to be no mention of it on the RiCino GitHub page that you linked to
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

xxxWALDOxxx

I will try and attach the 2 libraries later this evening.  I am sure I am handling the libraries wrong, but there is one for sending and one for receiving.  I believe that the transponder has to be setup for 8bit HEX as well, so a standard remote control won't work, at least the way the library is setup right now.  But I will try and attach them to my next post.

xxxWALDOxxx

I just quickly went back to that Github page and grabbed the zip folder for the libraries that were used for the multi receiver setup.  When I was building and programming the receivers I copied and pasted the library into my IRremote folder, then removed it and replaced it with the transponder library the same way when building the transponder.  All worked well. and continues to impress.  Just hoping to adapt the same setup into the counter display.  Thanks again for your interest in helping me out.  The library folder is attached to this post.

xxxWALDOxxx

I took the latest code you wrote and adapted my iteration of 2 receivers using that code.  I will definitely say this is more than likely not the correct way by any means to do this, but it was a quick way to check the library I posted for multi receiver setup.  I just duplicated your original code with another instance of the decode_results2 for the second receiver and changed a few serial prints to show which receiver was receiving.  It worked, but again, I am sure this is so very wrong, but worked as a test.  I changed the library for 32 bits instead of the 8 that we used for our Ricino setup so I can use a standard remote for testing for now.  Here is what I did......okay, okay, hold the laughter. I'm trying.

Code: [Select]
#include "IRremote.h"

const byte receivePin = 12;
const byte receivePin2 = 10;

unsigned long currentCode;
unsigned long previousCode;
unsigned long currentCode2;
unsigned long previousCode2;
unsigned long currentTime;
unsigned long startTime;
unsigned long ignorePeriod = 5000;
boolean ignoreSameCode = false;

IRrecv irrecv(receivePin);
IRrecv irrecv2(receivePin2);

decode_results results;
decode_results results2;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn();
  irrecv2.enableIRIn();
}

void loop()
{
  currentTime = millis();
  if (irrecv.decode(&results))  //signal received
  {
    irrecv.resume();
    currentCode = results.value;  //get current code
    if (currentCode == 0xFFFFFFFF)
    {
      return;
    }
    debugReport();
    if (currentCode != previousCode || ignoreSameCode == false) //we have a new code
    {
      Serial.print("\t\tNew code : ");
      Serial.println(currentCode, HEX);
      startTime = currentTime;
      ignoreSameCode = true;
      Serial.println("Wait period started");
    }
    previousCode = currentCode; //save the previous code
  }
  if ((ignoreSameCode == true) && currentTime - startTime >= ignorePeriod)
  {
    ignoreSameCode = false;
    Serial.println("Wait period ended");
  }
  if (irrecv2.decode(&results2))  //signal received
  {
    irrecv2.resume();
    currentCode2 = results2.value;  //get current code
    if (currentCode2 == 0xFFFFFFFF)
    {
      return;
    }
    debugReport();
    if (currentCode2 != previousCode2 || ignoreSameCode == false) //we have a new code
    {
      Serial.print("\t\tNew code2 : ");
      Serial.println(currentCode2, HEX);
      startTime = currentTime;
      ignoreSameCode = true;
      Serial.println("Wait period started 2");
    }
    previousCode2 = currentCode2; //save the previous code
  }
  if ((ignoreSameCode == true) && currentTime - startTime >= ignorePeriod)
  {
    ignoreSameCode = false;
    Serial.println("Wait period ended 2");
  }
}
void debugReport()
{
  Serial.print("currentCode : ");
  Serial.println(currentCode, HEX);
  Serial.print("previousCode : ");
  Serial.println(previousCode, HEX);
  Serial.print("ignoreSameCode : ");
  Serial.println(ignoreSameCode == false ? "false" : "true");
  Serial.println();
}




again, I am sure you have better methods, especially for debugging this.  I had to bring the baud rate down from what you originally had, it just couldn't keep up with displaying all the received signals with as many as I was sending with my 8bit transponders.   Your thoughts?

I was doing some digging as always trying to research on my own and saw your post to other members in regards to using an array......waaaaay outta my league, I'm glad I was able to spark a little interest here though.  Thanks again for all the help on this UKHeliBob. MUCH appreciated.

xxxWALDOxxx

using the last code I posted and playing with ideas I came to a few new problems I am sure someone else can see long before it happened.  Using the multi receiver library I can get the 2 receivers to work, figured I would start with 2 and add more as I can refine the code.  But a couple problems I am unsure how to fix.  Considering I have 2 instances of the receivers, I am unsure of how to use the translate() function.  Now if both the receivers are receiving the same code it will translate twice which will initially add 2 laps at a time.  If I had the 4 receivers going it would add 4 laps.  Also noticing that when it receives a different code after the first viable saved code it will not go into ignore because it reads the different code.  With multiple receivers there is a chance of 4 different codes within milliseconds of each other and will continue getting lap counts until they are out of the IR sensor range. Any ideas?

Code: [Select]
#include "IRremote.h"

int receiver = 12; // Signal Pin of IR receiver to Arduino Digital Pin 12
int receiver2 = 10;
int receiver3 = 9;
int Blue = 11;
int Red = 7;

int lap_count1;
int lap_count2;

int latchPin = 4;
int clockPin = 5;
int dataPin = 3;

unsigned long StartMS;
unsigned long CurrentMS;
unsigned long LastIR;
unsigned long LastIR2;
unsigned long LastIR3;
unsigned long CurrentIR;
unsigned long CurrentIR2;
unsigned long CurrentIR3;
unsigned long ignorePeriod = 10000;
bool ignoreSameCode = false;
bool ignoreSameCode2 = false;



byte segdisp[10] = {          B11111100,
                              B01100000,
                              B11011010,
                              B11110010,
                              B01100110,
                              B10110110,
                              B10111110,
                              B11100000,
                              B11111110,
                              B11100110,
 
   };


/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);     // create instance of 'irrecv'
IRrecv irrecv2(receiver2);
IRrecv irrecv3(receiver3);
decode_results results;      // create instance of 'decode_results'
decode_results results2;
decode_results results3;

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("Ready to Detect");
  irrecv.enableIRIn(); // Start the receiver
  irrecv2.enableIRIn();
  irrecv3.enableIRIn();
  pinMode(Blue, OUTPUT);
  pinMode(Red, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  digitalWrite(latchPin, LOW);                        // send to 7 segment displays
  shiftOut(dataPin, clockPin, LSBFIRST, B11111100);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111100);                     
  digitalWrite(latchPin, HIGH);
   


}/*--(end setup )---*/



/*-----( Function )-----*/
void translateIR() {// takes action based on IR code received
  int a;
  int b;
  int c;
  int d;
  a = lap_count1%10;
  b = lap_count1/10;
  c = lap_count2%10;
  d = lap_count2/10;
 
 


{

  switch(results.value)  // describe IR codes and what they will do
 
  {
     
   
  case 0x13:
  // BLUE button on tape light remote
  Serial.println("Driver 1");
  digitalWrite(Blue, HIGH);
  lap_count1 ++;
  Serial.println("Lap");
  Serial.println(lap_count1);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, segdisp[a]);
  shiftOut(dataPin, clockPin, LSBFIRST, segdisp[b]);
  digitalWrite(latchPin, HIGH);
  digitalWrite(Blue, LOW);
  break;
     

  case 0x14:   
  // RED button on tape light remote
  Serial.println("Driver 2");
  digitalWrite(Blue, HIGH);
  lap_count2 ++;
  Serial.println("Lap");
  Serial.println(lap_count2);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, segdisp[c]);
  shiftOut(dataPin, clockPin, LSBFIRST, segdisp[d]);
  digitalWrite(latchPin, HIGH);
  digitalWrite(Blue, LOW);
  break;

  case 0xFFA25: Serial.println("Reset");   // Play/Pause button on tape light remote
  digitalWrite(Red, HIGH);
  lap_count1 = 0;
  lap_count2 = 0;
  Serial.println(lap_count1, lap_count2);
   digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111100);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111100);
  digitalWrite(latchPin, HIGH);
   delay(1000);
  digitalWrite(Red, LOW);
  break;
   

  default:
    digitalWrite(Red, HIGH);
    delay(5);
    digitalWrite(Red, LOW);

  }// End Case
}
}

void loop() {  /*----( LOOP: RUNS CONSTANTLY )----*/
 
  CurrentMS = millis();
  if (irrecv.decode(&results))  //signal received
  {
    irrecv.resume();
    CurrentIR = results.value;
    if (CurrentIR == 0xFFFFFFFF)
    {
      return;
    }
    debugReport();
    if (CurrentIR != LastIR || ignoreSameCode == false)   //we have a new code
    {
    Serial.print("\t\tNew code : ");
    Serial.println(CurrentIR, HEX);   
    StartMS = CurrentMS;
    ignoreSameCode = true;
    Serial.println("wait period started");
   
    }
    LastIR = CurrentIR;
  }
    if ((ignoreSameCode == true) && CurrentMS - StartMS >= ignorePeriod)
    {
      ignoreSameCode = false;
      Serial.println("wait period over");
  }
   if (irrecv2.decode(&results2))  //signal received
  {
    irrecv2.resume();
    CurrentIR2 = results2.value;
    if (CurrentIR2 == 0xFFFFFFFF)
    {
      return;
    }
    debugReport();
    if (CurrentIR2 != LastIR2 || ignoreSameCode2 == false)   //we have a new code
    {
    Serial.print("\t\tNew code : ");
    Serial.println(CurrentIR2, HEX);   
    StartMS = CurrentMS;
    ignoreSameCode2 = true;
    Serial.println("wait period started");
    translateIR();
    }
    LastIR2 = CurrentIR2;
  }
    if ((ignoreSameCode2 == true) && CurrentMS - StartMS >= ignorePeriod)
    {
      ignoreSameCode2 = false;
      Serial.println("wait period over");
  }
}
void debugReport()
{
Serial.print("currentCode : ");
  Serial.println(CurrentIR, HEX);
  Serial.print("previousCode : ");
  Serial.println(LastIR, HEX);
  Serial.print("ignoreSameCode : ");
  Serial.println(ignoreSameCode == false ? "false" : "true");
  Serial.println(); 
}

xxxWALDOxxx

After a little more playing around with the code I ended with the following which resulted in better translation yet still have the problem with the counting portion of the code.  Again, please suggest better options as I am sure I am handling the multi receiver part of this all wrong.  The program seems to work pretty well, but if this is indeed the right way to handle the multi receiver part of the code, by the time I type in for all 4 receivers it seems a little much.  Anyways, here is what I have to date.

Code: [Select]
#include "IRremote.h"

int receiver = 12; // Signal Pin of IR receiver to Arduino Digital Pin 12
int receiver2 = 10;
int receiver3 = 9;
int Blue = 11;
int Red = 7;

int lap_count1;
int lap_count2;

int latchPin = 4;
int clockPin = 5;
int dataPin = 3;

unsigned long StartMS;
unsigned long CurrentMS;
unsigned long LastIR;
unsigned long LastIR2;
unsigned long LastIR3;
unsigned long CurrentIR;
unsigned long CurrentIR2;
unsigned long CurrentIR3;
unsigned long ignorePeriod = 10000;
bool ignoreSameCode = false;
bool ignoreSameCode2 = false;



byte segdisp[10] = {          B11111100,
                              B01100000,
                              B11011010,
                              B11110010,
                              B01100110,
                              B10110110,
                              B10111110,
                              B11100000,
                              B11111110,
                              B11100110,
 
   };


/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);     // create instance of 'irrecv'
IRrecv irrecv2(receiver2);
IRrecv irrecv3(receiver3);
decode_results results;      // create instance of 'decode_results'
decode_results results2;
decode_results results3;

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("Ready to Detect");
  irrecv.enableIRIn(); // Start the receiver
  irrecv2.enableIRIn();
  irrecv3.enableIRIn();
  pinMode(Blue, OUTPUT);
  pinMode(Red, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  digitalWrite(latchPin, LOW);                        // send to 7 segment displays
  shiftOut(dataPin, clockPin, LSBFIRST, B11111100);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111100);                     
  digitalWrite(latchPin, HIGH);
   


}/*--(end setup )---*/



/*-----( Function )-----*/
void translateIR() {// takes action based on IR code received
  int a;
  int b;
  int c;
  int d;
  a = lap_count1%10;
  b = lap_count1/10;
  c = lap_count2%10;
  d = lap_count2/10;
 
 


{

  switch(results.value)  // describe IR codes and what they will do
 
  {
     
   
  case 0x13:
  // BLUE button on tape light remote
  Serial.println("Driver 1");
  digitalWrite(Blue, HIGH);
  lap_count1 ++;
  Serial.println("Lap");
  Serial.println(lap_count1);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, segdisp[a]);
  shiftOut(dataPin, clockPin, LSBFIRST, segdisp[b]);
  digitalWrite(latchPin, HIGH);
  digitalWrite(Blue, LOW);
  break;
     

  case 0x14:   
  // RED button on tape light remote
  Serial.println("Driver 2");
  digitalWrite(Blue, HIGH);
  lap_count2 ++;
  Serial.println("Lap");
  Serial.println(lap_count2);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, segdisp[c]);
  shiftOut(dataPin, clockPin, LSBFIRST, segdisp[d]);
  digitalWrite(latchPin, HIGH);
  digitalWrite(Blue, LOW);
  break;

  case 0xFFA25: Serial.println("Reset");   // Play/Pause button on tape light remote
  digitalWrite(Red, HIGH);
  lap_count1 = 0;
  lap_count2 = 0;
  Serial.println(lap_count1, lap_count2);
   digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111100);
  shiftOut(dataPin, clockPin, LSBFIRST, B11111100);
  digitalWrite(latchPin, HIGH);
   delay(1000);
  digitalWrite(Red, LOW);
  break;
   

  default:
    digitalWrite(Red, HIGH);
    delay(5);
    digitalWrite(Red, LOW);

  }// End Case
}
}

void loop() {  /*----( LOOP: RUNS CONSTANTLY )----*/
 
  CurrentMS = millis();
  if (irrecv.decode(&results) || irrecv2.decode(&results2))  //signal received
  {
    irrecv.resume();
    irrecv2.resume();
    CurrentIR = results.value;
    CurrentIR2 = results2.value;
    if (CurrentIR == 0xFFFFFFFF || CurrentIR2 == 0xFFFFFFFF)
    {
      return;
    }
    debugReport();
    if ((CurrentIR != LastIR || ignoreSameCode == false) || (CurrentIR2 != LastIR2 || ignoreSameCode2 == false))   //we have a new code
    {
    Serial.print("\t\tNew code : ");
    Serial.println(CurrentIR, HEX);
    Serial.println(CurrentIR2, HEX);   
    StartMS = CurrentMS;
    ignoreSameCode = true;
    ignoreSameCode2 = true;
    Serial.println("wait period started");
    translateIR();
    }
    LastIR = CurrentIR;
    LastIR2 = CurrentIR2;
  }
    if (((ignoreSameCode == true) && CurrentMS - StartMS >= ignorePeriod) || ((ignoreSameCode2 == true) && CurrentMS - StartMS >= ignorePeriod))
    {
      ignoreSameCode = false;
      ignoreSameCode2 = false;
      Serial.println("wait period over");
     
  }
   
}
void debugReport()
{
Serial.print("currentCode : ");
  Serial.println(CurrentIR, HEX);
  Serial.print("currentCode2 :");
  Serial.println(CurrentIR2, HEX);
  Serial.print("previousCode : ");
  Serial.println(LastIR, HEX);
  Serial.print("previousCode2 :");
  Serial.println(LastIR2, HEX);
  Serial.print("ignoreSameCode : ");
  Serial.println(ignoreSameCode == false ? "false" : "true");
  Serial.println(); 
}

xxxWALDOxxx

Hmmmm, UKHeliBob, did you lose hope in me?  It was great getting the help I got from you.  I will do whatever is needed to get this figured out.  Any help I can get is MUCH APPRECIATED!!!!

UKHeliBob

I have not lose hope in you but I have been away from home for a few days dealing with a family crisis and have lost track of where you are with your project.

As far as I can see from the page that you linked to all of the receivers are connected to the same pin so you only need to read the pin to determine whether a code has been received from any of the transmitters.  I only have one IR receiver so I cannot test this
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

xxxWALDOxxx

no worries, family is always first.

what I am working on now is what I think is the next step.  When I get to adding the multi receivers in the code I will still have the problem of the ignore time.  Let me  explain a little better.  If I receive code for truck 1, it goes into the ignore period as it should.  If...truck 2 passes through it goes into ignore as it should, but, since the IR code received is different, it cancels the ignore time for truck 1 and will detect before the ignore period is over.  Once I get to the multi receiver part of this, it means I can have multiple trucks being detected at the same time, if this is the case, the 2 trucks will be counted multiple times through one pass.  I need to find a solution to the ignore time not being contingent only by the codes being different.  It needs to ignore the same code regardless if the next code is different, or the same, for "X" seconds.

clear as mud?

UKHeliBob

Quote
It needs to ignore the same code regardless if the next code is different, or the same, for "X" seconds.
There is a way to do this but it will involve more code to achieve what you need.  In essence each truck needs its own ignore period and other truck specific data and a convenient way to do this is to store the truck ignore start time in an array.  However, array indices are integers starting at zero and the truck IDs are longs so you need to translate each truck ID into a unique integer starting at zero.  

If each truck ID differed from the next one by one then this would be easy because you could simply subtract the smallest ID form that received to get a number from 0 to numberOfTrucks - 1 and the result could be used as the index to an array (or struct) of data for each truck.  If the truck IDs are not so conveniently arranged then the next best option is probably a switch/case based on the long truck ID to assign an ID from 0 to numberOfTrucks - 1 and then use this ID to access the array or struct.

Assuming that you have a short ID for the currently detected truck then you can use it to read an array or struct to find out whether that truck is currently being ignored.  If not then save its ignore start time in the array and flag it as being currently ignored.  If it is being ignored check whether the ignore time has elapsed and if it has then change its status.

I would suggest using an array of structs to hold the truck data such as ignore status, ignore start time, lap count and perhaps fastest lap, slowest lap or whatever would be interesting.

I suggest that you ignore the output of data for now and use the Serial monitor.  A larger display can come later and that is best handled by a function called from loop() only if the information to be displayed has changed

PROBLEMS
All of the above is predicated to the assumption that multiple IR receivers attached to the same input pin can be read reliably.

It would be possible for 2 or more trucks to pass under the sensors at the same time but if the code in loop() is kept to a minimum with no delay()s or unnecessary output then you might be OK
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

xxxWALDOxxx

I will study your latest post in more detail tonight when I get in front of my sketch and prototype.  I pretty much disregarded the original code for updating and working with displays and I am just using the serial monitor for the time being. 

I feel this is getting me a much better understanding of how the code works as I am able to understand why the changes you suggest will give the results I need.

I wrote up a quick sketch using nothing but "if" statements using specified instructions on "if" it received the specific code to 2 trucks and got the ignore part working for each truck, but as you said, with 20 trucks running the code will get very messy and long.

Just a quick statement. My current sensor bridge is made up of about 100 IR sensors, each zone of 25 IR sensors are hooked up to different input pins on my NANO ....e.g.. 12,11,10,9.  The 25 sensors for each zone are then connected in parallel to create the large coverage area and is very accurate at this point.  I figured after I can get the whole ignore part of the code figured out I could then start figuring out the multi-receiver pins figured out.  Unless this just won't work.

The ignore part of the RiCino receiver is all handled in the race management software, otherwise I would use the suggested code from that project to reference for this new counter project. 

Again, thanks for your patience with me and thanks for helping me out so much.

UKHeliBob

Here is some code for you to play with
Code: [Select]
#include "IRremote.h"

const byte NUMBER_OF_TRUCKS = 4;

struct trucks
{
  unsigned long ignorePeriodStart;
  boolean ignoreTruckCode = false;
  int lapCount = 0;
  boolean reported = false;
} truckData[NUMBER_OF_TRUCKS];  //array of truck data structs

const byte receivePin = 12;
unsigned long IRCode;
unsigned long currentTime;
unsigned long ignorePeriod = 5000;
byte currentTruckNumber = 0;
byte previousTruckNumber = 99;
boolean showLaps = false;
IRrecv irrecv(receivePin);
decode_results results;

void setup()
{
  Serial.begin(115200);
  irrecv.enableIRIn();
}

void loop()
{
  currentTime = millis();
  if (irrecv.decode(&results))  //signal received
  {
    irrecv.resume();
    IRCode = results.value;  //get current code
    decodeTruckNumber();  //translate IR code to truck number
    if (currentTruckNumber == 255)  //invalid truck number
    {
      return;
    }
    if ((currentTruckNumber != previousTruckNumber) || (truckData[currentTruckNumber].ignoreTruckCode == false))
    {
      truckData[currentTruckNumber].lapCount++;
      showLaps = true;  //lap cpunt has changed
      truckData[currentTruckNumber].ignoreTruckCode = true;
      Serial.print("started ignoring truck number : ");
      Serial.println(currentTruckNumber);
      truckData[currentTruckNumber].ignorePeriodStart = currentTime;
      truckData[currentTruckNumber].reported = false;
      previousTruckNumber = currentTruckNumber; //save the previous truck number
    }
  }
  if (showLaps) //show the lap count only if it has changed
  {
    lapDisplay();
  }
  checkTimeouts();
}

void decodeTruckNumber()  //translate IR code to array index
{
  switch (IRCode)
  {
    case 0x008CC03F:
      currentTruckNumber = 0;
      break;
    case 0x008C20DF:
      currentTruckNumber = 1;
      break;
    case 0x008CA05F:
      currentTruckNumber = 2;
      break;
    case 0x008C609F:
      currentTruckNumber = 3;
      break;
    default:    //no valid code found
      currentTruckNumber = 255;
      break;
  }
}

void checkTimeouts()  //check whether any ignore periods have ended
{
  for (int truck = 0; truck < NUMBER_OF_TRUCKS; truck++)
  {
    if (truckData[truck].ignoreTruckCode == true)
    {
      if (currentTime - truckData[truck].ignorePeriodStart >= ignorePeriod)
      {
        truckData[truck].ignoreTruckCode = false;  //stop ignoring the truck
        if (truckData[truck].reported == false)
        {
          Serial.print("stopped ignoring truck number : ");
          Serial.println(truck);
          truckData[truck].reported = true;
        }//already reported
      }//period ended
    }//ignoring repeats
  }//for loop
}

void lapDisplay() //display the lap count for each truck
{
  Serial.println("LAP COUNT");
  Serial.println("---------");
  for (int truck = 0; truck < NUMBER_OF_TRUCKS; truck++)
  {
    Serial.print("Truck number ");
    Serial.print(truck);
    Serial.print(" : ");
    Serial.println(truckData[truck].lapCount);
  }
  showLaps = false;
}

It uses the ideas from my previous post and would almost certainly cope with one of your 25 detector zones using one input pin.  Extending it to multiple zones using the modified library should be possible if a little complicated
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

xxxWALDOxxx

wow, I hope that didn't take you too long to write for me, but it is much appreciated.  I haven't had the chance to study it, but a quick copy, paste, and upload shows that if the next code is different the ignore time is still not working.  Maybe you expected this.  I will hopefully have some time to dig into it and play with it to see if I can figure out what needs to be done to make the ignore work.  It ignores if it is the same code that comes through during the ignore period, but if it is a different code it basically cancels the ignore of the previous code.  I can bounce between the buttons on my remote and count it as fast as I can press back and forth on the buttons.

Go Up