NFC module and a 10 second countdown timer

Dear people,

I'm trying to build a alarm that uses nfc tags. The nfc tags need to be introduced to the nfc card reader within 10 seconds after the door has opened. if not, the relays will switch and the alarm/lights will go crazy.

I have been trying for a good 3 hours to get the 10 seconds timer to work, but I just can't get it to work. I did my research on millis() and the example codes. I need to be able to use the card reader and let the timer count up to 10 at the same time (for obvious reasons).
Whatever I do, the relays always switch after 1 second after I opened the door (sensor).

please, can someone help me?

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3) 

// Or use this line for a breakout or shield with an I2C connection:
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

const int sensor = 8;       // door sensor input pin
int doorstate;              // 0 close - 1 open wwitch
int state;                  // statemachine

//this is for the blinking led:
const int ledPin =  LED_BUILTIN;        // the number of the LED pin
int ledState = LOW;                     // ledState used to set the LED
unsigned long previousMillis = 0;       // will store last time LED was updated
const long interval = 1000;             // interval at which to blink (milliseconds)

//this is for the alarm timer:
// I have no idea...

void setup(void) 
{
   timeStart = 0;
   pinMode(4, OUTPUT);     // sets the digital pin 4 as output for relay 1
   pinMode(5, OUTPUT);     // sets the digital pin 5 as output for relay 2  
   pinMode(6, OUTPUT);     // sets the digital pin 6 as output RED LED
   pinMode(7, OUTPUT);     // sets the digital pin 7 as output GREEN LED
   pinMode(13, OUTPUT);    // sets the digital pin 13 as output TEST LED
   pinMode(sensor, INPUT_PULLUP);  // sets pullup resistor on for sensor
   state = 1;              // starts machine with first state
}

void loop (void)
{  
   
   if (state == 1)
   {      
      digitalWrite(4, HIGH);  // turn relay 1 off
      digitalWrite(5, HIGH);  // turn relay 2 off
      Serial.begin(115200);
      Serial.println("Hello!");
      Serial.println("Alarmsystem booting up");
      Serial.println("Alarm status: UNARMED");
      Serial.println("Alarm will be armed when door is closed");
      
      for (int i = 0; i <= 1; i++) // 10 seconds bootup (when set to 9)
      {
         digitalWrite(7, HIGH);  // turn green light on
         delay(500);
         digitalWrite(7, LOW);  // turn green light off
         digitalWrite(6, HIGH);  // turn red light on 
         delay(500);
         digitalWrite(6, LOW);  // turn red light off
      }       
      doorstate = digitalRead(sensor); // check the status of the door (open or closed)
      while (doorstate == HIGH)        // door OPENED
      {
         doorstate = digitalRead(sensor); // check the status of the door (open or closed)
         if (doorstate == HIGH)        // door OPENED
         {
            Serial.println("Door is opened");
            delay(1000); 
         }
      }
      Serial.println("Door is closed");
      Serial.println("Alarmsystem booted");         
      state = 2;
   }      
   else if (state == 2) 
   {
      unsigned long currentMillis = millis(); //fancy light flashing while idle (nothing is happening and alarm is armed)
      if (currentMillis - previousMillis >= interval) 
      {  
         previousMillis = currentMillis;
         if (ledState == LOW) 
         {
            ledState = HIGH;
         } 
         else 
         {
            ledState = LOW;
         }  
         digitalWrite(6, ledState);
      }
      doorstate = digitalRead(sensor); // check the status of the door (open or closed)
      if (doorstate == HIGH)        // door OPENED
      {
         Serial.println("Door is opened");
         digitalWrite(6, LOW);  // turn red light off
         nfc.begin();
         
         uint32_t versiondata = nfc.getFirmwareVersion();
         if (! versiondata) {
            Serial.print("Didn't find PN53x board");
            while (1); // halt
         }
         // Got ok data, print it out!
         Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
         Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
         Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
         
         // configure board to read RFID tags
         nfc.SAMConfig();         
         Serial.println("Waiting for an ISO14443A Card ...");
         
         
         //----------the countdown (or countup) for the NFC scanner----------
         
         if (?????????? ) //if the NFC tag is not scanned in time (10 sec.)
         { 
            Serial.println("NFC not detected or too late");
            Serial.println("ALARM TRIGGERD");         
            Serial.println("Activating light and horn");
            digitalWrite(4, LOW);  // turn relay 1 on
            digitalWrite(5, LOW);  // turn relay 2 on        
         }
         
         uint8_t success;
         uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
         uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
         uint8_t mifareclassic_ReadDataBlock;
         
         // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
         // 'uid' will be populated with the UID, and uidLength will indicate
         // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
         success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
         
         if (success) {
            // Display some basic information about the card
            Serial.println("Found an ISO14443A card");
            Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
            Serial.print("  UID Value: ");
            
            nfc.PrintHex(uid, uidLength);
            
            if (uidLength == 4)
            {
               // We probably have a Mifare Classic card ... 
               uint32_t cardid = uid[0];
               cardid <<= 8;
               cardid |= uid[1];
               cardid <<= 8;
               cardid |= uid[2];  
               cardid <<= 8;
               cardid |= uid[3]; 
               Serial.print("Seems to be a Mifare Classic card #");
               Serial.println(cardid);
               
               //------------------Checking if the nfc card is matching with data base entrys------------------//
               
               if (cardid == 2861708310)
               {
                  digitalWrite(13, HIGH);  // sets the digital pin 13 on
                  Serial.println("Detected card id:");
                  Serial.println(cardid);
                  Serial.println("NFC card: 1");
                  Serial.println("Alarm has been Dissarmed");
                  state = 3;
               }
               else if (cardid == 2864376086)
               {
                  digitalWrite(13, HIGH);  // sets the digital pin 13 on
                  Serial.println("Detected card id:");
                  Serial.println(cardid);
                  Serial.println("NFC card: 2");
                  Serial.println("Alarm has been Dissarmed");
                  state = 3;
               }
               else if (cardid == 3403313686)
               {
                  digitalWrite(13, HIGH);  // sets the digital pin 13 on
                  Serial.println("Detected card id:");
                  Serial.println(cardid);
                  Serial.println("NFC card: 3");
                  Serial.println("Alarm has been Dissarmed");
                  state = 3;
               }
               else if (cardid == 2863228950)
               {
                  digitalWrite(13, HIGH);  // sets the digital pin 13 on
                  Serial.println("Detected card id:");
                  Serial.println(cardid);
                  Serial.println("NFC card: 4");
                  Serial.println("Alarm has been Dissarmed");
                  state = 3;
               }
               else if (cardid == 3392821014)
               {
                  digitalWrite(13, HIGH);  // sets the digital pin 13 on
                  Serial.println("Detected card id:");
                  Serial.println(cardid);
                  Serial.println("NFC card: 5");
                  Serial.println("Alarm has been Dissarmed");
                  state = 3;
               }               
            }             
         }
      }
   }
   else if (state == 3)
   {
      digitalWrite(7, HIGH);  // turn green light on
      delay(500);
      Serial.println("Waiting for door to be closed again...");
      doorstate = digitalRead(sensor);
      if (doorstate == LOW)        // door CLOSED
      {
         Serial.println("Door is closed");
         Serial.println("Alarm status: ARMED");
         state = 2;
         digitalWrite(7, LOW);  // turn green light off
      }      
      
   }
   else if (state == 4) 
   {
      
   }
}

You coded everything inside loop.

You should divide your code into mutliple functions where each function does one thing.

read NFC-tag

compare tag-number with allowed tag-numbers

check doorstatus

check if 10 seconds are over since door was opened.

and last but not least instead of nesting if and else-if-conditions a state-machine will clear up things a lot.

So there a some things you have to learn
here is my epxlanation of how non-blocking timing based on millis() works
as an everyday example with easy to follow numbers
delay() is blocking. As long as the delay is "delaying" nothing else of the code can be executed.
Now there is a technique of non-blocking timing.
The basic principle of non-blocking timing is fundamental different from using delay()

You have to understand the difference first and then look into the code.

otherwise you might try to "see" a "delay-analog-thing" in the millis()-code which it really isn't
Trying to see a "delay-analog-thing" in millis() makes it hard to understand millis()
Having understood the basic principle of non-blocking timing based on millis() makes it easy to understand.

imagine baking a frosted pizza
the cover says for preparation heat up oven to 200°C
then put pizza in.
Baking time 10 minutes

You are estimating heating up needs 3 minutes
You take a look onto your watch it is 13:02 (snapshot of time)
You start reading the newspaper and from time to time looking onto your watch
watch shows 13:02. 13:02 - 13:02 = 0 minutes passed by not yet time
watch shows 13:03. 13:03 - 13:02 = 1 minute passed by not yet time
watch shows 13:04. 13:04 - 13:02 = 2 minutes passed by not yet time

watch shows 13:05 when did I start 13:02? OK 13:05 - 13:02 = 3 minutes time to put pizza into the oven

New basetime 13:05 (the snapshot of time)
watch 13:06 not yet time
watch 13:07 not yet time
watch 13:08 not yet time (13:08 - 13:05 = 3 minutes is less than 10 minutes
watch 13:09 not yet time
watch 13:10 not yet time
watch 13:11 not yet time
watch 13:12 not yet time
watch 13:13 not yet time
watch 13:14 not yet time (13:14 - 13:05 = 9 minutes is less than 10 minutes
watch 13:15 when did I start 13:05 OK 13:15 - 13:05 = 10 minutes time to eat pizza (yum yum)

You did a repeated comparing how much time has passed by
This is what non-blocking timing does

In the code looking at "How much time has passed by" is done

currentTime - startTime >= bakingTime

bakingTime is 10 minutes

13:06 - 13:05 = 1 minute >= bakingTime is false
13:07 - 13:05 = 2 minutes >= bakingTime is false
...
13:14 - 13:05 = 9 minutes >= bakingTime is false
13:15 - 13:05 = 10 minutes >= bakingTime is TRUE time for timed action!!

So your loop() is doing

void loop()
// doing all kinds of stuff like reading the newspaper

if (currentTime - previousTime >= period) {
previousTime = currentTime; // first thing to do is updating the snapshot of time
// time for timed action
}

it has to be coded exactly this way because in this way it manages the rollover from Max back to zero
of the function millis() automatically

baldengineer.com has a very good tutorial about timing with function millis() too .

There is one paragraph that nails down the difference between function delay() and millis() down to the point:

The millis() function is one of the most powerful functions of the Arduino library. This function returns the number of milliseconds the current sketch has been running since the last reset. At first, you might be thinking, well that’s not every useful! But consider how you tell time during the day. Effectively, you look at how many minutes have elapsed since midnight. That’s the idea behind millis()!

Instead of “waiting a certain amount of time” like you do with delay(), you can use millis() to ask “how much time has passed”?

And here is is an example how state-machines work

I'm really interested in feed-back if you found these things understandable or what questions where left unanswered for you.

best regards Stefan

1 Like

Wow. First of all: thank you so much for your extensive reply! This really gives me hope to continue my project. I am a first year electrical engineer and I am a little familiar with coding, but i'm a bit scared to do things I don't quit know yet. I seemed to get away with the code I presented until well... I read your message very carefully and I am now studying the websites you send me. I will come back with better, more organized code a soon as possible!

edit: the thing I do find difficultis to create a snapshot of the millis. How am I supposed to do that?

This is now my current process.
good things: i made functions and i think i did the switch case thing good.

bad things:
it won't compile...

edit: now it does compile, had some stray curly brackets and had to make some variables global.

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3) 

// Or use this line for a breakout or shield with an I2C connection:
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

const int sensor = 8;       // door sensor input pin
int state;                  // statemachine state 
int door;                   // doorstate 0 closed or 1 open
bool tagdata;
unsigned long cardid;       //nfc tag cardid

//this is for the blinking led:
int ledState = LOW;                     // ledState used to set the LED
unsigned long previousMillis = 0;       // will store last time LED was updated
const long interval = 1000;             // interval at which to blink (milliseconds)

//this is for the alarm timer:
int counter; 
bool flag;


void setup(void) 
{
   pinMode(4, OUTPUT);     // sets the digital pin 4 as output for relay 1
   pinMode(5, OUTPUT);     // sets the digital pin 5 as output for relay 2  
   pinMode(6, OUTPUT);     // sets the digital pin 6 as output RED LED
   pinMode(7, OUTPUT);     // sets the digital pin 7 as output GREEN LED
   pinMode(13, OUTPUT);    // sets the digital pin 13 as output TEST LED
   pinMode(sensor, INPUT_PULLUP);  // sets pullup resistor on for sensor
   state = 1;              // starts machine with first state
}

void loop (void)
{  
   state = 1;
   switch (state)
   {
      case 1:
         digitalWrite(4, HIGH);  // turn relay 1 off
         digitalWrite(5, HIGH);  // turn relay 2 off
         Serial.begin(115200);
         Serial.println("Hello!");
         Serial.println("Alarmsystem booting up");
         Serial.println("Alarm status: UNARMED");
         Serial.println("Alarm will be armed when door is closed");
         
         for (int i = 0; i <= 1; i++) // 10 seconds bootup (when set to 9)
         {
            digitalWrite(7, HIGH);  // turn green light on
            delay(500);
            digitalWrite(7, LOW);  // turn green light off
            digitalWrite(6, HIGH);  // turn red light on 
            delay(500);
            digitalWrite(6, LOW);  // turn red light off
         }   
         checkdoorstate();
         if (door = 0)
         {
            Serial.println("Door is closed");
            Serial.println("Alarmsystem booted");         
            state = 2;
         } 
         break;
      case 2:
         blinkingled();
         checkdoorstate();
         if (door = 1)
         {
            Serial.println("Door is opened");
            digitalWrite(6, LOW);  // turn red light off
            nfcstart();
            checktag();
            if (tagdata  = true)   // if a tag has been recognized
            {
               Serial.println("Alarm has been Dissarmed");
               digitalWrite(7, HIGH);  // turn green light on
               Serial.println("Waiting for door to be closed again...");
               state = 3;    
            }
            if (flag = true) // If the ten second timer is over. Alarm will go off
            {
               Serial.println("NFC not detected or too late");
               Serial.println("ALARM TRIGGERD");         
               Serial.println("Activating light and horn");
               state = 4;
            }   
            break; 
      case 3: 
               checkdoorstate();
               if(door = 0) // if the door is closed
               { 
                  Serial.println("Door is closed");
                  Serial.println("Alarm status: ARMED");
                  digitalWrite(7, LOW);  // turn green light off
                  state = 2;
               }
            case 4:
               digitalWrite(4, LOW);  // turn relay 1 on
               digitalWrite(5, LOW);  // turn relay 2 on 
               delay (3000); // alarm goes wild for 3 seconds.
               counter = 0; // reset counter   
               state = 1;   // reboot system    
               break;
            default:
               break;
         }
   }
}   
int checkdoorstate()
{
   int doorstate;
   doorstate = digitalRead(sensor); // check the status of the door (open or closed)
   
   if (doorstate == HIGH)        // door OPENED 
   {
      door = 1; //door is open
   } 
   else 
   {
      door = 0; // door is closed
   }
   return door;
}

void blinkingled()
{
   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis >= interval) 
   {  
      previousMillis = currentMillis;
      if (ledState == LOW) 
      {
         ledState = HIGH;
      } 
      else 
      {
         ledState = LOW;
      }  
      digitalWrite(6, ledState);
   }
}

void nfcstart() // start of nfc system
{
   nfc.begin();    
   uint32_t versiondata = nfc.getFirmwareVersion();
   if (! versiondata) 
   {
      Serial.print("Didn't find PN53x board");
      while (1); // halt
   }
   // Got ok data, print it out!
   Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
   Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
   Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
   
   // configure board to read RFID tags
   nfc.SAMConfig();         
   Serial.println("Waiting for an ISO14443A Card ...");
   uint8_t success;
   uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
   uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
   uint8_t mifareclassic_ReadDataBlock;
   
   // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
   // 'uid' will be populated with the UID, and uidLength will indicate
   // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
   success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
   
   if (success)  // if a nfc tag has been detected
   {
      // Display some basic information about the card
      Serial.println("Found an ISO14443A card");
      Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
      Serial.print("  UID Value: ");
      
      nfc.PrintHex(uid, uidLength);
      
      if (uidLength == 4)
      {
         // We probably have a Mifare Classic card ... 
         uint32_t cardid = uid[0];
         cardid <<= 8;
         cardid |= uid[1];
         cardid <<= 8;
         cardid |= uid[2];  
         cardid <<= 8;
         cardid |= uid[3]; 
         Serial.print("Seems to be a Mifare Classic card #");
         Serial.println(cardid);
         return cardid;
      }
   }  
}
bool checktag() // checks the nfc tag database for matches.
{
   if (cardid == 2861708310)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 1");
      tagdata = true;
      return tagdata;
   }
   else if (cardid == 2864376086)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 2");
      tagdata = true;
      return tagdata;
   }
   else if (cardid == 3403313686)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 3");
      tagdata = true;
      return tagdata;
   }
   else if (cardid == 2863228950)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 4");
      tagdata = true;
      return tagdata;
   }
   else if (cardid == 3392821014)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 5");
      tagdata = true;
      return tagdata;
   }
}

bool starttensecondstimer() // starts ten second timer and returns flag when 10 seconds are over.
{
   flag = true;
   counter = 0;
   unsigned long currentMillis = millis(); // grab current time     
   if ((unsigned long)(currentMillis - previousMillis) >= interval)  // check if "interval" time has passed (1000 milliseconds) 
   {
      counter ++;
      Serial.println(counter);
      previousMillis = millis();
      if (counter > 9) // reset timer afer 10 seconds 
      {
         counter = 0;
         flag = true;
         return flag;
      }
   }
}


you declare a one variable of type unsigned long.
The usual name for it is "currentTime"

unsigned long currentTime ;

This is a 4-byte variable 4 * 8 = 32 bit

the function millis() will count up to 2^32 = 4.294.967.296 within around 49,5 days and then reach the max number and "rollover to zero counting up again.
As long as you do calculations with unsigned long substraction works to the right result

1 - 4.294.967.296 results in 1
2 - 4.294.967.296 results in 2 etc.

If you need more smpashots of time you declare another variable each of type unsigend long

unsigned long buttonPressTime;
unsigned long StartLEDOnTime;

the value of currentTime gets updated through

void loop {
  currentTime = millis();
...

for each purpose you need a timing for

further down inside loop you assign

buttonPressTime = currentTime;

StartLEDOnTime = currentTime;

etc.

best regards Stefan

I think I may have accomplished that with my last code I just send, correct me if i'm wrong.
This was my prototype code for that:

unsigned long interval=1000; // the time we need to wait
unsigned long previousMillis=0; // millis() returns an unsigned long.
unsigned long counter ;
bool flag;

void setup() {
   Serial.begin(115200);
   // initialize the pushbutton pin as an input: 
   pinMode(7, OUTPUT);     // sets the digital pin 7 as output GREEN LED
}

void loop() 
{
   starttensecondstimer();
}

bool starttensecondstimer()
{ 
   unsigned long currentMillis = millis(); // grab current time         
   // check if "interval" time has passed (1000 milliseconds)
   if ((unsigned long)(currentMillis - previousMillis) >= interval) 
   {
      counter ++;
      Serial.println(counter);
      previousMillis = millis();   
      if (counter > 9) // reset timer afer 10 seconds 
      {
         counter = 0;
         flag = true;
         return flag;
      }
   }
}


the code doesn't do anything yet with the flag though. Also, resetting the flag is a bit difficult I noticed.

Well it is always the same; information is the key
Click into the the bottom part of the arduino-IDE where all the messages run through if you compile or upload

press Ctrl-A to mark all lines
press Ctr-C to copy all marked into the clipboard.

Change to user-forum

click on the </>-button and then without pressing any other key
press Ctrl-V to insert the content of the clipboard into a posting as a code-section.

you can start searching for the error yourself be searching for the lines with a ": error:"

colon - space error ": error"
There are two numbers in such lines first is the line of code and the second the columm where the compile-error occured.

best regards Stefan

If you define a variable inside a function the value gets lost each time the function is exited.

To keep a value all the time the variable has to be declared outside any function

unsigned long currentTime;

void loop {
.... 
}

As a consequence: all functions "see" the same variable because the variable is declared global.

For learning more of this you should use much smaller demo-codes that do just one thing.

best regards Stefan

Got it.
Btw, got the code working now, updated my previous long code if you want to see it. Now the code runs but it gets stuck in this part: it doesn't run the whole case strangely:

      case 1:
         digitalWrite(4, HIGH);  // turn relay 1 off
         digitalWrite(5, HIGH);  // turn relay 2 off
         Serial.begin(115200);
         Serial.println("Hello!");
         Serial.println("Alarmsystem booting up");
         Serial.println("Alarm status: UNARMED");
         Serial.println("Alarm will be armed when door is closed");
         
///the part below is not working yet it seems/////

         for (int i = 0; i <= 1; i++) // 10 seconds bootup (when set to 9)
         {
            digitalWrite(7, HIGH);  // turn green light on
            delay(500);
            digitalWrite(7, LOW);  // turn green light off
            digitalWrite(6, HIGH);  // turn red light on 
            delay(500);
            digitalWrite(6, LOW);  // turn red light off
         }   
         checkdoorstate();
         if (door = 0)
         {
            Serial.println("Door is closed");
            Serial.println("Alarmsystem booted");         
            state = 2;
         } 
         break;

or maybe it does, but it does not respond to the led blinking part or the door sensor.
update: nevermind... my red led was just dead. The only part not working is the door sensor. or maybe it just doens't wanna jump to case 2 for some reason.

as a basic rule: post always your complete code

How should I know how your function checkdoorstate() looks now?
You might have modified it
best regards Stefan

I could, but my code is pretty long. I didn't wanna spam. I'm gonna test a bit more, then i'll reply.

I want to to show you how to add debug-output to your code.

If you post code by using code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy for forum"
  3. paste clipboard into write-window of a posting

then it is not "spammy" because the code-section has a limited height

about the door sensor.
I just tested the sensor with my simpelest code and it worked:

const int sensor = 8;
int state; // 0 close - 1 open wwitch

void setup()
{
  pinMode(13, OUTPUT);    // sets the digital pin 13 as output TEST LED
  pinMode(sensor, INPUT_PULLUP);
}void loop()
{
  state = digitalRead(sensor);
  
  if (state == HIGH){
    digitalWrite(13, HIGH);  // sets the digital pin 13 on
  }
  else{
    digitalWrite(13, LOW);  // sets the digital pin 13 off;
  }
  delay(100);
}

With my new/ main alarm code it doens't:

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3) 

// Or use this line for a breakout or shield with an I2C connection:
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

const int sensor = 8;       // door sensor input pin
int state;                  // statemachine state 
int door;                   // doorstate 0 closed or 1 open
bool tagdata;
unsigned long cardid;       //nfc tag cardid

//this is for the blinking led:
int ledState = LOW;                     // ledState used to set the LED
unsigned long previousMillis = 0;       // will store last time LED was updated
const long interval = 1000;             // interval at which to blink (milliseconds)

//this is for the alarm timer:
int counter; 
bool flag;


void setup(void) 
{
   pinMode(4, OUTPUT);     // sets the digital pin 4 as output for relay 1
   pinMode(5, OUTPUT);     // sets the digital pin 5 as output for relay 2  
   pinMode(6, OUTPUT);     // sets the digital pin 6 as output RED LED
   pinMode(7, OUTPUT);     // sets the digital pin 7 as output GREEN LED
   pinMode(13, OUTPUT);    // sets the digital pin 13 as output TEST LED
   pinMode(sensor, INPUT_PULLUP);  // sets pullup resistor on for sensor
   state = 1;              // starts machine with first state
}

void loop (void)
{  
   state = 1;
   switch (state)
   {
      case 1:
         digitalWrite(4, HIGH);  // turn relay 1 off
         digitalWrite(5, HIGH);  // turn relay 2 off
         Serial.begin(115200);
         Serial.println("Hello!");
         Serial.println("Alarmsystem booting up");
         Serial.println("Alarm status: UNARMED");
         Serial.println("Alarm will be armed when door is closed");
         
         for (int i = 0; i <= 1; i++) // 10 seconds bootup (when set to 9)
         {
            digitalWrite(7, HIGH);  // turn green light on
            delay(500);
            digitalWrite(7, LOW);  // turn green light off
            digitalWrite(6, HIGH);  // turn red light on 
            delay(500);
            digitalWrite(6, LOW);  // turn red light off
         }   
         checkdoorstate();
         if (door = 0)
         {
            Serial.println("Door is closed");
            Serial.println("Alarmsystem booted");         
            state = 2;
         } 
         break;
      case 2:
         blinkingled();
         checkdoorstate();
         if (door = 1)
         {
            Serial.println("Door is opened");
            digitalWrite(6, LOW);  // turn red light off
            nfcstart();
            checktag();
            if (tagdata  = true)   // if a tag has been recognized
            {
               Serial.println("Alarm has been Dissarmed");
               digitalWrite(7, HIGH);  // turn green light on
               Serial.println("Waiting for door to be closed again...");
               state = 3;    
            }
            if (flag = true) // If the ten second timer is over. Alarm will go off
            {
               Serial.println("NFC not detected or too late");
               Serial.println("ALARM TRIGGERD");         
               Serial.println("Activating light and horn");
               state = 4;
            }   
            break; 
      case 3: 
               checkdoorstate();
               if(door = 0) // if the door is closed
               { 
                  Serial.println("Door is closed");
                  Serial.println("Alarm status: ARMED");
                  digitalWrite(7, LOW);  // turn green light off
                  state = 2;
               }
            case 4:
               digitalWrite(4, LOW);  // turn relay 1 on
               digitalWrite(5, LOW);  // turn relay 2 on 
               delay (3000); // alarm goes wild for 3 seconds.
               counter = 0; // reset counter   
               state = 1;   // reboot system    
               break;
            default:
               break;
         }
   }
}   
int checkdoorstate()
{
   int doorstate;
   doorstate = digitalRead(sensor); // check the status of the door (open or closed)
   
   if (doorstate == HIGH)        // door OPENED 
   {
      door = 1; //door is open
   } 
   else 
   {
      door = 0; // door is closed
   }
   return door;
}

void blinkingled()
{
   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis >= interval) 
   {  
      previousMillis = currentMillis;
      if (ledState == LOW) 
      {
         ledState = HIGH;
      } 
      else 
      {
         ledState = LOW;
      }  
      digitalWrite(6, ledState);
   }
}

void nfcstart() // start of nfc system
{
   nfc.begin();    
   uint32_t versiondata = nfc.getFirmwareVersion();
   if (! versiondata) 
   {
      Serial.print("Didn't find PN53x board");
      while (1); // halt
   }
   // Got ok data, print it out!
   Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
   Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
   Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
   
   // configure board to read RFID tags
   nfc.SAMConfig();         
   Serial.println("Waiting for an ISO14443A Card ...");
   uint8_t success;
   uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
   uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
   uint8_t mifareclassic_ReadDataBlock;
   
   // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
   // 'uid' will be populated with the UID, and uidLength will indicate
   // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
   success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
   
   if (success)  // if a nfc tag has been detected
   {
      // Display some basic information about the card
      Serial.println("Found an ISO14443A card");
      Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
      Serial.print("  UID Value: ");
      
      nfc.PrintHex(uid, uidLength);
      
      if (uidLength == 4)
      {
         // We probably have a Mifare Classic card ... 
         uint32_t cardid = uid[0];
         cardid <<= 8;
         cardid |= uid[1];
         cardid <<= 8;
         cardid |= uid[2];  
         cardid <<= 8;
         cardid |= uid[3]; 
         Serial.print("Seems to be a Mifare Classic card #");
         Serial.println(cardid);
         return cardid;
      }
   }  
}
bool checktag() // checks the nfc tag database for matches.
{
   if (cardid == 2861708310)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 1");
      tagdata = true;
      return tagdata;
   }
   else if (cardid == 2864376086)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 2");
      tagdata = true;
      return tagdata;
   }
   else if (cardid == 3403313686)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 3");
      tagdata = true;
      return tagdata;
   }
   else if (cardid == 2863228950)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 4");
      tagdata = true;
      return tagdata;
   }
   else if (cardid == 3392821014)
   {
      digitalWrite(13, HIGH);  // sets the digital pin 13 on
      Serial.println("Detected card id:");
      Serial.println(cardid);
      Serial.println("NFC card: 5");
      tagdata = true;
      return tagdata;
   }
}

bool starttensecondstimer() // starts ten second timer and returns flag when 10 seconds are over.
{
   flag = true;
   counter = 0;
   unsigned long currentMillis = millis(); // grab current time     
   if ((unsigned long)(currentMillis - previousMillis) >= interval)  // check if "interval" time has passed (1000 milliseconds) 
   {
      counter ++;
      Serial.println(counter);
      previousMillis = millis();
      if (counter > 9) // reset timer afer 10 seconds 
      {
         counter = 0;
         flag = true;
         return flag;
      }
   }
}

post the

complete

code as a code-section

This is my complete code :slight_smile:

Is it not in a section??

Yes it is in a section.
But you re-edited a previous post.
Another basic-rule except for typos

don't

re-edit previous posts

I haven't seen it that you modified it. and in other cases a modified posting makes the following-up postings look as nonsense

So here is your code with added debug-output through two compiler-macros
As I don't have your PN532-library I can't make it compile.

The debug-output shows what is going on

#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);
// usage: dbg("1:my fixed text",myVariable);
// myVariable can be any variable or expression that is defined in scope

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);



#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3)

// Or use this line for a breakout or shield with an I2C connection:
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

const int sensor = 8;       // door sensor input pin
int state;                  // statemachine state
int door;                   // doorstate 0 closed or 1 open
bool tagdata;
unsigned long cardid;       //nfc tag cardid

//this is for the blinking led:
int ledState = LOW;                     // ledState used to set the LED
unsigned long previousMillis = 0;       // will store last time LED was updated
const long interval = 1000;             // interval at which to blink (milliseconds)

//this is for the alarm timer:
int counter;
bool flag;


void setup(void)
{
  Serial.begin(115200);
  pinMode(4, OUTPUT);     // sets the digital pin 4 as output for relay 1
  pinMode(5, OUTPUT);     // sets the digital pin 5 as output for relay 2
  pinMode(6, OUTPUT);     // sets the digital pin 6 as output RED LED
  pinMode(7, OUTPUT);     // sets the digital pin 7 as output GREEN LED
  pinMode(13, OUTPUT);    // sets the digital pin 13 as output TEST LED
  pinMode(sensor, INPUT_PULLUP);  // sets pullup resistor on for sensor
  state = 1;              // starts machine with first state
}

void loop (void)
{
  // print content of variable "state" once every 1000 milliseconds
  dbgi("1:top of loop", state, 1000); 
  state = 1;
  switch (state)
  {
    case 1:
      dbg("entering case 1",0); 
      digitalWrite(4, HIGH);  // turn relay 1 off
      digitalWrite(5, HIGH);  // turn relay 2 off
      Serial.println("Hello!");
      Serial.println("Alarmsystem booting up");
      Serial.println("Alarm status: UNARMED");
      Serial.println("Alarm will be armed when door is closed");

      dbg("direct before for-loop blink led", 0);
      for (int i = 0; i <= 1; i++) // 10 seconds bootup (when set to 9)
      {
        digitalWrite(7, HIGH);  // turn green light on
        delay(500);
        digitalWrite(7, LOW);  // turn green light off
        digitalWrite(6, HIGH);  // turn red light on
        delay(500);
        digitalWrite(6, LOW);  // turn red light off
      }
      dbg("direct after for-loop blink led", 0);
      dbg("checkdoorstate()", 0);
      checkdoorstate();
      if (door = 0)
      {
        Serial.println("Door is closed");
        Serial.println("Alarmsystem booted");
        state = 2;
      }
      dbg("leaving case 1",0); 
      break;

    case 2:
      dbg("entering case 2", 0); 
      blinkingled();
      checkdoorstate();
      if (door = 1)
      {
        Serial.println("Door is opened");
        digitalWrite(6, LOW);  // turn red light off
        nfcstart();
        checktag();
        if (tagdata  = true)   // if a tag has been recognized
        {
          Serial.println("Alarm has been Dissarmed");
          digitalWrite(7, HIGH);  // turn green light on
          Serial.println("Waiting for door to be closed again...");
          state = 3;
        }
        if (flag = true) // If the ten second timer is over. Alarm will go off
        {
          Serial.println("NFC not detected or too late");
          Serial.println("ALARM TRIGGERD");
          Serial.println("Activating light and horn");
          state = 4;
        }
        dbg("leaving case 2", 0);
        break;

      case 3:
        dbg("entering case 3", 0); 
        checkdoorstate();
        if (door = 0) // if the door is closed
        {
          Serial.println("Door is closed");
          Serial.println("Alarm status: ARMED");
          digitalWrite(7, LOW);  // turn green light off
          state = 2;
        }
        dbg("leaving case 3", 0);

      case 4:
        dbg("entering case 4", 0);
        digitalWrite(4, LOW);  // turn relay 1 on
        digitalWrite(5, LOW);  // turn relay 2 on
        delay (3000); // alarm goes wild for 3 seconds.
        counter = 0; // reset counter
        state = 1;   // reboot system
        dbg("leaving case 4", 0);
        break;
      default:
        dbg("default", 0);
        break;
      }
  }
}

int checkdoorstate()
{
  int doorstate;
  doorstate = digitalRead(sensor); // check the status of the door (open or closed)

  if (doorstate == HIGH)        // door OPENED
  {
    door = 1; //door is open
  }
  else
  {
    door = 0; // door is closed
  }
  return door;
}

void blinkingled()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    if (ledState == LOW)
    {
      ledState = HIGH;
    }
    else
    {
      ledState = LOW;
    }
    digitalWrite(6, ledState);
  }
}

void nfcstart() // start of nfc system
{
  nfc.begin();
  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata)
  {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();
  Serial.println("Waiting for an ISO14443A Card ...");
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
  uint8_t mifareclassic_ReadDataBlock;

  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

  if (success)  // if a nfc tag has been detected
  {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: "); Serial.print(uidLength, DEC); Serial.println(" bytes");
    Serial.print("  UID Value: ");

    nfc.PrintHex(uid, uidLength);

    if (uidLength == 4)
    {
      // We probably have a Mifare Classic card ...
      uint32_t cardid = uid[0];
      cardid <<= 8;
      cardid |= uid[1];
      cardid <<= 8;
      cardid |= uid[2];
      cardid <<= 8;
      cardid |= uid[3];
      Serial.print("Seems to be a Mifare Classic card #");
      Serial.println(cardid);
      return cardid;
    }
  }
}

bool checktag() // checks the nfc tag database for matches.
{
  if (cardid == 2861708310)
  {
    digitalWrite(13, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 1");
    tagdata = true;
    return tagdata;
  }
  else if (cardid == 2864376086)
  {
    digitalWrite(13, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 2");
    tagdata = true;
    return tagdata;
  }
  else if (cardid == 3403313686)
  {
    digitalWrite(13, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 3");
    tagdata = true;
    return tagdata;
  }
  else if (cardid == 2863228950)
  {
    digitalWrite(13, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 4");
    tagdata = true;
    return tagdata;
  }
  else if (cardid == 3392821014)
  {
    digitalWrite(13, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 5");
    tagdata = true;
    return tagdata;
  }
}

bool starttensecondstimer() // starts ten second timer and returns flag when 10 seconds are over.
{
  flag = true;
  counter = 0;
  unsigned long currentMillis = millis(); // grab current time
  if ((unsigned long)(currentMillis - previousMillis) >= interval)  // check if "interval" time has passed (1000 milliseconds)
  {
    counter ++;
    Serial.println(counter);
    previousMillis = millis();
    if (counter > 9) // reset timer afer 10 seconds
    {
      counter = 0;
      flag = true;
      return flag;
    }
  }
}

best regards Stefan

Your code uses hard-coded numbers for a part of inputs and outputs
You should replace hard-coded numbers with constants that have self-explaining names

IO-pin 4 is relay1 what does relay 1 do? I'm sure the relay1 isn't shouting "one one one one..."

IO-pin 5 is relay1 what does relay 2 do? I'm sure the relay2 isn't shouting two two two two..."

the names of the constants should say spot-on what happends
For the LEDs this is easy

you had multiple not-working if-conditions
if (door = 0)
means assing variable door value 0 and after assigning value zero evaluate the value of the variable door and use this result for the if-condition

what you intened was comparing them

if (door == 0)

do you see the double-equal-sign "==" this is comparing

here is a code-version with if-conditions corrected and self-explaining constants
which makes an extra-comment obsolete

#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);
// usage: dbg("1:my fixed text",myVariable);
// myVariable can be any variable or expression that is defined in scope

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);


#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3)

// Or use this line for a breakout or shield with an I2C connection:
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

const int sensor = 8;       // door sensor input pin
int state;                  // statemachine state
int door;                   // doorstate 0 closed or 1 open
bool tagdata;
unsigned long cardid;       //nfc tag cardid

//this is for the blinking led:
int ledState = LOW;                     // ledState used to set the LED
unsigned long previousMillis = 0;       // will store last time LED was updated
const long interval = 1000;             // interval at which to blink (milliseconds)

//this is for the alarm timer:
int counter;
bool flag;

const byte redLED_Pin   =  6;
const byte greenLED_Pin =  7;
const byte TestLED_Pin  = 13;

const byte OPENED = true;
const byte CLOSED = false;


void setup() {
  Serial.begin(115200);
  Serial.println( F("Setup-Start") );
  pinMode(4, OUTPUT);     // sets the digital pin 4 as output for relay 1
  pinMode(5, OUTPUT);     // sets the digital pin 5 as output for relay 2

  // comment is obsolete through self-explaining constant   sets the digital pin 6 as output RED LED
  pinMode(redLED_Pin, OUTPUT);     
  pinMode(greenLED_Pin, OUTPUT);     // sets the digital pin 7 as output GREEN LED
  pinMode(TestLED_Pin, OUTPUT);    // sets the digital pin 13 as output TEST LED
  pinMode(sensor, INPUT_PULLUP);  // sets pullup resistor on for sensor
  state = 1;              // starts machine with first state
}


void loop () {
  // print content of variable "state" once every 1000 milliseconds
  dbgi("1:top of loop", state, 1000);
  // state = 1; <==== this is wrong 
  // loop shall L O O P ! and variable state controls
  // which part of the code gets executed
  // that is the sense of purpose state-machine
  
  switch (state)  {
    case 1:
      dbg("entering case 1", 0);
      digitalWrite(4, HIGH);  // turn relay 1 off
      digitalWrite(5, HIGH);  // turn relay 2 off
      Serial.println("Hello!");
      Serial.println("Alarmsystem booting up");
      Serial.println("Alarm status: UNARMED");
      Serial.println("Alarm will be armed when door is closed");

      dbg("direct before for-loop blink led", 1);
      for (int i = 0; i <= 1; i++) // 10 seconds bootup (when set to 9)
      {
        digitalWrite(greenLED_Pin, HIGH);  // turn green light on
        delay(500);
        digitalWrite(greenLED_Pin, LOW);  // turn green light off
        digitalWrite(redLED_Pin, HIGH);  // turn red light on
        delay(500);
        digitalWrite(redLED_Pin, LOW);  // turn red light off
      }
      dbg("direct after for-loop blink led", 2);

      dbg("checkdoorstate()", 3);
      checkdoorstate();
      if (door == CLOSED) {
        Serial.println("Door is closed");
        Serial.println("Alarmsystem booted");
        state = 2;
      }
      dbg("leaving case 1", 4);
      break;

    case 2:
      dbg("entering case 2", 5);
      blinkingled();
      checkdoorstate();
      if (door == OPENED) {
        Serial.println("Door is opened");
        digitalWrite(redLED_Pin, LOW);  // turn red light off
        nfcstart();
        checktag();
        if (tagdata  = true)   // if a tag has been recognized
        {
          Serial.println("Alarm has been Dissarmed");
          digitalWrite(greenLED_Pin, HIGH);  // turn green light on
          Serial.println("Waiting for door to be closed again...");
          state = 3;
        }
        if (flag = true) // If the ten second timer is over. Alarm will go off
        {
          Serial.println("NFC not detected or too late");
          Serial.println("ALARM TRIGGERD");
          Serial.println("Activating light and horn");
          state = 4;
        }
        dbg("leaving case 2", 6);
        break;

      case 3:
        dbg("entering case 3", 7);
        checkdoorstate();
        if (door == CLOSED) // if the door is closed 
        {
          Serial.println("Door is closed");
          Serial.println("Alarm status: ARMED");
          digitalWrite(greenLED_Pin, LOW);  // turn green light off
          state = 2;
        }
        dbg("leaving case 3", 8);

      case 4:
        dbg("entering case 4", 9);
        digitalWrite(4, LOW);  // turn relay 1 on
        digitalWrite(5, LOW);  // turn relay 2 on
        delay (3000); // alarm goes wild for 3 seconds.
        counter = 0; // reset counter
        state = 1;   // reboot system
        dbg("leaving case 4", 10);
        break;

      default:
        dbg("default", 11);
        break;
      }
  }
}

int checkdoorstate() {
  int doorstate;
  doorstate = digitalRead(sensor); // check the status of the door (open or closed)

  if (doorstate == HIGH) {        // obsolete door OPENED
    door = OPENED; //obsolte door is open
  }
  else
  {
    door = CLOSED; // obsolete door is closed
  }
  return door;
}

void blinkingled() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)  {
    previousMillis = currentMillis;
    if (ledState == LOW){
      ledState = HIGH;
    }
    else {
      ledState = LOW;
    }
    digitalWrite(redLED_Pin, ledState);
  }
}

void nfcstart() // start of nfc system
{
  nfc.begin();
  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata)
  {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();
  Serial.println("Waiting for an ISO14443A Card ...");
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
  uint8_t mifareclassic_ReadDataBlock;

  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

  if (success)  // if a nfc tag has been detected
  {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: "); Serial.print(uidLength, DEC); Serial.println(" bytes");
    Serial.print("  UID Value: ");

    nfc.PrintHex(uid, uidLength);

    if (uidLength == 4)
    {
      // We probably have a Mifare Classic card ...
      uint32_t cardid = uid[0];
      cardid <<= 8;
      cardid |= uid[1];
      cardid <<= 8;
      cardid |= uid[2];
      cardid <<= 8;
      cardid |= uid[3];
      Serial.print("Seems to be a Mifare Classic card #");
      Serial.println(cardid);
      return cardid;
    }
  }
}

bool checktag() // checks the nfc tag database for matches.
{
  if (cardid == 2861708310)
  {
    digitalWrite(TestLED_Pin, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 1");
    tagdata = true;
    return tagdata;
  }
  else if (cardid == 2864376086)
  {
    digitalWrite(TestLED_Pin, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 2");
    tagdata = true;
    return tagdata;
  }
  else if (cardid == 3403313686)
  {
    digitalWrite(TestLED_Pin, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 3");
    tagdata = true;
    return tagdata;
  }
  else if (cardid == 2863228950)
  {
    digitalWrite(TestLED_Pin, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 4");
    tagdata = true;
    return tagdata;
  }
  else if (cardid == 3392821014)
  {
    digitalWrite(TestLED_Pin, HIGH);  // sets the digital pin 13 on
    Serial.println("Detected card id:");
    Serial.println(cardid);
    Serial.println("NFC card: 5");
    tagdata = true;
    return tagdata;
  }
}

bool starttensecondstimer() // starts ten second timer and returns flag when 10 seconds are over.
{
  flag = true;
  counter = 0;
  unsigned long currentMillis = millis(); // grab current time
  if ((unsigned long)(currentMillis - previousMillis) >= interval)  // check if "interval" time has passed (1000 milliseconds)
  {
    counter ++;
    Serial.println(counter);
    previousMillis = millis();
    if (counter > 9) // reset timer afer 10 seconds
    {
      counter = 0;
      flag = true;
      return flag;
    }
  }
}

best regards Stefan

1 Like

Wow man. Just wow. Never had such a good help before! I love the way you put the comments and I have never seen the dbg function you use. I will now compare your code to my old one. Man this is so usefull to me, you have no idea!

I must say that I don't quit understand this part of the code you wrote:

#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);
// usage: dbg("1:my fixed text",myVariable);
// myVariable can be any variable or expression that is defined in scope

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);

what does it do?

using the #define "statement" to make the compiler "write" code
#define can be used to make the compiler replace text that describes something with (almost) anything else

easy example
let's assume IO-pin number 4 shall be set to work as output
the command for defining an IO-pin to be configured as output is

pinMode(4,OUTPUT);
the number "4" says nothing about the purpose of this IO-pin

let's assume the IO-pin shall switch On/Off a buzzer

you would have to add a comment to explain
pinMode(4,OUTPUT); // IO-pin 4 is buzzer

the compiler needs the number. To make the code easier to read and understand
#define BuzzerPin 4
So the command looks like this
pinMode(BuzzerPin,OUTPUT);

the descriptive word "BuzzerPin" gets replaced through the compiler by a "4"
so what the compiler compiles is still
pinMode(4,OUTPUT);

the #define can do much more than just replace a word by a single number
it can replace multiple words like

#define prHello Serial.println("Hello World!");

identifier-part: prHello

replacement-part: Serial.println("Hello World!");

The mechanism behind it is the compiler acts like if you would

deleting the identifier-part:

and then

typing the replacement-part:

into your *.ino-textfile which is your sourcecode.

This is done right after clicking the compile or the upload-button in the IDE.

this means the macros act on a completely different level than the program-code
They act on the source-code-level

If your program is compiled and uploaded to the microcontroller things are "acting" on the program-level.

an expression like #myFixedText with a leading double-cross "#"
acts like a text-variable

#define dbg(myFixedText, variableName) \

parenthesis open myFixedText = use myFixedText as a macro-variable

a call of the macro looks like this:

dbg("entering case 1", 0);

This means all characters right behind the opening parenthese and the comma get stored into the macro-variable myFixedText

Serial.print( F(#myFixedText does

replace the character-sequence hold by the macro-variable myFixedText
so after this action the source-code looks like this

Serial.print( F("entering case 1"

The macro goes on
Serial.print( F(#myFixedText " " #variableName"=") ); \

which means after finishing the whole line your source-code looks is "transformed from

macro-call:

dbg("entering case 1", 0);

to

Serial.print( F("entering case 1  0=") );

macro-variable "variableName" holds the "0"

this part of the macro-code
Serial.print( F(#myFixedText " " #variableName"=") ); \

is replaced by the "0"
the rest
Serial.print( F(#myFixedText " " #variableName"**=") ); **

are again just characters
so at the end the source-code-line looks like this

Serial.print( F("entering case 1  0=") );

in principle the same thing happends with the rest of the macro

Serial.println(variableName);

With a modified example for the macro-call

dbg("damm! show me the content of variable",myStep);

results in

Serial.print(  F("damm! show me the content of variable myStep=") );
Serial.println(myStep);
dbg("what the heck is value of variable",myCounter);

results in

Serial.print(  F("what the heck is value of variable myCounter=") );
Serial.println(myCounter);

dbgi has some more code that is genious! It is a brilliant idea proposed by user
Coding_Badly So his username is self-ironic

a do - while -loop with a fixed condition "false"

At first view this seems to be nonsense a do-while-loop where the condition always evaluates to "false" means
run down the code only once

so why not leave away the do-while-loop???

The purpose of adding the do-while-loop is it makes the variable intervalStartTime
local to the while-loop

This has the effect that with mutliples calls of macro dbgi
the always the same named variable intervalStartTime are each local and don't disturb each other.

This means the macro dbgi can be called thousands of times where each call has its own set of variables.

best regards Stefan