RFID Garage door opener
-
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
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
-
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
-
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!
-
@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 86MFRC522::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 saysCard 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
-
@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
-
@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 };
-
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.
-
@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.
-
@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.
-
@codergirl56 there are a number of examples in the MFRC522 library which might help you.
You can find them here: https://github.com/miguelbalboa/rfidPlease 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.
-
@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()); } } }
-
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
-
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")); ```
-
@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
-
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!
-
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
-
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()); } } }
-
@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)
-
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()); } } }
-
@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.)
-
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
-
It would help if you share your error messages.
In general I would say, read the messages and (try to) interpret them (google?).
-
@thomas84 of course you need to install the libraries from library manager for all the Includes
-
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!
-
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.
-
Are you looking for an rfid system or just a radio remote control?
Suggested Topics
-
Welcome
Announcements • • hek