RFID Garage door opener


  • Contest Winner

    This sketch is to open a Garage door with an mifare RIFD-tag

    For an Arduino Nano v3 wiring :

    • rf24l01+ as descibed on the MySensors website
    • MFRC522 reader/writer as described above EXCEPT for pin D9 and D10: connect RST i.s.o. pin D9 to pin D7 and connect SDA(SS) i.s.o. pin D10 to pin D8
    • LED with 470ohm resistor between GMD and pin A3
    • push button between GND and pin D5
    • 5v relays coil between GND and pin D4 -> switch pins of the relays should be connected in parallel with your garage door push button.

    Features:

    • This project can record up to 18 RFID-"tags"
    • These card IDs are stored in to EEPROM by keeping them next to the RFID reader when the system in program mode. (Slow blinking LED) When a card is accepted as new card the LED will blink fast for a short time.
    • To keep the master-tags (choose your own) next to the RFID reader when pressing the push button. To clear all cards (except the master card) press the push button in program mode for 6 seconds. The LED will now fast blink for a couple of seconds.
    • Your garage your can be opened by keep a registered RFID tag next to the reader or by clicking the open icon on lock node presented by this plugin.
    • By by-passing the alarm node presented by this plug in the RFID will be temporarily disabled.
    • When an incorrect (not registered) RFID tag is scanned the alarm is triggered to detect illegal scan attempts
      RFIDSketch.png

    Used RFID reader can be found here:

    The Sketch code:

    /*
     * ----------------------------------------------------------------------------
     * This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
     * for further details and other examples.
     * 
     * NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
     * 
     * Released into the public domain.
     * ----------------------------------------------------------------------------
     * Example sketch/program showing how to read data from a PICC (that is: a RFID
     * Tag or Card) using a MFRC522 based RFID Reader on the Arduino SPI interface.
     * 
     * When the Arduino and the MFRC522 module are connected (see the pin layout
     * below), load this sketch into Arduino IDE then verify/compile and upload it.
     * To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M).
     * When you present a PICC (that is: a RFID Tag or Card) at reading distance
     * of the MFRC522 Reader/PCD, the serial output will show the ID/UID, type and
     * any data blocks it can read. Note: you may see "Timeout in communication"
     * messages when removing the PICC from reading distance too early.
     * 
     * If your reader supports it, this sketch/program will read all the PICCs
     * presented (that is: multiple tag reading). So if you stack two or more
     * PICCs on top of each other and present them to the reader, it will first
     * output all details of the first and then the next PICC. Note that this
     * may take some time as all data blocks are dumped, so keep the PICCs at
     * reading distance until complete.
     * 
     * Typical pin layout used:
     * -----------------------------------------------------------------------------------------
     *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
     *             Reader/PCD   Uno           Mega      Nano v3    Leonardo/Micro   Pro Micro
     * Signal      Pin          Pin           Pin       Pin        Pin              Pin
     * -----------------------------------------------------------------------------------------
     * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
     * SPI SS      SDA(SS)      10            53        D10        10               10
     * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
     * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
     * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
     */
    
    /*
     RFID Garagedoor opener by Bart Eversdijk
     
     This sketch is to open a Garage door with an mifare RIFD-tag 
      
      For an Arduino Nano v3
      Connection wiring :
        - nrf24l01+ as descibed on the MySensors website
        - MFRC522 reader/writer as described above EXCEPT for pin D9 and D10:  connect RST i.s.o. pin D9 to pin D7 and connect SDA(SS) i.s.o. pin D10 to pin D8 
        - LED with 470ohm resistor between GMD and pin A3 
        - push button between GND and pin D5
        - 5v relays coil between GND and  pin D4 -> switch pins of the relays should be connected in parallel with your garage door push button. 
      
      Features:
      This project can record up to 18 RFID-"tags"
      These card IDs are stored in to EEPROM by keeping them next to the RFID reader when the system in program mode. (Slow blinking LED) When a card is accepted as new card the LED will blink fast for a short time.
      To keep the master-tags (choose your own) next to the RFID reader when pressing the push button. To clear all cards (except the master card) press the push button in program mode for 6 seconds. The LED will now fast blink for a couple of seconds.
      
      Your garage your can be opened by keep a registered RFID tag next to the reader or by clicking the open icon on lock node presented by this plugin.
      By by-passing the alarm node presented by this plug in the RFID will be temporarily disabled.
      When an incorrect (not registered) RFID tag is scanned the alarm is triggered to detect illegal scan attempts   
    
    */
    
    #include <SPI.h>
    #include <MFRC522.h>
    #include <MySensor.h> 
    #include <Bounce2.h>
    
    #define RF_INIT_DELAY   125
    #define ONE_SEC         1000
    #define MAX_CARDS       18
    #define PROG_WAIT       10
    #define HEARTBEAT       10
    #define BAUD            115200
    
    /*Pin definitions*/
    #define LED_PIN         A3
    #define GARAGEPIN       4
    #define SWITCH_PIN      5
    #define RST_PIN		7		//  MFRC 
    #define SS_PIN		8		//  MFRC 
    
    MFRC522      mfrc522(SS_PIN, RST_PIN);	// Create MFRC522 instance
    MFRC522::Uid olduid;
    MFRC522::Uid masterkey = { 10, {0,0,0,0, 0,0,0,0, 0,0 },  0 };
    
    byte       countValidCards  = 0;
    MFRC522::Uid validCards[MAX_CARDS];
    
    void       ShowCardData(MFRC522::Uid* uid);
    bool       sameUid(MFRC522::Uid* old, MFRC522::Uid* check);
    void       copyUid(MFRC522::Uid* src, MFRC522::Uid* dest);
    bool       isValidCard(MFRC522::Uid* uid);
    int        releasecnt = 0;
    
    #define    CHILD_ID_ALARM    1
    #define    CHILD_ID_LOCK     2
    MySensor   gw;
    Bounce     debouncer = Bounce();
    
    int        oldSwitchValue=-1;
    int        switchValue = 0;
    long       timer = -1;
    bool       programmode = false;
    bool       ledon;
    int        programTimer = 0;
    bool       armed = true;
    unsigned long lastTime = 0;
    
    MyMessage  lockMsg(CHILD_ID_LOCK,          V_LOCK_STATUS);
    MyMessage  lockArmMsg(CHILD_ID_ALARM,      V_ARMED);
    MyMessage  wrongMsg(CHILD_ID_ALARM,        V_TRIPPED);
    
    void setup() {
    	Serial.begin(BAUD);		// Initialize serial communications with the PC
            pinMode(GARAGEPIN, OUTPUT);     // Initialise in/output ports
            
            // Make sure MFRC will be disabled on the SPI bus
            pinMode(RST_PIN, OUTPUT);     
            digitalWrite(RST_PIN, LOW);
            pinMode(SS_PIN, OUTPUT);     
            digitalWrite(SS_PIN, LOW);
    
            pinMode(LED_PIN, OUTPUT);
            digitalWrite(LED_PIN, LOW);
            // Setup the button
            pinMode(SWITCH_PIN, INPUT);
            // Activate internal pull-up
            digitalWrite(SWITCH_PIN, HIGH);
    
            // After setting up the button, setup debouncer
            debouncer.attach(SWITCH_PIN);
            debouncer.interval(5);
    
            // Init mysensors library
            gw.begin(incomingMessage, 5);
            gw.sendSketchInfo("RFID Garage", "1.1"); delay(RF_INIT_DELAY);
            
            // Register all sensors to gw (they will be created as child devices)
            gw.present(CHILD_ID_LOCK, S_LOCK);      delay(RF_INIT_DELAY);
            gw.present(CHILD_ID_ALARM, S_MOTION);   delay(RF_INIT_DELAY);
    
            recallEeprom();
            
            // Init MFRC RFID sensor
    	SPI.begin();			// Init SPI bus
    	mfrc522.PCD_Init();		// Init MFRC522
    	ShowReaderDetails();	        // Show details of PCD - MFRC522 Card Reader details
    
            gw.send(lockArmMsg.set(armed));
            Serial.println(F("Init done..."));
    }
    
    void loop() {
            timer++;
            delay(HEARTBEAT);
            gw.process();
            debouncer.update();
    
            // Get the update value
            int switchValue = debouncer.read();
            if (switchValue != oldSwitchValue) {
              // Send in the new value
              Serial.print (F("Switch "));
              Serial.println (switchValue);
              
              if (switchValue && programmode) {
                   lastTime     = millis() / 1000;
              }
              
              if (!switchValue && programmode && lastTime > 0) {
                   if ( (millis() / 1000) - lastTime > 3) {
                        Serial.println(F("Reset all cards"));  
                        countValidCards  = 0;
                        blinkFast(50);
                   } else {
                      Serial.println(F("Program off"));  
                      digitalWrite(LED_PIN, LOW);
                      programmode = false;
                      
                      storeEeprom();
                   }
              }
              
              if (!switchValue)   {
                  programTimer = 0;
              }
              oldSwitchValue = switchValue;
            }
            
            if (programmode && ((timer % (ONE_SEC / HEARTBEAT)) == 0 ))  {
                ledon = !ledon;
                digitalWrite(LED_PIN, ledon);
                programTimer++;
    
                // Stop program mode after 20 sec inactivity
                if (programTimer > PROG_WAIT)  {
                   programmode = false;
                   digitalWrite(LED_PIN, false);
                   Serial.println(F("Program expired"));  
                }
            }
            
            if ((timer % (200 / HEARTBEAT)) == 0 )   {
                 // Look for new cards
                 if ( ! mfrc522.PICC_IsNewCardPresent()) {
                      if (releasecnt > 0)   {
                          releasecnt--;
                          if (!releasecnt)  {
                              olduid.size = 0;
                              Serial.println(F("release"));
                          }
                        }
        		return;
        	    }
                releasecnt = 5;
        
        	   // Select one of the cards
        	   if ( ! mfrc522.PICC_ReadCardSerial()) {
        		return;
        	   }
        
               // Dump debug info about the card; PICC_HaltA() is automatically called
        	   //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
               if (!olduid.size || !sameUid(&(mfrc522.uid), &olduid))  {
                    ShowCardData(&(mfrc522.uid));
                    copyUid(&(mfrc522.uid), &olduid);
                    if ( isValidCard(&olduid) )   {
                         OpenDoor(programmode);
                    } else  {
                      
                       if (sameUid(&(mfrc522.uid), &masterkey)) {
                           // Only switch in program mode when mastercard is found AND the program button is pressed
                           if (switchValue)  {
                             Serial.println(F("Program mode"));
                             programmode = true;
                             programTimer = 0;
                             lastTime     = 0;
                           }
                       } else {
                           if (programmode) {
                             Serial.println(F("new card"));
                             programTimer = 0;
                             
                             if (countValidCards < MAX_CARDS)
                             {
                                // Add card to list...
                                copyUid(&(mfrc522.uid), &validCards[countValidCards]);
                                countValidCards++;
                                blinkFast(15);
                             }
                           } else {
                             Serial.println(F("Invalid card"));
                             if (armed) {
                                gw.send(wrongMsg.set(1));
                                delay(2000);
                                gw.send(wrongMsg.set(0));
                             }
                           }
                       }
                    }
               }
            }
    }
    
    void ShowCardData(MFRC522::Uid* uid) {
            Serial.print(F("Card UID:"));
    	for (byte i = 0; i < uid->size; i++) {
    		if(uid->uidByte[i] < 0x10) {
    			Serial.print(F(" 0"));
    		} else {
    			Serial.print(F(" "));
                    }
    		Serial.print(uid->uidByte[i], HEX);
    	} 
    	Serial.println();
    }
    
    void copyUid(MFRC522::Uid* src, MFRC522::Uid* dest)
    {
        dest->size = src->size;
        dest->sak  = src->sak;
        
        for (byte i = 0; i < src->size; i++) {
      	dest->uidByte[i] = src->uidByte[i];
        }
    }
    
    bool sameUid(MFRC522::Uid* old, MFRC522::Uid* check)
    {
        if (old->size != check->size) {
           return false;
        }
        for (byte i = 0; i < old->size; i++) {
      	if (old->uidByte[i] != check->uidByte[i]) {
                return false;
            }
        }
        return true;
    }
    
    bool isValidCard(MFRC522::Uid* uid)
    {
          for (byte i = 0; i < countValidCards; i++)  {
              if (validCards[i].size != uid->size)  {
                  break;
              }
              for (int j = 0; j < uid->size; j++) {
                  if (validCards[i].uidByte[j] != uid->uidByte[j])  {
                      break;
                  }
                  if (j == (uid->size - 1)) {  
                      return true;
                  }
              }
          }
          return false;
    }
    
    
    void storeEeprom()
    {
        byte address = 0;
        gw.saveState(address++, countValidCards);
        
        for (byte i = 0; i < countValidCards; i++) {
           gw.saveState(address++, validCards[i].size);
           for (byte j = 0; j < 10; j++) {
              gw.saveState(address++, validCards[i].uidByte[j]);
           } 
        }
    }
    
    void recallEeprom()
    {
        byte address = 0;
        
        countValidCards = gw.loadState(address++);
        if (countValidCards > MAX_CARDS) {
           Serial.println(F("Not a valid EEPROM reading set to default"));
           countValidCards = 0;
           storeEeprom();
           return;
        }
        
        for (byte i = 0; i < countValidCards; i++)  {
           validCards[i].size = gw.loadState(address++);
           for (byte j = 0; j < 10; j++)  {
              validCards[i].uidByte[j] = gw.loadState(address++);
           } 
        }
      
    }
    
    void blinkFast(int times)
    {
        for (int i = 0; i < times; i++) { 
           ledon = !ledon;
           digitalWrite(LED_PIN, ledon);
           delay(100);
        }
    }
    
    void OpenDoor(bool fakeOpen)
    {
        Serial.println(F("Open door!"));
        gw.send(lockMsg.set(false));
        
        if (!fakeOpen) { 
          digitalWrite(LED_PIN, HIGH);
          digitalWrite(GARAGEPIN, HIGH); 
        }
        delay(1000);
        
        if (!fakeOpen) { 
          digitalWrite(GARAGEPIN, LOW); 
          digitalWrite(LED_PIN, LOW);
        }
        
        gw.send(lockMsg.set(true));
    }
    
    void ShowReaderDetails() {
    	// Get the MFRC522 software version
    	byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
    	Serial.print(F("MFRC522 Software Version: 0x"));
    	Serial.print(v, HEX);
    	if (v == 0x91) {
    		Serial.print(F(" = v1.0"));
            } else if (v == 0x92) {
    		Serial.print(F(" = v2.0"));
            } else {
    		Serial.print(F(" (unknown)"));
            }
    	Serial.println("");
    	
            // When 0x00 or 0xFF is returned, communication probably failed
    	if ((v == 0x00) || (v == 0xFF)) {
    		Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
    	}
    }
    
    
    void incomingMessage(const MyMessage &message) 
    {
       if (message.type == V_LOCK_STATUS) {
         // Change relay state
         if (!message.getBool())  {
            OpenDoor(false);
         }
      
         // Write some debug info
         Serial.print(F("Lock status: "));
         Serial.println(message.getBool());
       }
       else 
       {
         if (message.type == V_ARMED)  {
           // Change relay state
           armed = message.getBool();
      
           // Write some debug info
           Serial.print(F("Arm status: "));
           Serial.println(message.getBool());
         }
         else
         {
           // Write some debug info
           Serial.print(F("Incoming msg type: "));
           Serial.print(message.type);
           Serial.print(F(" id: "));
           Serial.print(message.sensor);
           Serial.print(F(" content: "));
           Serial.println(message.getInt());
         }
       }
    }
    


  • Great Job @BartE , Homer must be proud 😎





  • Hello BartE,

    I tested your code but I did not find how to set the master key . Can you explain me how to do please ?

    Thanks!


  • Contest Winner

    @julien66500

    If you run the sketch with a Serial Monitor open you will see Card UID: with a number of hex values each time a RFID tag/card is held next to the reader.
    Just hold the desired master-key-card in front of the card reader and write down the hex values and fill them in in the struct on line 86

    MFRC522::Uid masterkey = { 10, {0,0,0,0, 0,0,0,0, 0,0 },  0 };
    

    The first number is the amount of hex values your key has, the 10 zero should be replaced by the number of HEX values you have.
    So suppose your master-key-card key says

    Card UID: 0x01 0x02 0x03
    

    Line 86 should look like this

    MFRC522::Uid masterkey = { 3, {0x01, 0x02, 0x03},  0 };
    


  • @BartE thank you, it works!



  • @Lawrence-Helm said:

    very cool, might have a go at some stage to try and use the nfc variant... So that you can open it with your phone http://www.aliexpress.com/item/Free-shipping-PN532-NFC-RFID-module-User-Kits-for-Arduino-compatible/2009097698.html?spm=2114.01020208.3.1.piLmyG&ws_ab_test=searchweb201556_9_79_78_77_80,searchweb201644_5,searchweb201560_6

    Well, I have that NFC reader, and I also have 2 Huawei G8 phones that have NFC build in. They both have the same NFC UID (1234), so distinguishing who opened the door is a problem. Even worse, a google search revealed that most phones have the same 1234 UID configured, which means that anyone with a NFC enabled phone can open your door!!!

    I still have to find a way to change that UID on the phone, or add extra NFC tags into the phone.



  • Hello.
    I have a problemm.
    The rfid don't store the card.
    If power off, all delete.
    What is the problem.

    Thx



  • Hi @BartE,

    Works great, but I want to let the masterkey trigger a second alarm, what way should I think; I have tried to let the mastercard open a second relay, but it didn't work. Maybe I should use a second programmed key lets say personkey and trigger on that? Can you give me some directions?

    Thanks Danny


  • Contest Winner

    @DannyM With this sketch a second relay (on pin 3) is controlled by the master-key

    The sketch should work but i did not test it.

    /*
     * ----------------------------------------------------------------------------
     * This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
     * for further details and other examples.
     * 
     * NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
     * 
     * Released into the public domain.
     * ----------------------------------------------------------------------------
     * Example sketch/program showing how to read data from a PICC (that is: a RFID
     * Tag or Card) using a MFRC522 based RFID Reader on the Arduino SPI interface.
     * 
     * When the Arduino and the MFRC522 module are connected (see the pin layout
     * below), load this sketch into Arduino IDE then verify/compile and upload it.
     * To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M).
     * When you present a PICC (that is: a RFID Tag or Card) at reading distance
     * of the MFRC522 Reader/PCD, the serial output will show the ID/UID, type and
     * any data blocks it can read. Note: you may see "Timeout in communication"
     * messages when removing the PICC from reading distance too early.
     * 
     * If your reader supports it, this sketch/program will read all the PICCs
     * presented (that is: multiple tag reading). So if you stack two or more
     * PICCs on top of each other and present them to the reader, it will first
     * output all details of the first and then the next PICC. Note that this
     * may take some time as all data blocks are dumped, so keep the PICCs at
     * reading distance until complete.
     * 
     * Typical pin layout used:
     * -----------------------------------------------------------------------------------------
     *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
     *             Reader/PCD   Uno           Mega      Nano v3    Leonardo/Micro   Pro Micro
     * Signal      Pin          Pin           Pin       Pin        Pin              Pin
     * -----------------------------------------------------------------------------------------
     * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
     * SPI SS      SDA(SS)      10            53        D10        10               10
     * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
     * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
     * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
     */
    
    /*
     RFID Garagedoor opener by Bart Eversdijk
     
     This sketch is to open a Garage door with an mifare RIFD-tag 
      
      For an Arduino Nano v3
      Connection wiring :
        - nrf24l01+ as descibed on the MySensors website
        - MFRC522 reader/writer as described above EXCEPT for pin D9 and D10:  connect RST i.s.o. pin D9 to pin D7 and connect SDA(SS) i.s.o. pin D10 to pin D8 
        - LED with 470ohm resistor between GMD and pin A3 
        - push button between GND and pin D5
        - 5v relays coil between GND and  pin D4 -> switch pins of the relays should be connected in parallel with your garage door push button. 
      
      Features:
      This project can record up to 18 RFID-"tags"
      These card IDs are stored in to EEPROM by keeping them next to the RFID reader when the system in program mode. (Slow blinking LED) When a card is accepted as new card the LED will blink fast for a short time.
      To keep the master-tags (choose your own) next to the RFID reader when pressing the push button. To clear all cards (except the master card) press the push button in program mode for 6 seconds. The LED will now fast blink for a couple of seconds.
      
      Your garage your can be opened by keep a registered RFID tag next to the reader or by clicking the open icon on lock node presented by this plugin.
      By by-passing the alarm node presented by this plug in the RFID will be temporarily disabled.
      When an incorrect (not registered) RFID tag is scanned the alarm is triggered to detect illegal scan attempts   
    
    */
    
    #include <SPI.h>
    #include <MFRC522.h>
    #include <MySensor.h> 
    #include <Bounce2.h>
    
    #define RF_INIT_DELAY   125
    #define ONE_SEC         1000
    #define MAX_CARDS       18
    #define PROG_WAIT       10
    #define HEARTBEAT       10
    #define BAUD            115200
    
    /*Pin definitions*/
    #define LED_PIN         A3
    #define SECONDRELAY     3
    #define GARAGEPIN       4
    #define SWITCH_PIN      5
    #define RST_PIN         7       //  MFRC 
    #define SS_PIN          8       //  MFRC 
    
    MFRC522      mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance
    MFRC522::Uid olduid;
    MFRC522::Uid masterkey = { 10, {0,0,0,0, 0,0,0,0, 0,0 },  0 };
    
    byte       countValidCards  = 0;
    MFRC522::Uid validCards[MAX_CARDS];
    
    void       ShowCardData(MFRC522::Uid* uid);
    bool       sameUid(MFRC522::Uid* old, MFRC522::Uid* check);
    void       copyUid(MFRC522::Uid* src, MFRC522::Uid* dest);
    bool       isValidCard(MFRC522::Uid* uid);
    int        releasecnt = 0;
    
    #define    CHILD_ID_ALARM    1
    #define    CHILD_ID_LOCK     2
    #define    CHILD_ID_LOCK2    3
    MySensor   gw;
    Bounce     debouncer = Bounce();
    
    int        oldSwitchValue=-1;
    int        switchValue = 0;
    long       timer = -1;
    bool       programmode = false;
    bool       ledon;
    int        programTimer = 0;
    bool       armed = true;
    unsigned long lastTime = 0;
    
    MyMessage  lockMsg(CHILD_ID_LOCK,          V_LOCK_STATUS);
    MyMessage  lock2Msg(CHILD_ID_LOCK2,          V_LOCK_STATUS);
    MyMessage  lockArmMsg(CHILD_ID_ALARM,      V_ARMED);
    MyMessage  wrongMsg(CHILD_ID_ALARM,        V_TRIPPED);
    
    void setup() {
            Serial.begin(BAUD);     // Initialize serial communications with the PC
            pinMode(GARAGEPIN, OUTPUT);     // Initialise in/output ports
            pinMode(SECONDRELAY, OUTPUT);     // Initialise in/output ports
            
            // Make sure MFRC will be disabled on the SPI bus
            pinMode(RST_PIN, OUTPUT);     
            digitalWrite(RST_PIN, LOW);
            pinMode(SS_PIN, OUTPUT);     
            digitalWrite(SS_PIN, LOW);
    
            pinMode(LED_PIN, OUTPUT);
            digitalWrite(LED_PIN, LOW);
            // Setup the button
            pinMode(SWITCH_PIN, INPUT_PULLUP);
    
            // After setting up the button, setup debouncer
            debouncer.attach(SWITCH_PIN);
            debouncer.interval(5);
    
            // Init mysensors library
            gw.begin(incomingMessage, 5);
            gw.sendSketchInfo("RFID Garage", "1.2"); delay(RF_INIT_DELAY);
            
            // Register all sensors to gw (they will be created as child devices)
            gw.present(CHILD_ID_LOCK, S_LOCK);      delay(RF_INIT_DELAY);
            gw.present(CHILD_ID_LOCK2, S_LOCK);      delay(RF_INIT_DELAY);
            gw.present(CHILD_ID_ALARM, S_MOTION);   delay(RF_INIT_DELAY);
    
            recallEeprom();
            
            // Init MFRC RFID sensor
            SPI.begin();            // Init SPI bus
            mfrc522.PCD_Init();     // Init MFRC522
            ShowReaderDetails();            // Show details of PCD - MFRC522 Card Reader details
    
            gw.send(lockArmMsg.set(armed));
            Serial.println(F("Init done..."));
    }
    
    void loop() {
            timer++;
            delay(HEARTBEAT);
            gw.process();
            debouncer.update();
    
            // Get the update value
            int switchValue = debouncer.read();
            if (switchValue != oldSwitchValue) {
              // Send in the new value
              Serial.print (F("Switch "));
              Serial.println (switchValue);
              
              if (switchValue && programmode) {
                   lastTime     = millis() / 1000;
              }
              
              if (!switchValue && programmode && lastTime > 0) {
                   if ( (millis() / 1000) - lastTime > 3) {
                        Serial.println(F("Reset all cards"));  
                        countValidCards  = 0;
                        blinkFast(50);
                   } else {
                      Serial.println(F("Program off"));  
                      digitalWrite(LED_PIN, LOW);
                      programmode = false;
                      
                      storeEeprom();
                   }
              }
              
              if (!switchValue)   {
                  programTimer = 0;
              }
              oldSwitchValue = switchValue;
            }
            
            if (programmode && ((timer % (ONE_SEC / HEARTBEAT)) == 0 ))  {
                ledon = !ledon;
                digitalWrite(LED_PIN, ledon);
                programTimer++;
    
                // Stop program mode after 20 sec inactivity
                if (programTimer > PROG_WAIT)  {
                   programmode = false;
                   digitalWrite(LED_PIN, false);
                   Serial.println(F("Program expired"));  
                }
            }
            
            if ((timer % (200 / HEARTBEAT)) == 0 )   {
                 // Look for new cards
                 if ( ! mfrc522.PICC_IsNewCardPresent()) {
                      if (releasecnt > 0)   {
                          releasecnt--;
                          if (!releasecnt)  {
                              olduid.size = 0;
                              Serial.println(F("release"));
                          }
                        }
                return;
                }
                releasecnt = 5;
        
               // Select one of the cards
               if ( ! mfrc522.PICC_ReadCardSerial()) {
                  return;
               }
        
               // Dump debug info about the card; PICC_HaltA() is automatically called
               //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
               if (!olduid.size || !sameUid(&(mfrc522.uid), &olduid))  {
                    ShowCardData(&(mfrc522.uid));
                    copyUid(&(mfrc522.uid), &olduid);
                    if ( isValidCard(&olduid) )   {
                         OpenDoor(programmode);
                    } else  {
                       if (sameUid(&(mfrc522.uid), &masterkey)) {
                           // Only switch in program mode when mastercard is found AND the program button is pressed
                           if (switchValue)  {
                             Serial.println(F("Program mode"));
                             programmode = true;
                             programTimer = 0;
                             lastTime     = 0;
                           } else {
                             OpenDoor2(programmode);
                           }
                       } else {
                           if (programmode) {
                             Serial.println(F("new card"));
                             programTimer = 0;
                             
                             if (countValidCards < MAX_CARDS)
                             {
                                // Add card to list...
                                copyUid(&(mfrc522.uid), &validCards[countValidCards]);
                                countValidCards++;
                                blinkFast(15);
                             }
                           } else {
                             Serial.println(F("Invalid card"));
                             if (armed) {
                                gw.send(wrongMsg.set(1));
                                delay(2000);
                                gw.send(wrongMsg.set(0));
                             }
                           }
                       }
                    }
               }
            }
    }
    
    void ShowCardData(MFRC522::Uid* uid) 
    {
        Serial.print(F("Card UID:"));
        for (byte i = 0; i < uid->size; i++) {
            if(uid->uidByte[i] < 0x10) {
                Serial.print(F(" 0"));
            } else {
                Serial.print(F(" "));
                    }
            Serial.print(uid->uidByte[i], HEX);
        } 
        Serial.println();
    }
    
    void copyUid(MFRC522::Uid* src, MFRC522::Uid* dest)
    {
        dest->size = src->size;
        dest->sak  = src->sak;
        
        for (byte i = 0; i < src->size; i++) {
        dest->uidByte[i] = src->uidByte[i];
        }
    }
    
    bool sameUid(MFRC522::Uid* old, MFRC522::Uid* check)
    {
        if (old->size != check->size) {
           return false;
        }
        for (byte i = 0; i < old->size; i++) {
            if (old->uidByte[i] != check->uidByte[i]) {
                return false;
            }
        }
        return true;
    }
    
    bool isValidCard(MFRC522::Uid* uid)
    {
          for (byte i = 0; i < countValidCards; i++)  {
              if (validCards[i].size != uid->size)  {
                  break;
              }
              for (int j = 0; j < uid->size; j++) {
                  if (validCards[i].uidByte[j] != uid->uidByte[j])  {
                      break;
                  }
                  if (j == (uid->size - 1)) {  
                      return true;
                  }
              }
          }
          return false;
    }
    
    
    void storeEeprom()
    {
        byte address = 0;
        gw.saveState(address++, countValidCards);
        
        for (byte i = 0; i < countValidCards; i++) {
           gw.saveState(address++, validCards[i].size);
           for (byte j = 0; j < 10; j++) {
              gw.saveState(address++, validCards[i].uidByte[j]);
           } 
        }
    }
    
    void recallEeprom()
    {
        byte address = 0;
        
        countValidCards = gw.loadState(address++);
        if (countValidCards > MAX_CARDS) {
           Serial.println(F("Not a valid EEPROM reading set to default"));
           countValidCards = 0;
           storeEeprom();
           return;
        }
        
        for (byte i = 0; i < countValidCards; i++)  {
           validCards[i].size = gw.loadState(address++);
           for (byte j = 0; j < 10; j++)  {
              validCards[i].uidByte[j] = gw.loadState(address++);
           } 
        }
      
    }
    
    void blinkFast(int times)
    {
        for (int i = 0; i < times; i++) { 
           ledon = !ledon;
           digitalWrite(LED_PIN, ledon);
           delay(100);
        }
    }
    
    void OpenDoor(bool fakeOpen)
    {
        Serial.println(F("Open door!"));
        gw.send(lockMsg.set(false));
        
        if (!fakeOpen) { 
          digitalWrite(LED_PIN, HIGH);
          digitalWrite(GARAGEPIN, HIGH); 
        }
        delay(1000);
        
        if (!fakeOpen) { 
          digitalWrite(GARAGEPIN, LOW); 
          digitalWrite(LED_PIN, LOW);
        }
        
        gw.send(lockMsg.set(true));
    }
    
    void OpenDoor2(bool fakeOpen)
    {
        Serial.println(F("Open door 2!"));
        gw.send(lock2Msg.set(false));
        
        if (!fakeOpen) { 
          digitalWrite(LED_PIN, HIGH);
          digitalWrite(SECONDRELAY, HIGH); 
        }
        delay(1000);
        
        if (!fakeOpen) { 
          digitalWrite(SECONDRELAY, LOW); 
          digitalWrite(LED_PIN, LOW);
        }
        
        gw.send(lock2Msg.set(true));
    }
    
    void ShowReaderDetails() {
        // Get the MFRC522 software version
        byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
        Serial.print(F("MFRC522 Software Version: 0x"));
        Serial.print(v, HEX);
        if (v == 0x91) {
            Serial.print(F(" = v1.0"));
            } else if (v == 0x92) {
            Serial.print(F(" = v2.0"));
            } else {
            Serial.print(F(" (unknown)"));
            }
        Serial.println("");
        
            // When 0x00 or 0xFF is returned, communication probably failed
        if ((v == 0x00) || (v == 0xFF)) {
            Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
        }
    }
    
    
    void incomingMessage(const MyMessage &message) 
    {
       if (message.type == V_LOCK_STATUS) {
         // Change relay state
         if (!message.getBool())  {
            switch (message.sensor)
            {
               case CHILD_ID_LOCK:
                  OpenDoor(false);
                  break;
               case CHILD_ID_LOCK2:
                  OpenDoor2(false);
                  break;
            }
         }
      
         // Write some debug info
         Serial.print(F("Lock:  "));
         Serial.print(message.sensor);
         Serial.print(F(" status: "));
         Serial.println(message.getBool());
       }
       else 
       {
         if (message.type == V_ARMED)  {
           // Change relay state
           armed = message.getBool();
      
           // Write some debug info
           Serial.print(F("Arm status: "));
           Serial.println(message.getBool());
         }
         else
         {
           // Write some debug info
           Serial.print(F("Incoming msg type: "));
           Serial.print(message.type);
           Serial.print(F(" id: "));
           Serial.print(message.sensor);
           Serial.print(F(" content: "));
           Serial.println(message.getInt());
         }
       }
    }
    


  • Hello BartE,
    I have the same issue as cyberfilou...
    Sketch works beautifully...but if I power off the Arduino (Pro Mini in my case) and power it on again, all stored cards are gone. Any ideas what could cause this, and how to prevent it?

    Thx a lot, Stefan


  • Contest Winner

    @SVLoneStar That is weird.

    Do you get this message each time you boot the Arduino? "Not a valid EEPROM reading set to default"
    What is the UID size (how many bytes) of the recorded cards?



  • Hi BartE - thanks for your reply!
    I do not receive any error regarding invalid EEPROM - not while writing, not at boot time.
    My cards are shown in this format: D4 04 E2 E9
    I register a Master Card like this (and it works until reboot):
    MFRC522::Uid masterkey = { 4, {0xD4,0x04,0xE2,0xE9}, 0 };


  • Contest Winner

    Cool stuff! You probably what some signing in there as well 🙂 would be a shame if someone snooped the open command from your controller and decided to pay a visit.


  • Contest Winner

    @SVLoneStar That should work, did you try the sketch shown in the topic?

    The function recallEeprom(); reads the EEPROM content and after closing the program mode this function storeEeprom();
    writes the EEPROM. Please add some debug info (Serial.print) and validate that these functions actually are called on

    • recallEeprom(); --> on start up
    • storeEeprom(); --> ending program mode.

  • Contest Winner

    @Anticimex yes your right but when i wrote this sketch signing was not in the released branch.



  • Nice work. I have yet to pick up an RFID reader to give that part of it a try, but I've modified it a little to have reed sensors for the 2 doors so that I can easily see if the door is open on my phone, and get notifications when the door opens at an unexpected time, like when the controller is set to vacation mode, or at times of night when we would not normally be coming and going.
    I'll be watching for someone to post up a signing version.

    Here's my 2 relay, 2 door sensor version.

    /*
     RFID Garagedoor opener by Bart Eversdijk
     Modified to add door sensors by Rod MacPherson
     
     This sketch is to open a Garage door with an mifare RIFD-tag 
      
      For an Arduino Nano v3
      Connection wiring :
        - nrf24l01+ as descibed on the MySensors website
        - MFRC522 reader/writer MOSI, MISO, SCK, 3.3V and GND as they are on the nrf24101+, but connect RST to pin D7 and connect SDA(SS) to pin D8 
        - LED with 470ohm resistor between GND and pin A3 
        - push button between GND and pin D5
        - 5v relays coil between GND and  pin D4 -> switch pins of the relays should be connected in parallel with your garage door push button. 
        - second relay for second door on pin D3
        
      Features:
      This project can record up to 18 RFID-"tags"
      These card IDs are stored in to EEPROM by keeping them next to the RFID reader when the system in program mode. (Slow blinking LED) When a card is accepted as new card the LED will blink fast for a short time.
      To keep the master-tags (choose your own) next to the RFID reader when pressing the push button. To clear all cards (except the master card) press the push button in program mode for 6 seconds. The LED will now fast blink for a couple of seconds.
      
      Your garage your can be opened by keep a registered RFID tag next to the reader or by clicking the open icon on lock node presented by this plugin.
      By by-passing the alarm node presented by this plug in the RFID will be temporarily disabled.
      When an incorrect (not registered) RFID tag is scanned the alarm is triggered to detect illegal scan attempts   
    
    */
    
    #include <SPI.h>
    #include <MFRC522.h>
    #include <MySensor.h> 
    #include <Bounce2.h>
    
    #define RF_INIT_DELAY   125
    #define ONE_SEC         1000
    #define MAX_CARDS       18
    #define PROG_WAIT       10
    #define HEARTBEAT       10
    #define BAUD            115200
    
    /*Pin definitions*/
    #define LED_PIN         A3
    #define SECONDRELAY     3
    #define GARAGEPIN       4
    #define SWITCH_PIN      5
    #define RST_PIN         7       //  MFRC 
    #define SS_PIN          8       //  MFRC 
    #define DOOR_PIN_L  A0  // Arduino Digital I/O pin for button/reed switch
    #define DOOR_PIN_R  A1  // Arduino Digital I/O pin for button/reed switch
    
    
    MFRC522      mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance
    MFRC522::Uid olduid;
    MFRC522::Uid masterkey = { 10, {0,0,0,0, 0,0,0,0, 0,0 },  0 };
    
    byte       countValidCards  = 0;
    MFRC522::Uid validCards[MAX_CARDS];
    
    void       ShowCardData(MFRC522::Uid* uid);
    bool       sameUid(MFRC522::Uid* old, MFRC522::Uid* check);
    void       copyUid(MFRC522::Uid* src, MFRC522::Uid* dest);
    bool       isValidCard(MFRC522::Uid* uid);
    int        releasecnt = 0;
    
    #define    CHILD_ID_ALARM    1
    #define    CHILD_ID_LOCK     2
    #define    CHILD_ID_LOCK2    3
    #define    CHILD_ID_DOOR_L    4
    #define    CHILD_ID_DOOR_R    5
    
    MySensor   gw;
    Bounce     debouncer = Bounce();
    Bounce     debouncerDoorR = Bounce();
    Bounce     debouncerDoorL = Bounce();
    int oldValueR=-1;
    int oldValueL=-1;
    
    int        oldSwitchValue=-1;
    int        switchValue = 0;
    long       timer = -1;
    bool       programmode = false;
    bool       ledon;
    int        programTimer = 0;
    bool       armed = true;
    unsigned long lastTime = 0;
    
    MyMessage  lockMsg(CHILD_ID_LOCK,          V_LOCK_STATUS);
    MyMessage  lock2Msg(CHILD_ID_LOCK2,          V_LOCK_STATUS);
    MyMessage  lockArmMsg(CHILD_ID_ALARM,      V_ARMED);
    MyMessage  wrongMsg(CHILD_ID_ALARM,        V_TRIPPED);
    MyMessage  doorRmsg(CHILD_ID_DOOR_R, V_TRIPPED);
    MyMessage  doorLmsg(CHILD_ID_DOOR_L, V_TRIPPED);
    
    void setup() {
            Serial.begin(BAUD);     // Initialize serial communications with the PC
            pinMode(GARAGEPIN, OUTPUT);     // Initialise in/output ports
            pinMode(SECONDRELAY, OUTPUT);     // Initialise in/output ports
            
            // Make sure MFRC will be disabled on the SPI bus
            pinMode(RST_PIN, OUTPUT);     
            digitalWrite(RST_PIN, LOW);
            pinMode(SS_PIN, OUTPUT);     
            digitalWrite(SS_PIN, LOW);
    
            pinMode(LED_PIN, OUTPUT);
            digitalWrite(LED_PIN, LOW);
            // Setup the button
            pinMode(SWITCH_PIN, INPUT_PULLUP);
    
            // After setting up the button, setup debouncer
            debouncer.attach(SWITCH_PIN);
            debouncer.interval(5);
    
            // Setup the right door sensor
            pinMode(DOOR_PIN_R,INPUT);
            // Activate internal pull-up
            digitalWrite(DOOR_PIN_R,HIGH);
      
            // After setting up the button, setup debouncer
            debouncerDoorR.attach(DOOR_PIN_R);
            debouncerDoorR.interval(5);
            
            // Setup the left door sensor
            pinMode(DOOR_PIN_L,INPUT);
            // Activate internal pull-up
            digitalWrite(DOOR_PIN_L,HIGH);
      
            // After setting up the button, setup debouncer
            debouncerDoorL.attach(DOOR_PIN_L);
            debouncerDoorL.interval(5);
      
    
            // Init mysensors library
            gw.begin(incomingMessage, 5);
            gw.sendSketchInfo("RFID Garage", "1.2"); delay(RF_INIT_DELAY);
            
            // Register all sensors to gw (they will be created as child devices)
            gw.present(CHILD_ID_LOCK, S_LOCK);      delay(RF_INIT_DELAY);
            gw.present(CHILD_ID_LOCK2, S_LOCK);      delay(RF_INIT_DELAY);
            gw.present(CHILD_ID_ALARM, S_MOTION);   delay(RF_INIT_DELAY);
            gw.present(CHILD_ID_DOOR_R, S_DOOR); 
            gw.present(CHILD_ID_DOOR_L, S_DOOR); 
            
            recallEeprom();
            
            // Init MFRC RFID sensor
            SPI.begin();            // Init SPI bus
            mfrc522.PCD_Init();     // Init MFRC522
            ShowReaderDetails();            // Show details of PCD - MFRC522 Card Reader details
    
            gw.send(lockArmMsg.set(armed));
            Serial.println(F("Init done..."));
    }
    
    void loop() {
            timer++;
            delay(HEARTBEAT);
            gw.process();
            debouncer.update();
            debouncerDoorL.update();
            // Get the update value for Left
            int valueL = debouncerDoorL.read(); 
            if (valueL != oldValueL) {
               // Send in the new value for Left
               gw.send(doorLmsg.set(valueL==HIGH ? 1 : 0));
               oldValueL = valueL;
            }
            debouncerDoorR.update();
            // Get the update value for Right
            int valueR = debouncerDoorR.read();
            if (valueR != oldValueR) {
               // Send in the new value for Right
               gw.send(doorRmsg.set(valueR==HIGH ? 1 : 0));
               oldValueR = valueR;
            }
    
            // Get the update value
            int switchValue = debouncer.read();
            if (switchValue != oldSwitchValue) {
              // Send in the new value
              Serial.print (F("Switch "));
              Serial.println (switchValue);
              
              if (switchValue && programmode) {
                   lastTime     = millis() / 1000;
              }
              
              if (!switchValue && programmode && lastTime > 0) {
                   if ( (millis() / 1000) - lastTime > 3) {
                        Serial.println(F("Reset all cards"));  
                        countValidCards  = 0;
                        blinkFast(50);
                   } else {
                      Serial.println(F("Program off"));  
                      digitalWrite(LED_PIN, LOW);
                      programmode = false;
                      
                      storeEeprom();
                   }
              }
              
              if (!switchValue)   {
                  programTimer = 0;
              }
              oldSwitchValue = switchValue;
            }
            
            if (programmode && ((timer % (ONE_SEC / HEARTBEAT)) == 0 ))  {
                ledon = !ledon;
                digitalWrite(LED_PIN, ledon);
                programTimer++;
    
                // Stop program mode after 20 sec inactivity
                if (programTimer > PROG_WAIT)  {
                   programmode = false;
                   digitalWrite(LED_PIN, false);
                   Serial.println(F("Program expired"));  
                }
            }
            
            if ((timer % (200 / HEARTBEAT)) == 0 )   {
                 // Look for new cards
                 if ( ! mfrc522.PICC_IsNewCardPresent()) {
                      if (releasecnt > 0)   {
                          releasecnt--;
                          if (!releasecnt)  {
                              olduid.size = 0;
                              Serial.println(F("release"));
                          }
                        }
                return;
                }
                releasecnt = 5;
        
               // Select one of the cards
               if ( ! mfrc522.PICC_ReadCardSerial()) {
                  return;
               }
        
               // Dump debug info about the card; PICC_HaltA() is automatically called
               //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
               if (!olduid.size || !sameUid(&(mfrc522.uid), &olduid))  {
                    ShowCardData(&(mfrc522.uid));
                    copyUid(&(mfrc522.uid), &olduid);
                    if ( isValidCard(&olduid) )   {
                         OpenDoor(programmode);
                    } else  {
                       if (sameUid(&(mfrc522.uid), &masterkey)) {
                           // Only switch in program mode when mastercard is found AND the program button is pressed
                           if (switchValue)  {
                             Serial.println(F("Program mode"));
                             programmode = true;
                             programTimer = 0;
                             lastTime     = 0;
                           } else {
                             OpenDoor2(programmode);
                           }
                       } else {
                           if (programmode) {
                             Serial.println(F("new card"));
                             programTimer = 0;
                             
                             if (countValidCards < MAX_CARDS)
                             {
                                // Add card to list...
                                copyUid(&(mfrc522.uid), &validCards[countValidCards]);
                                countValidCards++;
                                blinkFast(15);
                             }
                           } else {
                             Serial.println(F("Invalid card"));
                             if (armed) {
                                gw.send(wrongMsg.set(1));
                                delay(2000);
                                gw.send(wrongMsg.set(0));
                             }
                           }
                       }
                    }
               }
            }
    }
    
    void ShowCardData(MFRC522::Uid* uid) 
    {
        Serial.print(F("Card UID:"));
        for (byte i = 0; i < uid->size; i++) {
            if(uid->uidByte[i] < 0x10) {
                Serial.print(F(" 0"));
            } else {
                Serial.print(F(" "));
                    }
            Serial.print(uid->uidByte[i], HEX);
        } 
        Serial.println();
    }
    
    void copyUid(MFRC522::Uid* src, MFRC522::Uid* dest)
    {
        dest->size = src->size;
        dest->sak  = src->sak;
        
        for (byte i = 0; i < src->size; i++) {
        dest->uidByte[i] = src->uidByte[i];
        }
    }
    
    bool sameUid(MFRC522::Uid* old, MFRC522::Uid* check)
    {
        if (old->size != check->size) {
           return false;
        }
        for (byte i = 0; i < old->size; i++) {
            if (old->uidByte[i] != check->uidByte[i]) {
                return false;
            }
        }
        return true;
    }
    
    bool isValidCard(MFRC522::Uid* uid)
    {
          for (byte i = 0; i < countValidCards; i++)  {
              if (validCards[i].size != uid->size)  {
                  break;
              }
              for (int j = 0; j < uid->size; j++) {
                  if (validCards[i].uidByte[j] != uid->uidByte[j])  {
                      break;
                  }
                  if (j == (uid->size - 1)) {  
                      return true;
                  }
              }
          }
          return false;
    }
    
    
    void storeEeprom()
    {
        byte address = 0;
        gw.saveState(address++, countValidCards);
        
        for (byte i = 0; i < countValidCards; i++) {
           gw.saveState(address++, validCards[i].size);
           for (byte j = 0; j < 10; j++) {
              gw.saveState(address++, validCards[i].uidByte[j]);
           } 
        }
    }
    
    void recallEeprom()
    {
        byte address = 0;
        
        countValidCards = gw.loadState(address++);
        if (countValidCards > MAX_CARDS) {
           Serial.println(F("Not a valid EEPROM reading set to default"));
           countValidCards = 0;
           storeEeprom();
           return;
        }
        
        for (byte i = 0; i < countValidCards; i++)  {
           validCards[i].size = gw.loadState(address++);
           for (byte j = 0; j < 10; j++)  {
              validCards[i].uidByte[j] = gw.loadState(address++);
           } 
        }
      
    }
    
    void blinkFast(int times)
    {
        for (int i = 0; i < times; i++) { 
           ledon = !ledon;
           digitalWrite(LED_PIN, ledon);
           delay(100);
        }
    }
    
    void OpenDoor(bool fakeOpen)
    {
        Serial.println(F("Open door!"));
        gw.send(lockMsg.set(false));
        
        if (!fakeOpen) { 
          digitalWrite(LED_PIN, HIGH);
          digitalWrite(GARAGEPIN, HIGH); 
        }
        delay(1000);
        
        if (!fakeOpen) { 
          digitalWrite(GARAGEPIN, LOW); 
          digitalWrite(LED_PIN, LOW);
        }
        
        gw.send(lockMsg.set(true));
    }
    
    void OpenDoor2(bool fakeOpen)
    {
        Serial.println(F("Open door 2!"));
        gw.send(lock2Msg.set(false));
        
        if (!fakeOpen) { 
          digitalWrite(LED_PIN, HIGH);
          digitalWrite(SECONDRELAY, HIGH); 
        }
        delay(1000);
        
        if (!fakeOpen) { 
          digitalWrite(SECONDRELAY, LOW); 
          digitalWrite(LED_PIN, LOW);
        }
        
        gw.send(lock2Msg.set(true));
    }
    
    void ShowReaderDetails() {
        // Get the MFRC522 software version
        byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
        Serial.print(F("MFRC522 Software Version: 0x"));
        Serial.print(v, HEX);
        if (v == 0x91) {
            Serial.print(F(" = v1.0"));
            } else if (v == 0x92) {
            Serial.print(F(" = v2.0"));
            } else {
            Serial.print(F(" (unknown)"));
            }
        Serial.println("");
        
            // When 0x00 or 0xFF is returned, communication probably failed
        if ((v == 0x00) || (v == 0xFF)) {
            Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
        }
    }
    
    
    void incomingMessage(const MyMessage &message) 
    {
       if (message.type == V_LOCK_STATUS) {
         // Change relay state
         if (!message.getBool())  {
            switch (message.sensor)
            {
               case CHILD_ID_LOCK:
                  OpenDoor(false);
                  break;
               case CHILD_ID_LOCK2:
                  OpenDoor2(false);
                  break;
            }
         }
      
         // Write some debug info
         Serial.print(F("Lock:  "));
         Serial.print(message.sensor);
         Serial.print(F(" status: "));
         Serial.println(message.getBool());
       }
       else 
       {
         if (message.type == V_ARMED)  {
           // Change relay state
           armed = message.getBool();
      
           // Write some debug info
           Serial.print(F("Arm status: "));
           Serial.println(message.getBool());
         }
         else
         {
           // Write some debug info
           Serial.print(F("Incoming msg type: "));
           Serial.print(message.type);
           Serial.print(F(" id: "));
           Serial.print(message.sensor);
           Serial.print(F(" content: "));
           Serial.println(message.getInt());
         }
       }
    }
    


  • Hi @BartE - thanks for putting this together! It has been very helpful.

    I am working on a project with two wireless MFRC522 modules and RFID Reader. I want to be able to read PICC cards with the RFID reader and send it the UID between the modules. So essentially a more bare version of the code you have written with the garage door opening code. I was wondering if you could help me out in simplifying the code to just reading the UID off the PICC cards and outputting that date between the RCF522 modules.

    Thanks in advance.


  • Contest Winner

    @codergirl56 there are a number of examples in the MFRC522 library which might help you.
    You can find them here: https://github.com/miguelbalboa/rfid

    Please feel free to ask questions if the examples does not help you further



  • @BartE thanks for getting back to me. I've looked through the examples on the MFRC522 library. I think the main thing I'm struggling with is setting up and initializing the N24L01 module and the RFID on the same arduino uno. My plan is to have one N24L01 and RFID on one arduino module, and a second N24L01 on a second arduino. I want the RFID to read the UID off of PICC cards and be able to wirelessly transmit the UID between the N24L01 modules. I think it's simpler than the code you have written here, but I'm struggling to simplify the code you have to only what I need. Could you possibly walk through what each function in your program is used for? Thanks in advance.


  • Contest Winner

    @codergirl56 Oke i will give it a try:

    Basic IO pin set up

    void setup() {
            Serial.begin(BAUD);     // Initialize serial communications with the PC
            pinMode(GARAGEPIN, OUTPUT);     // Initialise in/output ports
            pinMode(SECONDRELAY, OUTPUT);     // Initialise in/output ports
    

    This part initializes the SPI I/O pins used by the RFID reader so it release the SPI bus for thr NFR radio

            // Make sure MFRC will be disabled on the SPI bus
            pinMode(RST_PIN, OUTPUT);     
            digitalWrite(RST_PIN, LOW);
            pinMode(SS_PIN, OUTPUT);     
            digitalWrite(SS_PIN, LOW);
    

    Init LED and button I/O-pin

            pinMode(LED_PIN, OUTPUT);
            digitalWrite(LED_PIN, LOW);
            // Setup the button
            pinMode(SWITCH_PIN, INPUT_PULLUP);
    
            // After setting up the button, setup debouncer
            debouncer.attach(SWITCH_PIN);
            debouncer.interval(5);
    

    Init radion module

            // Init mysensors library
            gw.begin(incomingMessage, 5);
            gw.sendSketchInfo("RFID Garage", "1.2"); delay(RF_INIT_DELAY);
            
            // Register all sensors to gw (they will be created as child devices)
            gw.present(CHILD_ID_LOCK, S_LOCK);      delay(RF_INIT_DELAY);
            gw.present(CHILD_ID_LOCK2, S_LOCK);      delay(RF_INIT_DELAY);
            gw.present(CHILD_ID_ALARM, S_MOTION);   delay(RF_INIT_DELAY);
    

    Read eeprom settings

            recallEeprom();
    

    nit SPI bus for MFRC RFID sensor

            SPI.begin();            // Init SPI bus
            mfrc522.PCD_Init();     // Init MFRC522
            ShowReaderDetails();            // Show details of PCD - MFRC522 Card Reader details
    
            gw.send(lockArmMsg.set(armed));
            Serial.println(F("Init done..."));
    }
    
    void loop() {
            timer++;
            delay(HEARTBEAT);
            gw.process();
            debouncer.update();
    
            // Get the update value
            int switchValue = debouncer.read();
            if (switchValue != oldSwitchValue) {
              // Send in the new value
              Serial.print (F("Switch "));
              Serial.println (switchValue);
              
              if (switchValue && programmode) {
                   lastTime     = millis() / 1000;
              }
              
              if (!switchValue && programmode && lastTime > 0) {
                   if ( (millis() / 1000) - lastTime > 3) {
                        Serial.println(F("Reset all cards"));  
                        countValidCards  = 0;
                        blinkFast(50);
                   } else {
                      Serial.println(F("Program off"));  
                      digitalWrite(LED_PIN, LOW);
                      programmode = false;
                      
                      storeEeprom();
                   }
              }
              
              if (!switchValue)   {
                  programTimer = 0;
              }
              oldSwitchValue = switchValue;
            }
            
            if (programmode && ((timer % (ONE_SEC / HEARTBEAT)) == 0 ))  {
                ledon = !ledon;
                digitalWrite(LED_PIN, ledon);
                programTimer++;
    
                // Stop program mode after 20 sec inactivity
                if (programTimer > PROG_WAIT)  {
                   programmode = false;
                   digitalWrite(LED_PIN, false);
                   Serial.println(F("Program expired"));  
                }
            }
            
            if ((timer % (200 / HEARTBEAT)) == 0 )   {
                 // Look for new cards
                 if ( ! mfrc522.PICC_IsNewCardPresent()) {
                      if (releasecnt > 0)   {
                          releasecnt--;
                          if (!releasecnt)  {
                              olduid.size = 0;
                              Serial.println(F("release"));
                          }
                        }
                return;
                }
                releasecnt = 5;
    

    Check if a RFID card is held at the RFID reader if not: skip the rest and start over with loop()

               // Select one of the cards
               if ( ! mfrc522.PICC_ReadCardSerial()) {
                  return;
               }
        
               // Dump debug info about the card; PICC_HaltA() is automatically called
               //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
    

    Check if this card is the same as the previous loop if not enter the IF loop

               if (!olduid.size || !sameUid(&(mfrc522.uid), &olduid))  {
                    ShowCardData(&(mfrc522.uid));
                    copyUid(&(mfrc522.uid), &olduid);
                    if ( isValidCard(&olduid) )   {
                         OpenDoor(programmode);
                    } else  {
    

    Check if the master card was presented and the button was pressed enter program mode

                       if (sameUid(&(mfrc522.uid), &masterkey)) {
                           // Only switch in program mode when mastercard is found AND the program button is pressed
                           if (switchValue)  {
                             Serial.println(F("Program mode"));
                             programmode = true;
                             programTimer = 0;
                             lastTime     = 0;
                           } else {
                             OpenDoor2(programmode);
                           }
                       } else {
    

    If not the master card and this card in not known and we're in program mode add this as a new card

                           if (programmode) {
                             Serial.println(F("new card"));
                             programTimer = 0;
                             
                             if (countValidCards < MAX_CARDS)
                             {
                                // Add card to list...
                                copyUid(&(mfrc522.uid), &validCards[countValidCards]);
                                countValidCards++;
                                blinkFast(15);
                             }
                           } else {
                             Serial.println(F("Invalid card"));
                             if (armed) {
                                gw.send(wrongMsg.set(1));
                                delay(2000);
                                gw.send(wrongMsg.set(0));
                             }
                           }
                       }
                    }
               }
            }
    }
    

    These are support functions

    void ShowCardData(MFRC522::Uid* uid) 
    {
        Serial.print(F("Card UID:"));
        for (byte i = 0; i < uid->size; i++) {
            if(uid->uidByte[i] < 0x10) {
                Serial.print(F(" 0"));
            } else {
                Serial.print(F(" "));
                    }
            Serial.print(uid->uidByte[i], HEX);
        } 
        Serial.println();
    }
    
    void copyUid(MFRC522::Uid* src, MFRC522::Uid* dest)
    {
        dest->size = src->size;
        dest->sak  = src->sak;
        
        for (byte i = 0; i < src->size; i++) {
        dest->uidByte[i] = src->uidByte[i];
        }
    }
    
    bool sameUid(MFRC522::Uid* old, MFRC522::Uid* check)
    {
        if (old->size != check->size) {
           return false;
        }
        for (byte i = 0; i < old->size; i++) {
            if (old->uidByte[i] != check->uidByte[i]) {
                return false;
            }
        }
        return true;
    }
    
    bool isValidCard(MFRC522::Uid* uid)
    {
          for (byte i = 0; i < countValidCards; i++)  {
              if (validCards[i].size != uid->size)  {
                  break;
              }
              for (int j = 0; j < uid->size; j++) {
                  if (validCards[i].uidByte[j] != uid->uidByte[j])  {
                      break;
                  }
                  if (j == (uid->size - 1)) {  
                      return true;
                  }
              }
          }
          return false;
    }
    
    
    void storeEeprom()
    {
        byte address = 0;
        gw.saveState(address++, countValidCards);
        
        for (byte i = 0; i < countValidCards; i++) {
           gw.saveState(address++, validCards[i].size);
           for (byte j = 0; j < 10; j++) {
              gw.saveState(address++, validCards[i].uidByte[j]);
           } 
        }
    }
    
    void recallEeprom()
    {
        byte address = 0;
        
        countValidCards = gw.loadState(address++);
        if (countValidCards > MAX_CARDS) {
           Serial.println(F("Not a valid EEPROM reading set to default"));
           countValidCards = 0;
           storeEeprom();
           return;
        }
        
        for (byte i = 0; i < countValidCards; i++)  {
           validCards[i].size = gw.loadState(address++);
           for (byte j = 0; j < 10; j++)  {
              validCards[i].uidByte[j] = gw.loadState(address++);
           } 
        }
      
    }
    
    void blinkFast(int times)
    {
        for (int i = 0; i < times; i++) { 
           ledon = !ledon;
           digitalWrite(LED_PIN, ledon);
           delay(100);
        }
    }
    
    void OpenDoor(bool fakeOpen)
    {
        Serial.println(F("Open door!"));
        gw.send(lockMsg.set(false));
        
        if (!fakeOpen) { 
          digitalWrite(LED_PIN, HIGH);
          digitalWrite(GARAGEPIN, HIGH); 
        }
        delay(1000);
        
        if (!fakeOpen) { 
          digitalWrite(GARAGEPIN, LOW); 
          digitalWrite(LED_PIN, LOW);
        }
        
        gw.send(lockMsg.set(true));
    }
    
    void OpenDoor2(bool fakeOpen)
    {
        Serial.println(F("Open door 2!"));
        gw.send(lock2Msg.set(false));
        
        if (!fakeOpen) { 
          digitalWrite(LED_PIN, HIGH);
          digitalWrite(SECONDRELAY, HIGH); 
        }
        delay(1000);
        
        if (!fakeOpen) { 
          digitalWrite(SECONDRELAY, LOW); 
          digitalWrite(LED_PIN, LOW);
        }
        
        gw.send(lock2Msg.set(true));
    }
    
    void ShowReaderDetails() {
        // Get the MFRC522 software version
        byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
        Serial.print(F("MFRC522 Software Version: 0x"));
        Serial.print(v, HEX);
        if (v == 0x91) {
            Serial.print(F(" = v1.0"));
            } else if (v == 0x92) {
            Serial.print(F(" = v2.0"));
            } else {
            Serial.print(F(" (unknown)"));
            }
        Serial.println("");
        
            // When 0x00 or 0xFF is returned, communication probably failed
        if ((v == 0x00) || (v == 0xFF)) {
            Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
        }
    }
    
    
    void incomingMessage(const MyMessage &message) 
    {
       if (message.type == V_LOCK_STATUS) {
         // Change relay state
         if (!message.getBool())  {
            switch (message.sensor)
            {
               case CHILD_ID_LOCK:
                  OpenDoor(false);
                  break;
               case CHILD_ID_LOCK2:
                  OpenDoor2(false);
                  break;
            }
         }
      
         // Write some debug info
         Serial.print(F("Lock:  "));
         Serial.print(message.sensor);
         Serial.print(F(" status: "));
         Serial.println(message.getBool());
       }
       else 
       {
         if (message.type == V_ARMED)  {
           // Change relay state
           armed = message.getBool();
      
           // Write some debug info
           Serial.print(F("Arm status: "));
           Serial.println(message.getBool());
         }
         else
         {
           // Write some debug info
           Serial.print(F("Incoming msg type: "));
           Serial.print(message.type);
           Serial.print(F(" id: "));
           Serial.print(message.sensor);
           Serial.print(F(" content: "));
           Serial.println(message.getInt());
         }
       }
    }


  • @BartE

    Hi BartE, I have the same issue regarding tags lost after power off. I run the debug instruction using Serial print as you mentioned. I found out that the storeEeprom line did not run after closing the program mode. I think this is why the tags are lost after power cycle.

    send: 210-210-0-0 s=255,c=3,t=15,pt=2,l=2,sg=0,st=ok:0
    send: 210-210-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.4
    send: 210-210-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
    read: 0-0-210 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    sensor started, id=210, parent=0, distance=1
    send: 210-210-0-0 s=255,c=3,t=11,pt=0,l=9,sg=0,st=ok:RFID Lock
    send: 210-210-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.1
    send: 210-210-0-0 s=2,c=0,t=19,pt=0,l=0,sg=0,st=ok:
    send: 210-210-0-0 s=1,c=0,t=1,pt=0,l=0,sg=0,st=ok:
    RecallEeprom
    MFRC522 Software Version: 0x92 = v2.0
    send: 210-210-0-0 s=1,c=1,t=15,pt=2,l=2,sg=0,st=ok:1
    Init done...
    Switch 1
    Card UID: 26 13 80 41
    Invalid card
    send: 210-210-0-0 s=1,c=1,t=16,pt=2,l=2,sg=0,st=ok:1
    send: 210-210-0-0 s=1,c=1,t=16,pt=2,l=2,sg=0,st=ok:0
    release
    Card UID: xx xx xx xx
    Program mode
    release
    Card UID: xx xx xx xx
    new card
    release
    Program expired
    

    Thanks



  • @BartE

    I've just solved the issue regarding tags lost after power off.

    Simply add the line "StoreEeprom();" after the program mode function

      if (programmode && ((timer % (ONE_SEC / HEARTBEAT)) == 0 ))  {
                ledon = !ledon;
                digitalWrite(LED_PIN, ledon);
                programTimer++;
    
                // Stop program mode after 20 sec inactivity
                if (programTimer > PROG_WAIT)  {
                   programmode = false;
                   digitalWrite(LED_PIN, false);
                   Serial.println(F("Program expired"));  
    
                   storeEeprom();
                   Serial.println(F("Store Card to EEPROM"));  ```

  • Contest Winner

    @Chakkie sorry for the slow response (i was on a pre summer holiday)

    Thx for analyzing this report. The fix you did made is not what i meant with program expired.

    The idea is that you start program mode by pressing the program button and holding the master card.
    And now one can add one or more new RFID cards and when your oke press the program button for a short period to END the program mode and store the new cards.

    If you wait too long the program mode will expire and the new cards are NOT stored. Off course you can change this behavior by adding this line as you suggested.



  • hello to all guys, I noticed some problems, if the power goes away there is a flaw in the system. I modified the source as needed to me, now you turn the sensor on domoticz when you turn on and off when you turn off. I modified the project to create an alarm homemade I configured via lua script the motion sensors. I mounted on the bell so as to turn on and off when I go out or within the home. thank you all

    0_1464953572731_rfidCompreto.jpg 0_1464953579700_rfidmoduloporta-180x180.jpg 0_1464953586849_rfidcentralina-180x180.jpg
    0_1464953864460_mysensor nano+radio+rfid_pcb.jpg
    0_1464954180603_allarm.jpg



  • Hi Everyone,
    I have tested this code http://etabetastudio.blogspot.it/2016/07/tutorial-lettore-rfid-rc522-arduino-idea.html to test RFID RC-522 with Arduino 2009 and all is ok, also to registred RFID card on EEPROM...
    I hope to help uo...bye



  • Dear All,

    I'm a newbie and I found in MySensors website the project for RFID Lock Sensors that use PN532 RFID Reader, but as I already have with me a RC-522 RFID reader, searching on the forum I found this post that I thinked it will suit my case.

    I assembled the various hardware parts as described on first post, but when I copied the sketch code in my arduino IDE, I'm not able to get it work.

    I get some error message that is not so clear for me.

    It's seems the sketch is for a previous version of MySensors Library or Arduino IDE, but I'm not sure of this.

    As I use Arduino IDE 1.6.12 that has included MySensors Library 2.0.0, is the Sketch you included in the first post already valid for that setup ?

    It' will be possible to have a valid sketch working with new setup or eventually to know how to proceed to make the actual one working ?

    Thank you in advance for your attention.



  • @Mercury69
    It was written prior to the MySensors 2.0 update.

    You can convert pre- 2.0 sketches by following the instructions on https://forum.mysensors.org/topic/4276/converting-a-sketch-from-1-5-x-to-2-0-x

    If you need a hand just post here with your question, I'll try to help, but it's really not too bad once you get started. I'm in the process of converting all of my code to 2.0 as well.



  • @Rod-MacPherson
    Dear Rod, thank you for the suggestion you gave me.
    Following the instruction you indicated me, I was able to make the sketch working with new MySensors 2.0 library.

    Considering that I'm not a programmer, it was quite easy to make the sketch working.

    Thank you again for your suggestion and off course thank you to BartE for the good original work he did.

    If someone need new sketch working with library 2.0, feel free to ask me.



  • @Mercury69 you can post the sketch ?



  • @Mercury69 I would also love to have a look at your scetch!



  • @Mercury69

    Please, I would also like to see your code if it possible.



  • Hi Rod

    Can you modify your code for 2.0 lib ?

    Thank you
    Andrey


  • Mod

    Here is the new code for lib 2.0, but I am having some problem with initialization of rc522. I connected RST tu D7 and SDA to D8. Any idea what to look for?

    /*
    * ----------------------------------------------------------------------------
    * This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
    * for further details and other examples.
    *
    * NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
    *
    * Released into the public domain.
    * ----------------------------------------------------------------------------
    * Example sketch/program showing how to read data from a PICC (that is: a RFID
    * Tag or Card) using a MFRC522 based RFID Reader on the Arduino SPI interface.
    *
    * When the Arduino and the MFRC522 module are connected (see the pin layout
    * below), load this sketch into Arduino IDE then verify/compile and upload it.
    * To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M).
    * When you present a PICC (that is: a RFID Tag or Card) at reading distance
    * of the MFRC522 Reader/PCD, the serial output will show the ID/UID, type and
    * any data blocks it can read. Note: you may see "Timeout in communication"
    * messages when removing the PICC from reading distance too early.
    *
    * If your reader supports it, this sketch/program will read all the PICCs
    * presented (that is: multiple tag reading). So if you stack two or more
    * PICCs on top of each other and present them to the reader, it will first
    * output all details of the first and then the next PICC. Note that this
    * may take some time as all data blocks are dumped, so keep the PICCs at
    * reading distance until complete.
    *
    * Typical pin layout used:
    * -----------------------------------------------------------------------------------------
    *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
    *             Reader/PCD   Uno           Mega      Nano v3    Leonardo/Micro   Pro Micro
    * Signal      Pin          Pin           Pin       Pin        Pin              Pin
    * -----------------------------------------------------------------------------------------
    * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
    * SPI SS      SDA(SS)      10            53        D10        10               10
    * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
    * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
    * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
    */
    
    /*
    RFID Garagedoor opener by Bart Eversdijk
    
    This sketch is to open a Garage door with an mifare RIFD-tag
    
    For an Arduino Nano v3
    Connection wiring :
    - nrf24l01+ as descibed on the MySensors website
    - MFRC522 reader/writer as described above EXCEPT for pin D9 and D10:  connect RST i.s.o. pin D9 to pin D7 and connect SDA(SS) i.s.o. pin D10 to pin D8
    - LED with 470ohm resistor between GMD and pin A3
    - push button between GND and pin D5
    - 5v relays coil between GND and  pin D4 -> switch pins of the relays should be connected in parallel with your garage door push button.
    
    Features:
    This project can record up to 18 RFID-"tags"
    These card IDs are stored in to EEPROM by keeping them next to the RFID reader when the system in program mode. (Slow blinking LED) When a card is accepted as new card the LED will blink fast for a short time.
    To keep the master-tags (choose your own) next to the RFID reader when pressing the push button. To clear all cards (except the master card) press the push button in program mode for 6 seconds. The LED will now fast blink for a couple of seconds.
    
    Your garage your can be opened by keep a registered RFID tag next to the reader or by clicking the open icon on lock node presented by this plugin.
    By by-passing the alarm node presented by this plug in the RFID will be temporarily disabled.
    When an incorrect (not registered) RFID tag is scanned the alarm is triggered to detect illegal scan attempts
    
    */ 
    #include <MySensors.h>
    #include <SPI.h>
    #include <MFRC522.h> 
    #include <Bounce2.h>
    
    #define RF_INIT_DELAY   125
    #define ONE_SEC         1000
    #define MAX_CARDS       18
    #define PROG_WAIT       10
    #define HEARTBEAT       10
    #define BAUD            115200
    
    /*Pin definitions*/
    #define LED_PIN         A3
    #define GARAGEPIN       4
    #define SWITCH_PIN      5
    #define RST_PIN		7		//  MFRC 
    #define SS_PIN		8		//  MFRC 
    
    MFRC522      mfrc522(SS_PIN, RST_PIN);	// Create MFRC522 instance
    MFRC522::Uid olduid;
    MFRC522::Uid masterkey = { 10,{ 0,0,0,0, 0,0,0,0, 0,0 },  0 };
    
    byte       countValidCards = 0;
    MFRC522::Uid validCards[MAX_CARDS];
    
    void       ShowCardData(MFRC522::Uid* uid);
    bool       sameUid(MFRC522::Uid* old, MFRC522::Uid* check);
    void       copyUid(MFRC522::Uid* src, MFRC522::Uid* dest);
    bool       isValidCard(MFRC522::Uid* uid);
    int        releasecnt = 0;
    
    #define    CHILD_ID_ALARM    1
    #define    CHILD_ID_LOCK     2
    Bounce     debouncer = Bounce();
    
    int        oldSwitchValue = -1;
    int        switchValue = 0;
    long       timer = -1;
    bool       programmode = false;
    bool       ledon;
    int        programTimer = 0;
    bool       armed = true;
    unsigned long lastTime = 0;
    
    MyMessage  lockMsg(CHILD_ID_LOCK, V_LOCK_STATUS);
    MyMessage  lockArmMsg(CHILD_ID_ALARM, V_ARMED);
    MyMessage  wrongMsg(CHILD_ID_ALARM, V_TRIPPED);
    
    void setup() {
    	Serial.begin(BAUD);		// Initialize serial communications with the PC
    	pinMode(GARAGEPIN, OUTPUT);     // Initialise in/output ports
    
    									// Make sure MFRC will be disabled on the SPI bus
    	pinMode(RST_PIN, OUTPUT);
    	digitalWrite(RST_PIN, LOW);
    	pinMode(SS_PIN, OUTPUT);
    	digitalWrite(SS_PIN, LOW);
    
    	pinMode(LED_PIN, OUTPUT);
    	digitalWrite(LED_PIN, LOW);
    	// Setup the button
    	pinMode(SWITCH_PIN, INPUT);
    	// Activate internal pull-up
    	digitalWrite(SWITCH_PIN, HIGH);
    
    	// After setting up the button, setup debouncer
    	debouncer.attach(SWITCH_PIN);
    	debouncer.interval(5);
    
    	// Init mysensors library
    	
    	sendSketchInfo("RFID Garage", "1.1"); delay(RF_INIT_DELAY);
    
    	// Register all sensors to gw (they will be created as child devices)
    	present(CHILD_ID_LOCK, S_LOCK);      delay(RF_INIT_DELAY);
    	present(CHILD_ID_ALARM, S_MOTION);   delay(RF_INIT_DELAY);
    
    	recallEeprom();
    
    	// Init MFRC RFID sensor
    	SPI.begin();			// Init SPI bus
    	mfrc522.PCD_Init();		// Init MFRC522
    	ShowReaderDetails();	        // Show details of PCD - MFRC522 Card Reader details
    
    	send(lockArmMsg.set(armed));
    	Serial.println(F("Init done..."));
    }
    
    void loop() {
    	timer++;
    	delay(HEARTBEAT);
    	debouncer.update();
    
    	// Get the update value
    	int switchValue = debouncer.read();
    	if (switchValue != oldSwitchValue) {
    		// Send in the new value
    		Serial.print(F("Switch "));
    		Serial.println(switchValue);
    
    		if (switchValue && programmode) {
    			lastTime = millis() / 1000;
    		}
    
    		if (!switchValue && programmode && lastTime > 0) {
    			if ((millis() / 1000) - lastTime > 3) {
    				Serial.println(F("Reset all cards"));
    				countValidCards = 0;
    				blinkFast(50);
    			}
    			else {
    				Serial.println(F("Program off"));
    				digitalWrite(LED_PIN, LOW);
    				programmode = false;
    
    				storeEeprom();
    			}
    		}
    
    		if (!switchValue) {
    			programTimer = 0;
    		}
    		oldSwitchValue = switchValue;
    	}
    
    	if (programmode && ((timer % (ONE_SEC / HEARTBEAT)) == 0)) {
    		ledon = !ledon;
    		digitalWrite(LED_PIN, ledon);
    		programTimer++;
    
    		// Stop program mode after 20 sec inactivity
    		if (programTimer > PROG_WAIT) {
    			programmode = false;
    			digitalWrite(LED_PIN, false);
    			Serial.println(F("Program expired"));
    		}
    	}
    
    	if ((timer % (200 / HEARTBEAT)) == 0) {
    		// Look for new cards
    		if (!mfrc522.PICC_IsNewCardPresent()) {
    			if (releasecnt > 0) {
    				releasecnt--;
    				if (!releasecnt) {
    					olduid.size = 0;
    					Serial.println(F("release"));
    				}
    			}
    			return;
    		}
    		releasecnt = 5;
    
    		// Select one of the cards
    		if (!mfrc522.PICC_ReadCardSerial()) {
    			return;
    		}
    
    		// Dump debug info about the card; PICC_HaltA() is automatically called
    		//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
    		if (!olduid.size || !sameUid(&(mfrc522.uid), &olduid)) {
    			ShowCardData(&(mfrc522.uid));
    			copyUid(&(mfrc522.uid), &olduid);
    			if (isValidCard(&olduid)) {
    				OpenDoor(programmode);
    			}
    			else {
    
    				if (sameUid(&(mfrc522.uid), &masterkey)) {
    					// Only switch in program mode when mastercard is found AND the program button is pressed
    					if (switchValue) {
    						Serial.println(F("Program mode"));
    						programmode = true;
    						programTimer = 0;
    						lastTime = 0;
    					}
    				}
    				else {
    					if (programmode) {
    						Serial.println(F("new card"));
    						programTimer = 0;
    
    						if (countValidCards < MAX_CARDS)
    						{
    							// Add card to list...
    							copyUid(&(mfrc522.uid), &validCards[countValidCards]);
    							countValidCards++;
    							blinkFast(15);
    						}
    					}
    					else {
    						Serial.println(F("Invalid card"));
    						if (armed) {
    							send(wrongMsg.set(1));
    							delay(2000);
    							send(wrongMsg.set(0));
    						}
    					}
    				}
    			}
    		}
    	}
    }
    
    void ShowCardData(MFRC522::Uid* uid) {
    	Serial.print(F("Card UID:"));
    	for (byte i = 0; i < uid->size; i++) {
    		if (uid->uidByte[i] < 0x10) {
    			Serial.print(F(" 0"));
    		}
    		else {
    			Serial.print(F(" "));
    		}
    		Serial.print(uid->uidByte[i], HEX);
    	}
    	Serial.println();
    }
    
    void copyUid(MFRC522::Uid* src, MFRC522::Uid* dest)
    {
    	dest->size = src->size;
    	dest->sak = src->sak;
    
    	for (byte i = 0; i < src->size; i++) {
    		dest->uidByte[i] = src->uidByte[i];
    	}
    }
    
    bool sameUid(MFRC522::Uid* old, MFRC522::Uid* check)
    {
    	if (old->size != check->size) {
    		return false;
    	}
    	for (byte i = 0; i < old->size; i++) {
    		if (old->uidByte[i] != check->uidByte[i]) {
    			return false;
    		}
    	}
    	return true;
    }
    
    bool isValidCard(MFRC522::Uid* uid)
    {
    	for (byte i = 0; i < countValidCards; i++) {
    		if (validCards[i].size != uid->size) {
    			break;
    		}
    		for (int j = 0; j < uid->size; j++) {
    			if (validCards[i].uidByte[j] != uid->uidByte[j]) {
    				break;
    			}
    			if (j == (uid->size - 1)) {
    				return true;
    			}
    		}
    	}
    	return false;
    }
    
    
    void storeEeprom()
    {
    	byte address = 0;
    	saveState(address++, countValidCards);
    
    	for (byte i = 0; i < countValidCards; i++) {
    		saveState(address++, validCards[i].size);
    		for (byte j = 0; j < 10; j++) {
    			saveState(address++, validCards[i].uidByte[j]);
    		}
    	}
    }
    
    void recallEeprom()
    {
    	byte address = 0;
    
    	countValidCards = loadState(address++);
    	if (countValidCards > MAX_CARDS) {
    		Serial.println(F("Not a valid EEPROM reading set to default"));
    		countValidCards = 0;
    		storeEeprom();
    		return;
    	}
    
    	for (byte i = 0; i < countValidCards; i++) {
    		validCards[i].size = loadState(address++);
    		for (byte j = 0; j < 10; j++) {
    			validCards[i].uidByte[j] = loadState(address++);
    		}
    	}
    
    }
    
    void blinkFast(int times)
    {
    	for (int i = 0; i < times; i++) {
    		ledon = !ledon;
    		digitalWrite(LED_PIN, ledon);
    		delay(100);
    	}
    }
    
    void OpenDoor(bool fakeOpen)
    {
    	Serial.println(F("Open door!"));
    	send(lockMsg.set(false));
    
    	if (!fakeOpen) {
    		digitalWrite(LED_PIN, HIGH);
    		digitalWrite(GARAGEPIN, HIGH);
    	}
    	delay(1000);
    
    	if (!fakeOpen) {
    		digitalWrite(GARAGEPIN, LOW);
    		digitalWrite(LED_PIN, LOW);
    	}
    
    	send(lockMsg.set(true));
    }
    
    void ShowReaderDetails() {
    	// Get the MFRC522 software version
    	byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
    	Serial.print(F("MFRC522 Software Version: 0x"));
    	Serial.print(v, HEX);
    	if (v == 0x91) {
    		Serial.print(F(" = v1.0"));
    	}
    	else if (v == 0x92) {
    		Serial.print(F(" = v2.0"));
    	}
    	else {
    		Serial.print(F(" (unknown)"));
    	}
    	Serial.println("");
    
    	// When 0x00 or 0xFF is returned, communication probably failed
    	if ((v == 0x00) || (v == 0xFF)) {
    		Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
    	}
    }
    
    
    void incomingMessage(const MyMessage &message)
    {
    	if (message.type == V_LOCK_STATUS) {
    		// Change relay state
    		if (!message.getBool()) {
    			OpenDoor(false);
    		}
    
    		// Write some debug info
    		Serial.print(F("Lock status: "));
    		Serial.println(message.getBool());
    	}
    	else
    	{
    		if (message.type == V_ARMED) {
    			// Change relay state
    			armed = message.getBool();
    
    			// Write some debug info
    			Serial.print(F("Arm status: "));
    			Serial.println(message.getBool());
    		}
    		else
    		{
    			// Write some debug info
    			Serial.print(F("Incoming msg type: "));
    			Serial.print(message.type);
    			Serial.print(F(" id: "));
    			Serial.print(message.sensor);
    			Serial.print(F(" content: "));
    			Serial.println(message.getInt());
    		}
    	}
    }
    

  • Contest Winner

    @gohan the MIFARE chip needs to be disabled from the SPI bus before the radio is initialized

    so put this piece of code in the before() function

    void before() {
    	// Make sure MFRC is disabled from the SPI bus
    	pinMode(RST_PIN, OUTPUT);
    	digitalWrite(RST_PIN, LOW);
    	pinMode(SS_PIN, OUTPUT);
    	digitalWrite(SS_PIN, LOW);
    }
    

    The MySensors library will iniitialize the MyS before the setup() function but after the before()

    these lines

    sendSketchInfo("RFID Garage", "1.1"); delay(RF_INIT_DELAY);
    // Register all sensors to gw (they will be created as child devices)
    present(CHILD_ID_LOCK, S_LOCK);      delay(RF_INIT_DELAY);
    present(CHILD_ID_ALARM, S_MOTION);   delay(RF_INIT_DELAY);
    

    Should be part of

    void presentation() {
         sendSketchInfo("RFID Garage", "1.1"); delay(RF_INIT_DELAY);
         // Register all sensors to gw (they will be created as child devices)
         
         present(CHILD_ID_LOCK, S_LOCK);      delay(RF_INIT_DELAY);
         present(CHILD_ID_ALARM, S_MOTION);   delay(RF_INIT_DELAY);
    }
    

    and the function:

    void incomingMessage(const MyMessage &message) 
    

    should be renamed to

    void receive(const MyMessage &message)
    

  • Mod

    It didn't change much, here is the log

    0 MCO:BGN:INIT NODE,CP=RNNNA--,VER=2.1.1
    3 MCO:BGN:BFR
    4 TSM:INIT
    5 TSF:WUR:MS=0
    13 TSM:INIT:TSP OK
    14 TSM:INIT:STATID=4
    16 TSF:SID:OK,ID=4
    18 TSM:FPAR
    59 TSF:MSG:SEND,4-4-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    803 TSF:MSG:READ,0-0-4,s=255,c=3,t=8,pt=1,l=1,sg=0:0
    808 TSF:MSG:FPAR OK,ID=0,D=1
    2067 TSM:FPAR:OK
    2068 TSM:ID
    2069 TSM:ID:OK
    2071 TSM:UPL
    2075 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
    2082 TSF:MSG:READ,0-0-4,s=255,c=3,t=25,pt=1,l=1,sg=0:1
    2087 TSF:MSG:PONG RECV,HP=1
    2089 TSM:UPL:OK
    2092 TSM:READY:ID=4,PAR=0,DIS=1
    2135 !TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=NACK:0100
    4143 TSF:MSG:SEND,4-4-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=1,st=OK:2.1.1
    4152 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0
    4250 TSF:MSG:READ,0-0-4,s=255,c=3,t=6,pt=0,l=1,sg=0:M
    4261 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=11,pt=0,l=11,sg=0,ft=0,st=OK:RFID Garage
    4272 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:1.1
    4406 TSF:MSG:SEND,4-4-0-0,s=2,c=0,t=19,pt=0,l=0,sg=0,ft=0,st=OK:
    4539 TSF:MSG:SEND,4-4-0-0,s=1,c=0,t=1,pt=0,l=0,sg=0,ft=0,st=OK:
    4670 MCO:REG:REQ
    4674 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
    4685 TSF:MSG:READ,0-0-4,s=255,c=3,t=27,pt=1,l=1,sg=0:1
    4690 MCO:PIM:NODE REG=1
    4692 MCO:BGN:STP
    MFRC522 Software Version: 0x0 (unknown)
    WARNING: Communication failure, is the MFRC522 properly connected?
    4755 TSF:MSG:SEND,4-4-0-0,s=1,c=1,t=15,pt=1,l=1,sg=0,ft=0,st=OK:1
    Init done...
    4761 MCO:BGN:INIT OK,TSP=1
    Switch 1
    

    Here is also the code with the changes you suggested

    /*
    * ----------------------------------------------------------------------------
    * This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
    * for further details and other examples.
    *
    * NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
    *
    * Released into the public domain.
    * ----------------------------------------------------------------------------
    * Example sketch/program showing how to read data from a PICC (that is: a RFID
    * Tag or Card) using a MFRC522 based RFID Reader on the Arduino SPI interface.
    *
    * When the Arduino and the MFRC522 module are connected (see the pin layout
    * below), load this sketch into Arduino IDE then verify/compile and upload it.
    * To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M).
    * When you present a PICC (that is: a RFID Tag or Card) at reading distance
    * of the MFRC522 Reader/PCD, the serial output will show the ID/UID, type and
    * any data blocks it can read. Note: you may see "Timeout in communication"
    * messages when removing the PICC from reading distance too early.
    *
    * If your reader supports it, this sketch/program will read all the PICCs
    * presented (that is: multiple tag reading). So if you stack two or more
    * PICCs on top of each other and present them to the reader, it will first
    * output all details of the first and then the next PICC. Note that this
    * may take some time as all data blocks are dumped, so keep the PICCs at
    * reading distance until complete.
    *
    * Typical pin layout used:
    * -----------------------------------------------------------------------------------------
    *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
    *             Reader/PCD   Uno           Mega      Nano v3    Leonardo/Micro   Pro Micro
    * Signal      Pin          Pin           Pin       Pin        Pin              Pin
    * -----------------------------------------------------------------------------------------
    * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
    * SPI SS      SDA(SS)      10            53        D10        10               10
    * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
    * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
    * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
    */
    
    /*
    RFID Garagedoor opener by Bart Eversdijk
    
    This sketch is to open a Garage door with an mifare RIFD-tag
    
    For an Arduino Nano v3
    Connection wiring :
    - nrf24l01+ as descibed on the MySensors website
    - MFRC522 reader/writer as described above EXCEPT for pin D9 and D10:  connect RST i.s.o. pin D9 to pin D7 and connect SDA(SS) i.s.o. pin D10 to pin D8
    - LED with 470ohm resistor between GMD and pin A3
    - push button between GND and pin D5
    - 5v relays coil between GND and  pin D4 -> switch pins of the relays should be connected in parallel with your garage door push button.
    
    Features:
    This project can record up to 18 RFID-"tags"
    These card IDs are stored in to EEPROM by keeping them next to the RFID reader when the system in program mode. (Slow blinking LED) When a card is accepted as new card the LED will blink fast for a short time.
    To keep the master-tags (choose your own) next to the RFID reader when pressing the push button. To clear all cards (except the master card) press the push button in program mode for 6 seconds. The LED will now fast blink for a couple of seconds.
    
    Your garage your can be opened by keep a registered RFID tag next to the reader or by clicking the open icon on lock node presented by this plugin.
    By by-passing the alarm node presented by this plug in the RFID will be temporarily disabled.
    When an incorrect (not registered) RFID tag is scanned the alarm is triggered to detect illegal scan attempts
    
    */
    // Enable debug prints
    #define MY_DEBUG
    #define MY_NODE_ID 4
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    #define MY_RF24_CHANNEL	10 
    #include <MySensors.h>
    #include <SPI.h>
    #include <MFRC522.h> 
    #include <Bounce2.h>
    
    #define RF_INIT_DELAY   125
    #define ONE_SEC         1000
    #define MAX_CARDS       18
    #define PROG_WAIT       10
    #define HEARTBEAT       10
    #define BAUD            115200
    
    /*Pin definitions*/
    #define LED_PIN         A3
    #define GARAGEPIN       4
    #define SWITCH_PIN      5
    #define RST_PIN		7		//  MFRC 
    #define SS_PIN		8		//  MFRC 
    
    MFRC522      mfrc522(SS_PIN, RST_PIN);	// Create MFRC522 instance
    MFRC522::Uid olduid;
    MFRC522::Uid masterkey = { 4,{ 0xC6,0x35,0x5D,0x8E},  0 };
    
    byte       countValidCards = 0;
    MFRC522::Uid validCards[MAX_CARDS];
    
    void       ShowCardData(MFRC522::Uid* uid);
    bool       sameUid(MFRC522::Uid* old, MFRC522::Uid* check);
    void       copyUid(MFRC522::Uid* src, MFRC522::Uid* dest);
    bool       isValidCard(MFRC522::Uid* uid);
    int        releasecnt = 0;
    
    #define    CHILD_ID_ALARM    1
    #define    CHILD_ID_LOCK     2
    Bounce     debouncer = Bounce();
    
    int        oldSwitchValue = -1;
    int        switchValue = 0;
    long       timer = -1;
    bool       programmode = false;
    bool       ledon;
    int        programTimer = 0;
    bool       armed = true;
    unsigned long lastTime = 0;
    
    MyMessage  lockMsg(CHILD_ID_LOCK, V_LOCK_STATUS);
    MyMessage  lockArmMsg(CHILD_ID_ALARM, V_ARMED);
    MyMessage  wrongMsg(CHILD_ID_ALARM, V_TRIPPED);
    
    void before() {
    	// Make sure MFRC is disabled from the SPI bus
    	pinMode(RST_PIN, OUTPUT);
    	digitalWrite(RST_PIN, LOW);
    	pinMode(SS_PIN, OUTPUT);
    	digitalWrite(SS_PIN, LOW);
    }
    
    void presentation() {
    	sendSketchInfo("RFID Garage", "1.1"); delay(RF_INIT_DELAY);
    	// Register all sensors to gw (they will be created as child devices)
    
    	present(CHILD_ID_LOCK, S_LOCK);      delay(RF_INIT_DELAY);
    	present(CHILD_ID_ALARM, S_MOTION);   delay(RF_INIT_DELAY);
    }
    
    void setup() {
    	Serial.begin(BAUD);		// Initialize serial communications with the PC
    	pinMode(GARAGEPIN, OUTPUT);     // Initialise in/output ports
    
    									// Make sure MFRC will be disabled on the SPI bus
    	/*pinMode(RST_PIN, OUTPUT);
    	digitalWrite(RST_PIN, LOW);
    	pinMode(SS_PIN, OUTPUT);
    	digitalWrite(SS_PIN, LOW);*/
    
    	pinMode(LED_PIN, OUTPUT);
    	digitalWrite(LED_PIN, LOW);
    	// Setup the button
    	pinMode(SWITCH_PIN, INPUT);
    	// Activate internal pull-up
    	digitalWrite(SWITCH_PIN, HIGH);
    
    	// After setting up the button, setup debouncer
    	debouncer.attach(SWITCH_PIN);
    	debouncer.interval(5);
    
    	// Init mysensors library
    	
    	/*sendSketchInfo("RFID Garage", "1.1"); delay(RF_INIT_DELAY);
    
    	// Register all sensors to gw (they will be created as child devices)
    	present(CHILD_ID_LOCK, S_LOCK);      delay(RF_INIT_DELAY);
    	present(CHILD_ID_ALARM, S_MOTION);   delay(RF_INIT_DELAY);*/
    
    	recallEeprom();
    
    	// Init MFRC RFID sensor
    	SPI.begin();			// Init SPI bus
    	mfrc522.PCD_Init();		// Init MFRC522
    	ShowReaderDetails();	        // Show details of PCD - MFRC522 Card Reader details
    
    	send(lockArmMsg.set(armed));
    	Serial.println(F("Init done..."));
    }
    
    void loop() {
    	timer++;
    	delay(HEARTBEAT);
    	debouncer.update();
    
    	// Get the update value
    	int switchValue = debouncer.read();
    	if (switchValue != oldSwitchValue) {
    		// Send in the new value
    		Serial.print(F("Switch "));
    		Serial.println(switchValue);
    
    		if (switchValue && programmode) {
    			lastTime = millis() / 1000;
    		}
    
    		if (!switchValue && programmode && lastTime > 0) {
    			if ((millis() / 1000) - lastTime > 3) {
    				Serial.println(F("Reset all cards"));
    				countValidCards = 0;
    				blinkFast(50);
    			}
    			else {
    				Serial.println(F("Program off"));
    				digitalWrite(LED_PIN, LOW);
    				programmode = false;
    
    				storeEeprom();
    			}
    		}
    
    		if (!switchValue) {
    			programTimer = 0;
    		}
    		oldSwitchValue = switchValue;
    	}
    
    	if (programmode && ((timer % (ONE_SEC / HEARTBEAT)) == 0)) {
    		ledon = !ledon;
    		digitalWrite(LED_PIN, ledon);
    		programTimer++;
    
    		// Stop program mode after 20 sec inactivity
    		if (programTimer > PROG_WAIT) {
    			programmode = false;
    			digitalWrite(LED_PIN, false);
    			Serial.println(F("Program expired"));
    		}
    	}
    
    	if ((timer % (200 / HEARTBEAT)) == 0) {
    		// Look for new cards
    		if (!mfrc522.PICC_IsNewCardPresent()) {
    			if (releasecnt > 0) {
    				releasecnt--;
    				if (!releasecnt) {
    					olduid.size = 0;
    					Serial.println(F("release"));
    				}
    			}
    			return;
    		}
    		releasecnt = 5;
    
    		// Select one of the cards
    		if (!mfrc522.PICC_ReadCardSerial()) {
    			return;
    		}
    
    		// Dump debug info about the card; PICC_HaltA() is automatically called
    		//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
    		if (!olduid.size || !sameUid(&(mfrc522.uid), &olduid)) {
    			ShowCardData(&(mfrc522.uid));
    			copyUid(&(mfrc522.uid), &olduid);
    			if (isValidCard(&olduid)) {
    				OpenDoor(programmode);
    			}
    			else {
    
    				if (sameUid(&(mfrc522.uid), &masterkey)) {
    					// Only switch in program mode when mastercard is found AND the program button is pressed
    					if (switchValue) {
    						Serial.println(F("Program mode"));
    						programmode = true;
    						programTimer = 0;
    						lastTime = 0;
    					}
    				}
    				else {
    					if (programmode) {
    						Serial.println(F("new card"));
    						programTimer = 0;
    
    						if (countValidCards < MAX_CARDS)
    						{
    							// Add card to list...
    							copyUid(&(mfrc522.uid), &validCards[countValidCards]);
    							countValidCards++;
    							blinkFast(15);
    						}
    					}
    					else {
    						Serial.println(F("Invalid card"));
    						if (armed) {
    							send(wrongMsg.set(1));
    							delay(2000);
    							send(wrongMsg.set(0));
    						}
    					}
    				}
    			}
    		}
    	}
    }
    
    void ShowCardData(MFRC522::Uid* uid) {
    	Serial.print(F("Card UID:"));
    	for (byte i = 0; i < uid->size; i++) {
    		if (uid->uidByte[i] < 0x10) {
    			Serial.print(F(" 0"));
    		}
    		else {
    			Serial.print(F(" "));
    		}
    		Serial.print(uid->uidByte[i], HEX);
    	}
    	Serial.println();
    }
    
    void copyUid(MFRC522::Uid* src, MFRC522::Uid* dest)
    {
    	dest->size = src->size;
    	dest->sak = src->sak;
    
    	for (byte i = 0; i < src->size; i++) {
    		dest->uidByte[i] = src->uidByte[i];
    	}
    }
    
    bool sameUid(MFRC522::Uid* old, MFRC522::Uid* check)
    {
    	if (old->size != check->size) {
    		return false;
    	}
    	for (byte i = 0; i < old->size; i++) {
    		if (old->uidByte[i] != check->uidByte[i]) {
    			return false;
    		}
    	}
    	return true;
    }
    
    bool isValidCard(MFRC522::Uid* uid)
    {
    	for (byte i = 0; i < countValidCards; i++) {
    		if (validCards[i].size != uid->size) {
    			break;
    		}
    		for (int j = 0; j < uid->size; j++) {
    			if (validCards[i].uidByte[j] != uid->uidByte[j]) {
    				break;
    			}
    			if (j == (uid->size - 1)) {
    				return true;
    			}
    		}
    	}
    	return false;
    }
    
    
    void storeEeprom()
    {
    	byte address = 0;
    	saveState(address++, countValidCards);
    
    	for (byte i = 0; i < countValidCards; i++) {
    		saveState(address++, validCards[i].size);
    		for (byte j = 0; j < 10; j++) {
    			saveState(address++, validCards[i].uidByte[j]);
    		}
    	}
    }
    
    void recallEeprom()
    {
    	byte address = 0;
    
    	countValidCards = loadState(address++);
    	if (countValidCards > MAX_CARDS) {
    		Serial.println(F("Not a valid EEPROM reading set to default"));
    		countValidCards = 0;
    		storeEeprom();
    		return;
    	}
    
    	for (byte i = 0; i < countValidCards; i++) {
    		validCards[i].size = loadState(address++);
    		for (byte j = 0; j < 10; j++) {
    			validCards[i].uidByte[j] = loadState(address++);
    		}
    	}
    
    }
    
    void blinkFast(int times)
    {
    	for (int i = 0; i < times; i++) {
    		ledon = !ledon;
    		digitalWrite(LED_PIN, ledon);
    		delay(100);
    	}
    }
    
    void OpenDoor(bool fakeOpen)
    {
    	Serial.println(F("Open door!"));
    	send(lockMsg.set(false));
    
    	if (!fakeOpen) {
    		digitalWrite(LED_PIN, HIGH);
    		digitalWrite(GARAGEPIN, HIGH);
    	}
    	delay(1000);
    
    	if (!fakeOpen) {
    		digitalWrite(GARAGEPIN, LOW);
    		digitalWrite(LED_PIN, LOW);
    	}
    
    	send(lockMsg.set(true));
    }
    
    void ShowReaderDetails() {
    	// Get the MFRC522 software version
    	byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
    	Serial.print(F("MFRC522 Software Version: 0x"));
    	Serial.print(v, HEX);
    	if (v == 0x91) {
    		Serial.print(F(" = v1.0"));
    	}
    	else if (v == 0x92) {
    		Serial.print(F(" = v2.0"));
    	}
    	else {
    		Serial.print(F(" (unknown)"));
    	}
    	Serial.println("");
    
    	// When 0x00 or 0xFF is returned, communication probably failed
    	if ((v == 0x00) || (v == 0xFF)) {
    		Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
    	}
    }
    
    
    void receive(const MyMessage &message)
    {
    	if (message.type == V_LOCK_STATUS) {
    		// Change relay state
    		if (!message.getBool()) {
    			OpenDoor(false);
    		}
    
    		// Write some debug info
    		Serial.print(F("Lock status: "));
    		Serial.println(message.getBool());
    	}
    	else
    	{
    		if (message.type == V_ARMED) {
    			// Change relay state
    			armed = message.getBool();
    
    			// Write some debug info
    			Serial.print(F("Arm status: "));
    			Serial.println(message.getBool());
    		}
    		else
    		{
    			// Write some debug info
    			Serial.print(F("Incoming msg type: "));
    			Serial.print(message.type);
    			Serial.print(F(" id: "));
    			Serial.print(message.sensor);
    			Serial.print(F(" content: "));
    			Serial.println(message.getInt());
    		}
    	}
    }
    

  • Contest Winner

    @gohan did you try running the MRRC522 demo application only?

    So eliminating all MySensors stuff. To check the wiring.(make sure the pin 7 an 8 definition are correct.)


  • Mod

    If I unplug the nrf24 and use the original wiring with the demo sketch I can read the tags. I checked with multimeter from arduino to the rfid pins and they are OK. But I'll be ordering the newer board that supports nfc



  • Hello all,

    I am very new to arduino and all this stuff. This rfid garage opener ist exactly what i am lookibg for as my first project. But i have problems compiling the code with arduino ide. I get error notifications regarding the .h files. Do I have to include them in my arduino ide folders? Can someone please tell me where to find them? And where i have to save them?

    It would be very nice if someone helps me!

    Thanks


  • Mod

    It would help if you share your error messages.
    In general I would say, read the messages and (try to) interpret them (google?).


  • Mod

    @thomas84 of course you need to install the libraries from library manager for all the Includes


  • Mod

    Welcome to the MySensors community @thomas84 !

    Instructions on how to install MySensors is available at https://www.mysensors.org/about/arduino#installing-the-sensor-libraries



  • Hello all,

    Thanks for your answers! Yesterday I could finish the uploading to the arduino nano. Now I wanted to test the garage opener and did the connections like in the picture at the top of this. But nothing is hapening 😞 Even the red light led ist not on. Do I have to "start" the programm some how?

    Thanks for your help!


  • Mod

    I got issues too when I tryed the MFRC522 and couldn't get it working with the NFR24, you might have better luck using the I2C model



  • Why is the NFR24 needed at all?



  • I was Looking for the best garage Door Openers and some other issues related to their installation and so i found this discussion.I want some suggestions that which will be best and good quality garage door opener? also i saw somewhere that it may start making noises and it may have small range so which will be the quietest and longer range with best in quality.


  • Mod

    Are you looking for an rfid system or just a radio remote control?


Log in to reply
 

Suggested Topics

  • 8
  • 1
  • 90
  • 1
  • 3
  • 44

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts