1

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();
}
1
  • Does the timer count at all? Show us an image of what u see on your LCD and in the serial monitor Apr 3 '16 at 13:23
1

Of course not - your timer() function is blocking meaning that it does not return, and so does not permit anything else to execute, until its timing is completely done.

You will need to re-design your program. Some options include:

1) Capturing an initial timestamp from millis() and comparing to it on each iteration through loop() to decide when your time has approximately elapsed, and to update the display with an appropriate value if that point is not yet reached. This is probably the best choice for your application, but be aware that after about 50 days of uptime, the difference calculation can be briefly incorrect, unless you account for overflow.

2) Place a short delay in the main loop (maybe 100 ms), and count iterations of the main loop until you have reached your desired time. Beware though that your effective time will become longer if other parts of the loop take time (especially variable amounts of it) to execute.

3) Set up an event timer in the background with interrupts. This is a lot more complex and probably not advisable in your application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.