|
| 1 | +/* |
| 2 | + RFID Lock sensor/actuator |
| 3 | + |
| 4 | + |
| 5 | +
|
| 6 | + Use RFID tag to lock/unlock a door or trigger a scene on your controller. |
| 7 | + This example sketch allows you to add an optional relay or solenoid |
| 8 | + which can be activated/opened by RFID or controller. |
| 9 | +
|
| 10 | + Use the I2C wiring option for your RFID module and connect to the following Arduino pins. |
| 11 | + |
| 12 | + RFID Arduino |
| 13 | + ----- ------- |
| 14 | + GND -> GND |
| 15 | + VCC -> +5V |
| 16 | + SCL -> A5 |
| 17 | + SDA -> A4 |
| 18 | + |
| 19 | + Use normal wiring for NRF24L01 radio |
| 20 | + |
| 21 | + Attach a optional relay or solonoid lock to pin 4 |
| 22 | + |
| 23 | +*/ |
| 24 | + |
| 25 | +#include <MySensor.h> |
| 26 | +#include <SPI.h> |
| 27 | +#include <Wire.h> |
| 28 | +#include <PN532_I2C.h> |
| 29 | +#include <PN532.h> |
| 30 | + |
| 31 | + |
| 32 | +// Add your valid rfid keys here. To find you your key just run sketch; hold your new RFID tag in fron ot the reader; |
| 33 | +// and copy the key from serial output of this sketch. |
| 34 | +const uint8_t maxKeyLength = 7; |
| 35 | +uint8_t validKeys[][maxKeyLength] = { |
| 36 | + { 0xB3, 0xC6, 0xD9, 0x80, 0x00, 0x00, 0x00 }, |
| 37 | + { 0, 0, 0, 0, 0, 0, 0 }, |
| 38 | + { 0, 0, 0, 0, 0, 0, 0 }, |
| 39 | + { 0, 0, 0, 0, 0, 0, 0 }, |
| 40 | + { 0, 0, 0, 0, 0, 0, 0 }}; |
| 41 | +int keyCount = sizeof validKeys / maxKeyLength; |
| 42 | + |
| 43 | + |
| 44 | +#define CHILD_ID 99 // Id of the sensor child |
| 45 | + |
| 46 | +/*Pin definitions*/ |
| 47 | +const int lockPin = 4; // (Digital 4) The pin that activates the relay/solenoid lock. |
| 48 | + |
| 49 | +bool lockStatus; |
| 50 | +MySensor gw; |
| 51 | +MyMessage lockMsg(CHILD_ID, V_LOCK_STATUS); |
| 52 | +PN532_I2C pn532i2c(Wire); |
| 53 | +PN532 nfc(pn532i2c); |
| 54 | + |
| 55 | +void setup() { |
| 56 | + |
| 57 | + pinMode(lockPin, OUTPUT); |
| 58 | + |
| 59 | + nfc.begin(); |
| 60 | + uint32_t versiondata = nfc.getFirmwareVersion(); |
| 61 | + if (! versiondata) { |
| 62 | + Serial.print("Couldn't find PN53x board"); |
| 63 | + while (1); // halt |
| 64 | + } |
| 65 | + Serial.print("Found NFC chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); |
| 66 | + Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); |
| 67 | + Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC); |
| 68 | + // Set the max number of retry attempts to read from a card |
| 69 | + // This prevents us from waiting forever for a card, which is |
| 70 | + // the default behaviour of the PN532. |
| 71 | + nfc.setPassiveActivationRetries(0x3); |
| 72 | + |
| 73 | + // configure board to read RFID tags |
| 74 | + nfc.SAMConfig(); |
| 75 | + |
| 76 | + // Init mysensors library |
| 77 | + gw.begin(incomingMessage); |
| 78 | + |
| 79 | + gw.sendSketchInfo("RFID Lock", "1.0"); |
| 80 | + gw.present(CHILD_ID, S_LOCK); |
| 81 | + |
| 82 | + lockStatus = gw.loadState(0); // Read last lock status from eeprom |
| 83 | + setLockState(lockStatus, true); // Now set the last known state and send it to controller |
| 84 | +} |
| 85 | + |
| 86 | +void loop() { |
| 87 | + boolean success; |
| 88 | + uint8_t key[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID |
| 89 | + uint8_t currentKeyLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) |
| 90 | + |
| 91 | + gw.process(); // Process incomming messages |
| 92 | + |
| 93 | + // Wait for an ISO14443A type cards (Mifare, etc.). When one is found |
| 94 | + // 'uid' will be populated with the UID, and uidLength will indicate |
| 95 | + // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) |
| 96 | + success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &key[0], ¤tKeyLength); |
| 97 | + |
| 98 | + if (success) { |
| 99 | + Serial.print("Found tag id: "); |
| 100 | + for (uint8_t i=0; i < currentKeyLength; i++) |
| 101 | + { |
| 102 | + if (i>0) Serial.print(","); |
| 103 | + Serial.print("0x");Serial.print(key[i], HEX); |
| 104 | + } |
| 105 | + for (uint8_t i=currentKeyLength; i < maxKeyLength; i++) |
| 106 | + { |
| 107 | + Serial.print(",0x00"); |
| 108 | + } |
| 109 | + |
| 110 | + |
| 111 | + Serial.println(""); |
| 112 | + |
| 113 | + boolean valid = false; |
| 114 | + // Compare this key to the valid once registered here in sketch |
| 115 | + for (int i=0;i<keyCount && !valid;i++) { |
| 116 | + for (int j=0;i<currentKeyLength && !valid;j++) { |
| 117 | + if (key[j] != validKeys[i][j]) { |
| 118 | + break; |
| 119 | + } |
| 120 | + if (j==currentKeyLength-1) { |
| 121 | + valid = true; |
| 122 | + } |
| 123 | + } |
| 124 | + } |
| 125 | + if (valid) { |
| 126 | + // Switch lock status |
| 127 | + setLockState(!lockStatus, true); |
| 128 | + } |
| 129 | + |
| 130 | + // Wait for card/tag to leave reader |
| 131 | + while(nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &key[0], ¤tKeyLength)); |
| 132 | + } |
| 133 | +} |
| 134 | + |
| 135 | + |
| 136 | + |
| 137 | +// Unlocks the door. |
| 138 | +void setLockState(bool state, bool send){ |
| 139 | + if (state) |
| 140 | + Serial.println("open lock"); |
| 141 | + else |
| 142 | + Serial.println("close lock"); |
| 143 | + if (send) |
| 144 | + gw.send(lockMsg.set(state)); |
| 145 | + digitalWrite(lockPin, state); |
| 146 | + gw.saveState(0,state); |
| 147 | + lockStatus = state; |
| 148 | +} |
| 149 | + |
| 150 | +void incomingMessage(const MyMessage &message) { |
| 151 | + // We only expect one type of message from controller. But we better check anyway. |
| 152 | + if (message.type==V_LOCK_STATUS) { |
| 153 | + // Change relay state |
| 154 | + setLockState(message.getBool(), false); |
| 155 | + |
| 156 | + // Write some debug info |
| 157 | + Serial.print("Incoming lock status:"); |
| 158 | + Serial.println(message.getBool()); |
| 159 | + } |
| 160 | +} |
| 161 | + |
0 commit comments