Arduino countdown timer preventing rest of program running

I have a program that checks to see if an RFID tag has been read, if it has, it runs some code.

I also have a count down timer function (timer) that I'd like to run in the background. It displays the clock on the bottom of the LCD.

The problem I'm having is that when I put timer(); in the main loop, the rest of the program is delayed for the duration of the count down which means that no RFID cards are read.

The timer works, but nothing below timer(); is running. I assume this is because of the use of delay.

Does anyone know how I can prevent this? Thank you.

  #include <SPI.h>      
#include <MFRC522.h>  
#include <Wire.h>
#include <LiquidCrystal_I2C.h>


int readflag;
int initstate = 1;

int nextred = 4;
int nextblue = 8;

uint8_t readCard[4];           

int minutes = 1; //start min
int seconds = 0; //start seconds


MFRC522 mfrc522(10, 9);
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


///////////////////////////////////////// Setup ///////////////////////////////////
void setup() {

    //Protocol Configuration
  Serial.begin(9600);  
  SPI.begin();           
  mfrc522.PCD_Init();    
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);

  lcd.begin(20, 4);


}


///////////////////////////////////////////////////////////////////////////////
  // Main loop
///////////////////////////////////////////////////////////////////////////////
void loop () {

 do {                                                             
   readflag = checkread(); 
if (initstate == 0) {
  timer(); //start timer - timer works but nothing below timer(); is running.
   lcd.setCursor(0,0);
   lcd.print("Red team next: ");
   lcd.print(nextred);
    lcd.setCursor(0,1);
    lcd.print("Blue team next: ");
    lcd.print(nextblue);

}
  }
  while (!readflag); 
  tone(8, 850, 15);
  recordid();
  updatenextteamnumbers();
}


///////////////////////////////////////////////////////////////////////////////
  // Function to update team next numbers
///////////////////////////////////////////////////////////////////////////////
void updatenextteamnumbers() {
//If Blue Tag scanned show team info
  if (*((uint32_t *)readCard) == 0xACB7D573) {

    Serial.println("Blue Tag detected, showing team info");
    initstate=0;

   }


//Red Team (sequence 4, 5, 2, 1, 9)
else if (*((uint32_t *)readCard) == 0x29FDC9F5 && initstate == 0) {
    Serial.println("CARD 4 detected");
    nextred = 5;

      }

else if (*((uint32_t *)readCard) == 0x3FCE7832 && initstate == 0) {

    Serial.println("CARD 5 detected");
    nextred = 2;

}

else if (*((uint32_t *)readCard) == 0x3FCCECE2 && initstate == 0) {

    Serial.println("CARD 2 detected");
    nextred = 1;

      }


  else if (*((uint32_t *)readCard) == 0x3F7AB752 && initstate == 0) {

    Serial.println("CARD 1 detected");
    nextred = 9;

    //activateredrelay

      }


  else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {

    Serial.println("CARD 9 detected");
    redwins();    

      }



//Blue Team (sequence 8, 6, 3, 7, 10)

else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {
    Serial.println("CARD 8 detected");
    nextblue = 6;

      }

else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {

    Serial.println("CARD 6 detected");
    nextblue = 3;

}

else if (*((uint32_t *)readCard) == 0x3F7ABA82 && initstate == 0) {

    Serial.println("CARD 3 detected");
    nextblue = 7;

      }


  else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {

    Serial.println("CARD 7 detected");
    nextblue = 10;

    //activatebluerelay

      }


  else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {

    Serial.println("CARD 10 detected");
    bluewins();    

      }

 }


///////////////////////////////////////////////////////////////////////////////
  // Stores the ID of the card that's been detected in readCard byte array
///////////////////////////////////////////////////////////////////////////////
void recordid() {
    mfrc522.PICC_IsNewCardPresent();
    mfrc522.PICC_ReadCardSerial();

    for (int i = 0; i < mfrc522.uid.size; i++) { 
        readCard[i] = mfrc522.uid.uidByte[i];  
        Serial.print(mfrc522.uid.uidByte[i], HEX);
        }
Serial.println("");
    mfrc522.PICC_HaltA();
  }


/////////////////////////////////////////////
  // Returns 1 if a card has been detected
/////////////////////////////////////////////
int checkread() {
   if ( ! mfrc522.PICC_IsNewCardPresent()) { 
    return 0; }                                        //no card detected

    mfrc522.PICC_HaltA(); 
    return 1; }                                       //card detected


/////////////////////////////////////////////
  // Runs if red team wins
/////////////////////////////////////////////
void redwins() {
      lcd.clear();
      lcd.setCursor(0,0); 
      lcd.print("Red team wins!");
      lcd.display();
      Serial.println("Red team wins!");
      delay(36000);
}

 /////////////////////////////////////////////
  // Runs if blue team wins
/////////////////////////////////////////////
void bluewins() {
      lcd.clear();
      lcd.setCursor(0,0); 
      lcd.print("Blue team wins!");
      lcd.display();
      Serial.println("Blue team wins!");
      delay(36000);
}


 /////////////////////////////////////////////
  // Count down timer
/////////////////////////////////////////////
void timer() {
lcd.setCursor(0,3);
  lcd.print("Time left:");
 while (minutes > 0 || seconds >= 0) {
  lcd.setCursor(15, 3);
 (minutes < 10) ? lcd.print("0") : NULL;
 lcd.print(minutes);
 lcd.print(":");
 (seconds < 10) ? lcd.print("0") : NULL;
 lcd.print(seconds);
 lcd.display();
 decrement();
 delay(1000);
 }
}

 /////////////////////////////////////////////
  // Decrement timer
/////////////////////////////////////////////
void decrement() {
      if (seconds > 0) {
          seconds -= 1;
      } 
      else      {
         if (minutes > 0) {
           seconds = 59;
           minutes -= 1;
          } 
          else  {
            timeup();
          }
       }
}

 /////////////////////////////////////////////
  // Called when time expires
/////////////////////////////////////////////
void timeup() {
      lcd.clear();
      lcd.setCursor(0,0); 
      lcd.print("Time up!");
      lcd.display();
}

Not surprising since you have a delay() in your timer.

Have a look at BlinkWithOutDelay, which is a non-blocking approach.

There's a library called elapsedMillis which is probably what you want. It's basically the BlinkWithOutDelay approach in a box.

Thanks, I've given that a go.

However, regardless where I put the call to the function containing millis (i.e. this LED flash one) it does not run properly.

The LED is always on in this case.

  #include <SPI.h>      
#include <MFRC522.h>  
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#include <elapsedMillis.h>

elapsedMillis timeElapsed;

int readflag;
int initstate = 1;

int nextred = 4;
int nextblue = 8;

uint8_t readCard[4];           

int minutes = 1; //start min
int seconds = 0; //start seconds


MFRC522 mfrc522(10, 9);
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


///////////////////////////////////////// Setup ///////////////////////////////////
void setup() {

    //Protocol Configuration
  Serial.begin(9600);  
  SPI.begin();           
  mfrc522.PCD_Init();    
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);

  lcd.begin(20, 4);

pinMode(1, OUTPUT);     

}


///////////////////////////////////////////////////////////////////////////////
  // Main loop
///////////////////////////////////////////////////////////////////////////////
void loop () {

flash();

 do {                                                             
   readflag = checkread(); 
if (initstate == 0) {
  
   lcd.setCursor(0,0);
   lcd.print("Red team next: ");
   lcd.print(nextred);
    lcd.setCursor(0,1);
    lcd.print("Blue team next: ");
    lcd.print(nextblue);

}
  }
  while (!readflag); 
  tone(8, 850, 15);
  recordid();
  updatenextteamnumbers();
}


///////////////////////////////////////////////////////////////////////////////
  // Function to update team next numbers
///////////////////////////////////////////////////////////////////////////////
void updatenextteamnumbers() {
//If Blue Tag scanned show team info
  if (*((uint32_t *)readCard) == 0xACB7D573) {

    Serial.println("Blue Tag detected, showing team info");
    initstate=0;

   }


//Red Team (sequence 4, 5, 2, 1, 9)
else if (*((uint32_t *)readCard) == 0x29FDC9F5 && initstate == 0) {
    Serial.println("CARD 4 detected");
    nextred = 5;

      }

else if (*((uint32_t *)readCard) == 0x3FCE7832 && initstate == 0) {

    Serial.println("CARD 5 detected");
    nextred = 2;

}

else if (*((uint32_t *)readCard) == 0x3FCCECE2 && initstate == 0) {

    Serial.println("CARD 2 detected");
    nextred = 1;

      }


  else if (*((uint32_t *)readCard) == 0x3F7AB752 && initstate == 0) {

    Serial.println("CARD 1 detected");
    nextred = 9;

    //activateredrelay

      }


  else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {

    Serial.println("CARD 9 detected");
    redwins();    

      }



//Blue Team (sequence 8, 6, 3, 7, 10)

else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {
    Serial.println("CARD 8 detected");
    nextblue = 6;

      }

else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {

    Serial.println("CARD 6 detected");
    nextblue = 3;

}

else if (*((uint32_t *)readCard) == 0x3F7ABA82 && initstate == 0) {

    Serial.println("CARD 3 detected");
    nextblue = 7;

      }


  else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {

    Serial.println("CARD 7 detected");
    nextblue = 10;

    //activatebluerelay

      }


  else if (*((uint32_t *)readCard) == 0x00000000 && initstate == 0) {

    Serial.println("CARD 10 detected");
    bluewins();    

      }

 }


///////////////////////////////////////////////////////////////////////////////
  // Stores the ID of the card that's been detected in readCard byte array
///////////////////////////////////////////////////////////////////////////////
void recordid() {
    mfrc522.PICC_IsNewCardPresent();
    mfrc522.PICC_ReadCardSerial();

    for (int i = 0; i < mfrc522.uid.size; i++) { 
        readCard[i] = mfrc522.uid.uidByte[i];  
        Serial.print(mfrc522.uid.uidByte[i], HEX);
        }
Serial.println("");
    mfrc522.PICC_HaltA();
  }


/////////////////////////////////////////////
  // Returns 1 if a card has been detected
/////////////////////////////////////////////
int checkread() {
   if ( ! mfrc522.PICC_IsNewCardPresent()) { 
    return 0; }                                        //no card detected

    mfrc522.PICC_HaltA(); 
    return 1; }                                       //card detected


/////////////////////////////////////////////
  // Runs if red team wins
/////////////////////////////////////////////
void redwins() {
      lcd.clear();
      lcd.setCursor(0,0); 
      lcd.print("Red team wins!");
      lcd.display();
      Serial.println("Red team wins!");
      delay(36000);
}

 /////////////////////////////////////////////
  // Runs if blue team wins
/////////////////////////////////////////////
void bluewins() {
      lcd.clear();
      lcd.setCursor(0,0); 
      lcd.print("Blue team wins!");
      lcd.display();
      Serial.println("Blue team wins!");
      delay(36000);
}

boolean ledState = LOW;
unsigned int interval = 1000;

void flash() {
 if (timeElapsed > interval) 
  {        
      ledState = !ledState;         // toggle the state from HIGH to LOW to HIGH to LOW ... 
      digitalWrite(1, ledState);
      timeElapsed = 0;              // reset the counter to 0 so the counting starts over...
  }
  
}

Rather frustrating, maybe it's not possible to have a counter and this rfid reader at the same time?

What board do you use? On most Arduinos pin 1 is one of the serial port pins and hence your code might not work.

If pin 1 is indeed the correct pin, have you studied the library? The 'problem' with libraries is that if your code doesn't work as expected, you have to study the library to understand it so you know what you're doing wrong in your code or to find the bug in the library.