RFID 2 person readout



  • Hi all,

    IDE1.6.5; nano v3

    I want to make a sketch to check with RFID cards which person is present.

    So far I have it working for one person, but I don't know how to change the code so It will work for two or more persons. Each person (card) needs to (un)lock another lock in Vera.

    Is there somebody who can help me to get started?

    This is my code:

    /*
     * ----------------------------------------------------------------------------
     * This sketch uses the MFRC522 library ; 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.
     * 
     * This sketch show a simple locking mechanism using the RC522 RFID module.
     * ----------------------------------------------------------------------------
     * 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
     *
     * RC522 module shares pins:
     * Pin 11 MOSI
     * Pin12 MISO
     * Pin 13 SCK
     * And extra:
     * pin7 (iso9) for CE
     * pin 8(iso10) for CSN/CS
     * If your SPI module needs an IRQ also use a different pin for pin 2 (IRQ) as well
     */
    #include <MySensor.h>
    #include <SPI.h>
    #include <MFRC522.h>
    
    #define RST_PIN         7           // Configurable, see typical pin layout above
    #define SS_PIN          8          // Configurable, see typical pin layout above
    
    #define CHILD_ID_RFID1 0
    #define CHILD_ID_RFID2 1
    
    bool lockStatus;
    MySensor gw;
    MyMessage msgP1(CHILD_ID_RFID1, V_LOCK_STATUS);
    MyMessage msgP2(CHILD_ID_RFID2, V_LOCK_STATUS);
    
    MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
    
    String read_rfid;
    String ok_rfid_1="abcdefg";
    String ok_rfid_2="hijklmn"; //add as many as you need.
    
    //Use the lines below if you plan on using a servo as a locking mechanism.
    #include <Servo.h> 
    Servo myservo;  // create servo object to control a servo 
    int posClosed = 0;    // variable to store the servo position for locked
    int posOpen = 270;    //same for open...
    
    /*
     * Initialize.
     */
    void setup() {
        Serial.begin(11500);         // Initialize serial communications with the PC
        while (!Serial);            // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
    // First make sure mfrc is releasing the SPI bus 
        pinMode(RST_PIN, OUTPUT);     
        digitalWrite(RST_PIN, LOW);
        pinMode(SS_PIN, OUTPUT);     
        digitalWrite(SS_PIN, LOW);
    
        // Init mysensors library
        gw.begin(incomingMessage);
    
         // Init MFRC RFID sensor
        SPI.begin();            // Init SPI bus
        mfrc522.PCD_Init();     // Init MFRC522
    
        //Choose which lock below:
        //pinMode(lock, OUTPUT);
        myservo.attach(2);  // attaches the servo on pin 2 to the servo object 
    
          // Send the Sketch Version Information to the Gateway
      gw.sendSketchInfo("RFID", "0.0.5");
    
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID_RFID1, S_LOCK);
      gw.present(CHILD_ID_RFID2, S_LOCK);
    
      lockStatus = gw.loadState(0);    // Read last lock status from eeprom
      setLockState(lockStatus, true); // Now set the last known state and send it to controller 
    }
    
    /*
     * Helper routine to dump a byte array as hex values to Serial.
     */
    void dump_byte_array(byte *buffer, byte bufferSize) {
        read_rfid="";
        for (byte i = 0; i < bufferSize; i++) {
            read_rfid=read_rfid + String(buffer[i], HEX);
        }
    }
    
    void open_lock() {
      //Use this routine when working with Relays and Solenoids etc.
      //digitalWrite(lock, HIGH);
      //delay(2000);
      //digitalWrite(lock,LOW);
      
      //Use this routine when working with Servos.
      myservo.write(posOpen); 
      delay(2000);
      myservo.write(posClosed);
    
    }
    
    void loop() {
        gw.process(); // Process incomming messages
    
    //  boolean success;  //niet nodig met onderstaande if functie
        // Look for new cards
        if ( ! mfrc522.PICC_IsNewCardPresent())
            return;
    
        // Select one of the cards
        if ( ! mfrc522.PICC_ReadCardSerial())
            return;
    
        dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
        //Serial.println(read_rfid);
        if (read_rfid==ok_rfid_1) {
          //ok, open the door.
          setLockState(!lockStatus, true);
          Serial.println("Hi person1");
          open_lock();     
        }
        if (read_rfid==ok_rfid_2) {
          //ok, open the door.
          //setLockState(!lockStatus, true);
          Serial.println("Hi person2");
          open_lock();
        }
        //Add below as many "keys" as you want
        //if (read_rfid==ok_rfid_2) {
          //also ok, open the door
        //  open_lock();
        //}
        // else not needed. Anything else is not ok, and will not open the door..
    }
    
    // open door and set state.
    void setLockState(bool state, bool send){
      if (state) 
         Serial.println("open lock");
      else
         Serial.println("close lock");
      if (send)
         gw.send(msgP1.set(state));
    //  digitalWrite(lockPin, state);
       gw.saveState(0,state);
       lockStatus = state;
     }
    
    void incomingMessage(const MyMessage &message) {
       // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_LOCK_STATUS) {
         // Change relay state
          setLockState(message.getBool(), false);
        }  
         // Write some debug info
         Serial.print("Incoming lock status:");
         Serial.println(message.getBool());
    } 
    

  • Contest Winner

    @DannyM

    I also made a scketch with the mifare RFID tag reader.
    Checking for multiple cards i did use this code (note not all code is listed only the relevant parts, let met know if you need more, than i need to strip down my sketch because it does more):

    MFRC522::Uid validCards[MAX_CARDS];
    MFRC522::Uid masterkey = { 8, {0xHEX, 0xHEX,  0xHEX, 0xHEX, 0xHEX, 0xHEX, 0xHEX, 0xHEX },  0 };
    
    
    // ... other code 
    
    void loop () {
    
              timer++;
             // 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 (!olduid.size || !sameUid(&(mfrc522.uid), &olduid))  {
                    copyUid(&(mfrc522.uid), &olduid);
                    if ( isValidCard(&olduid) )   {
                         open_lock();
                    } else  {
                       if (sameUid(&(mfrc522.uid), &masterkey)) {
                           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 {
                             gw.send(wrongMsg.set(1));
                             Serial.println(F("Invalid card"));
                             delay(2000);
                             gw.send(wrongMsg.set(0));
                           }
                       }
                    }
    
    
        // ... other code 
      }
    
    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);
        }
    }
    
    


  • @BartE

    I think I have enough code for what I want, it is in the

    void storeEprom() 
    void recallEeprom()
    

    functions. So I am gonna try to implement this into my code.

    Thanks so far..


Log in to reply
 

Suggested Topics

6
Online

11.4k
Users

11.1k
Topics

112.7k
Posts