RFID Garage door opener


  • Plugin Developer

    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 :sunglasses:





  • 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!


  • Plugin Developer

    @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


  • Plugin Developer

    @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


  • Plugin Developer

    @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.


  • Plugin Developer

    @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.

  • Plugin Developer

    @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.


  • Plugin Developer

    @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.


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.