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

1 Answer 1

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.

answered Apr 3, 2016 at 15:24

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.