0

I am using this code.. But everytime after one rfid tag is read by the reader, I have to manually press the reset button on the arduino before scanning the next tag. I want to do this operation after every 10 or 20 seconds from one tag scanning without manually pressing the reset button. What changes I have to make to this code??

/*
* source: http://www.electroschematics.com/11301/arduino-rfid-reader-rc522-access-control-system/
* Read a card using a mfrc522 reader on your SPI interface
* Pin layout should be as follows (on Arduino Uno):
* MOSI: Pin 11 / ICSP-4
* MISO: Pin 12 / ICSP-1
* SCK: Pin 13 / ISCP-3
* SS: Pin 10
* RST: Pin 9
*/

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

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address----------------------------------------------

#define SS_PIN 10
#define RST_PIN 9

RFID rfid(SS_PIN,RST_PIN);

int startAlarm = false;
int resetAlarm = 2;
int relay = 6;
int alarm = 8;

int serNum[5];

int cards[][5] = {
  {00,162,227,135,198} // card 1

};

bool access = false;

void setup()
{
  // Setup size of LCD 20 characters and 2 lines  
  lcd.begin(20,2);    //------------------------------------------------------
  // Back light on
  lcd.backlight();  //---------------------------------------------------------

  lcd.setCursor(0,0);         //----------------------------------------------
  lcd.print("SCAN your ID");   //------------------------------------------------

    Serial.begin(9600);
    SPI.begin();
    rfid.init();
    pinMode(resetAlarm, INPUT);
    pinMode(relay, OUTPUT);
    pinMode(alarm, OUTPUT);
    digitalWrite(relay, HIGH); // or LOW if you have a regular relay------------------------------(ALREADY CHANGED)
    attachInterrupt(0, reset_alarm, LOW);
}

void loop()
{

    if(rfid.isCard()){

        if(rfid.readCardSerial()){
            Serial.print(rfid.serNum[0]);
            Serial.print(",");
            Serial.print(rfid.serNum[1]);
            Serial.print(",");
            Serial.print(rfid.serNum[2]);
            Serial.print(",");
            Serial.print(rfid.serNum[3]);
            Serial.print(",");
            Serial.print(rfid.serNum[4]);
            Serial.println("");

            for(int x = 0; x < sizeof(cards); x++){
              for(int i = 0; i < sizeof(rfid.serNum); i++ ){
                  if(rfid.serNum[i] != cards[x][i]) {
                      access = false;
                      break;
                  } else {
                      access = true;
                  }
              }
              if(access) break;
            }

        }

       if(access){
          Serial.println("Welcome!"); 
          startAlarm = false;
          digitalWrite(relay, LOW); // HIGH with regular relay (I have already changed the code)  //------------------------------   
          lcd.setCursor(0,0);   //----------------------------------------------------------------------------------------------
          lcd.print("Access Granted");  //-------------------------------------------------------------------------------------------
          delay(3000);  
          lcd.clear();
          lcd.setCursor(0,0);         //----------------------------------------------
          lcd.print("SCAN your ID");   //------------------------------------------------
             //---------------------------------------------------------------
       } else {
           Serial.println("Not allowed!"); 
           startAlarm = true; 
           digitalWrite(relay, HIGH);  // LOW with regular relay (I have already changed the code)----------------------------------
           lcd.setCursor(0,0);         //------------------------------------------------------------------------------------
           lcd.print("Invalid Access ");        //------------------------------------------------------------------------------------
           delay(3000);  
           lcd.clear();                            //--------------------------------------------
           lcd.setCursor(0,0);         //----------------------------------------------
           lcd.print("SCAN your ID");   //------------------------------------------------

       }        
    }

    if(startAlarm) {
       digitalWrite(alarm, HIGH); 
    } else {
      digitalWrite(alarm, LOW); 
    }

    rfid.halt();

}

void reset_alarm(){
    startAlarm = false;
}
  • 4
    Sound like you are having a software problem. I'd suggest trying to fix that, instead of this hackish workaround. My first instinct is that, because you call rfid.halt();, the RFID reader will no longer read any further cards, which would explain why you need to reset the Arduino. – Gerben Mar 28 '17 at 9:35
  • XY problem. – Enric Blanco Mar 28 '17 at 14:20
1

I would think the rfid library would be able to read multiple cards in a row... however I'm not familiar with it.

Here is an answer from a similar question about how to initiate a hardware reset with software using the watchdog timer - https://arduino.stackexchange.com/a/1478/31106 :

The SoftReset library makes it easy. Although it is not difficult to implement directly. Shown below..

#include <avr/wdt.h>
...
setup() {

  ...
  MCUSR = 0;  // clear out any flags of prior resets.
  ...

then when desired...

...
wdt_enable(WDTO_15MS); // turn on the WatchDog and don't stroke it.
for(;;) { 
  // do nothing and wait for the eventual...
} 
...
  • 1
    This would certainly force a system restart which is what the OP said he wanted. It is, however, a drastic solution for what is almost certainly a simple coding problem which may be better handled by a timeout or some similar mechanism in the application program. – 6v6gt Mar 28 '17 at 11:20
  • 100% agree. Finding a solution that didn't require a reset would be ideal. – Mazaryk Mar 28 '17 at 17:15
1

This may not be your only issue, but I think you are using sizeof() wrongly. This 'function' returns the number of bytes occupied by a variable or type OR the number of bytes occupied by an array.

So

1 == sizeof(char)
6 == sizeof ("Hello")  // Because of the trailing null
2 == sizeof(int)
int cards[][5] = {
                  {00,162,227,135,198} // card 1
                 };
10 == sizeof (cards)

So you line that says for(int x = 0; x < sizeof(cards); x++){ is happening 10 times, not once.

Personally I would never use sizeof to measure the size of an array, but if you have to then you need to do this:

size = sizeof (cards) / sizeof (int)
  • 1
    You mean 10 == sizeof(cards). – Edgar Bonet Mar 28 '17 at 13:35
  • Yes I do, I wasn't sure when I wrote it, but just tested and corrected it. – Code Gorilla Mar 28 '17 at 14:00
  • As you may know, sizeof is an operator rather than a function. So one can say, equivalently, sizeof (cards) / sizeof (cards[0]) or sizeof cards/ sizeof cards[0]. Note, per §6.5.3.4.2 of ISO/IEC 9899:201x N1570 C++ std, "The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type." That is, sizeof (int) is ok, but malformed sizeof int is not ok – James Waldby - jwpat7 Mar 29 '17 at 6:17

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.