My Cart

How to Identify People Using Smart Cards Kit (NFC/RFID 13.56MHz)

Difficulty Level: Expert -

1. Introduction

This tutorial allows the user to indentify different cards associated to several people. If they are close to an antenna, RFID card will save how many times that person has been there.

Ingredients:

    - 1 x Smart Cards Kit (NFC/RFID 13.56MHz):
    • 1x Platform
    • 1x NFC/RFID 13.56MHz
    • 1x RGB LED
    • 3x 220Ω resistors
    • 1x LCD
    • 1x Potentiometer
    • 1x Buzzer
    • 1x Breadboard
    • 1x External power supply
    • 1x Programming cable
    • Jumper Wires

Preparation Time: 30 minutes

Buy now
NOTE: Depending on the platform chosen to develop the project, the ingredients and the schematics shown in this tutorial can vary.

This project can be developed with Arduino or Intel Galileo. It is also compatible with Raspberry Pi using the Raspberry Pi to Arduino shields connection bridge.

For further information about the RFID 13.56MHz Shield, consult the main tutorial.

Step 1: Connection

Connect the RFID module with its antenna to the Xbee Shield and then, connect the shield to the Arduino. Connect the RGB LED with the resistors, the buzzer, the potentiometer and the LCD in the breadboard as you can see in the next diagram.

Connect two wires, red and black, to the two long rows on the side of the breadboard to provide access to the 5 volt supply and ground. A potentiometer will adjust LCD contrast. Connect left terminal of the potentiometer to 5 volt and the right terminal to GND. Connect the central leg of the potentiometer to the third pin of the LCD display. Follow the wire color diagram to connect all LCD pins. Connect pin 6,10 and 11 to the RGB LED with a resistor in each pin and power it with 5 volt in the longest leg of the RGB LED. Finally, connect positive terminal of the buzzer, marked with a "+", to a resistor and then to pin 9 and the remaining terminal of the buzzer to GND.

Step 2: The Code

Arduino:

Code:
/*  
 *  RFID 13.56 MHz / NFC Module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.0
 *  Design:            David GascĂłn 
 *  Implementation:    Luis Miguel MartĂ­
 */
 			
// include the library code:
#include <LiquidCrystal.h>


//define constants
#define RED 6
#define GREEN 10
#define BLUE 11
#define BUZZ 9

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 8, 5, 4, 3, 2);

struct worker {

  char name[16];
  uint8_t acces_level;
  uint8_t visits;
  uint8_t UID[4];

};

struct RGB{

  uint8_t r;
  uint8_t g;
  uint8_t b;

};

//create and initilize users
worker user[3];

//colours

RGB orange = {
  0,225,255};
RGB lime = {
  64, 0, 255};
RGB cyan = {
  255, 79, 9};
RGB off = {
  255,255,255};
RGB red = {
  0,255,255};
RGB white = {
  0,0,0};
RGB purple = {
  100,255,100};


//RFID needed

uint8_t dataRX[35];//Receive buffer.
uint8_t dataTX[35];//Transmit buffer.
uint8_t _UID[4]; // stores the UID (unique identifier) of a card.
uint8_t blockData[] =	{
  0x10, 0x11,  0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};//Data to write (16 bytes).
uint8_t keyAccess[] = {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };// stores the key or password.
uint8_t address = 0x04;//Address to read.
uint8_t visits_address = 0x05;//Address to read.
uint8_t ATQ[2];//Answer to request
uint8_t state1;//state of the process
uint8_t state2;
uint8_t aux[16];//Auxiliar buffer. 
uint8_t aux1[] = {
  0x64,0x9E,0xCD,0xEA};
uint8_t aux2[] = {
  0xA4,0x03,0xCE,0xEA};
uint8_t aux3[] = {
  0x34,0x2C,0xCB,0xEA};

void setup() {

  pinMode(RED,OUTPUT);
  pinMode(GREEN,OUTPUT);
  pinMode(BLUE,OUTPUT);
  analogWrite(BUZZ,128);
  delay(100);
  analogWrite(BUZZ,0);
  lcd.begin(16, 2);
  lcd.print("SecureSys");
  lcd.setCursor(0,2);
  lcd.print("Keeps safe all");
  delay(3000);
  Serial.begin(115200);
  //initiate users
  strcpy(user[0].name, "Lewis Marvin    ");
  user[0].UID[0] = 0x64;
  user[0].UID[1] = 0x9E;
  user[0].UID[2] = 0xCD;
  user[0].UID[3] = 0xEA;
  print(user[0].UID,4);
  user[0].acces_level = 3;
  user[0].visits = 0;
  strcpy(user[1].name, "Mark Bean       ");
  user[1].UID[0] = 0xA4;
  user[1].UID[1] = 0x03;
  user[1].UID[2] = 0xCE;
  user[1].UID[3] = 0xEA;
  print(user[1].UID,4);
  user[1].acces_level = 1;
  user[1].visits = 0;
  strcpy(user[2].name, "George Slaughter");
  user[2].UID[0] = 0x34;
  user[2].UID[1] = 0x2C;
  user[2].UID[2] = 0xCB;
  user[2].UID[3] = 0xEA;
  print(user[2].UID,4);
  user[2].acces_level = 2;
  user[2].visits = 0;
  getFirmware();
  configureSAM();

}

void loop() {

  lcd.clear();
  lcd.print("Scanning...");
  setColour(lime.r,lime.g,lime.b);
  //bucle lectura tarjeta

  init(_UID, ATQ);

  Serial.print( "The Card UID : ");
  print(_UID , 4);
  //search user
  boolean found = false;
  byte user_found;
  for(byte i = 0; i<3; i++){

    if (!equalUIDs(user[i].UID,_UID)){
      print(user[i].UID,4);
      print(_UID , 4);
      lcd.clear();
      lcd.print("User:");
      lcd.setCursor(0,2);
      lcd.print(user[i].name);
      found = true;
      user_found = i;
      state1 = authenticate(_UID, address, keyAccess);
      state2 = readData(address, aux);
      for (byte j=0; j<5; j++){

        setColour(off.r,off.g,off.b);
        delay(200);
        setColour(white.r,white.g,white.b);
        delay(200);
      }
    }
    setColour(lime.r,lime.g,lime.b);
  }
  if (found){
    /////////////////////////////////////////////////////////////
    //Auntenticate a block with his keyAccess


    if ( state1 == 0) {

      lcd.clear();
      lcd.print("Correct card...");
      delay(1000);

    } 
    else {



    }
    /////////////////////////////////////////////////////////////
    //Read from address after authentication

    Serial.print("\n");

    if (state2 == 0) {

      user[user_found].visits++;
      lcd.clear();
      lcd.print("You've been here");
      lcd.setCursor(0,2);
      lcd.print(user[user_found].visits);
      lcd.setCursor(4,2);
      lcd.print("times today");
      delay(3000);
      lcd.clear();
      lcd.print("Acces level:");
      lcd.setCursor(0,2);
      lcd.print(user[user_found].acces_level);
      delay(3000);
      switch(user[user_found].acces_level){

      case 1:
        lcd.clear();
        lcd.print("Acces denied!");
        setColour(red.r,red.g,red.b);
        delay(1000);
        analogWrite(BUZZ,78);
        delay(1000);
        analogWrite(BUZZ,0);
        break;

      case 2:

        lcd.clear();
        lcd.print("Acces granted!");
        lcd.setCursor(0,2);
        lcd.print("Go ahead!");
        setColour(cyan.r, cyan.g, cyan.b);
        delay(2000);
        analogWrite(BUZZ,128);
        delay(100);
        analogWrite(BUZZ,0);
        delay(100);
        analogWrite(BUZZ,128);
        delay(100);
        analogWrite(BUZZ,0);
        break;

      case 3:

        lcd.clear();
        lcd.print("Total acces!");
        lcd.setCursor(0,2);
        lcd.print("Go ahead!");
        setColour(purple.r, purple.g, purple.b);
        delay(2000);
        analogWrite(BUZZ,128);
        delay(100);
        analogWrite(BUZZ,0);
        delay(100);
        analogWrite(BUZZ,128);
        delay(100);
        analogWrite(BUZZ,0);
        break;
      }

    } 
    else {

      lcd.clear();
      lcd.print("Couldn't read");
      lcd.setCursor(0,2);
      lcd.print("Wave card again");
      setColour(orange.r, orange.g, orange.b);
      delay(3000);

    }

  } 
  else {

    lcd.clear();
    lcd.print("UID not found");
    lcd.setCursor(0,2);
    lcd.print("Please leave");
    setColour(red.r, red.g, red.b);
    delay(3000);

  }


}


//**********************************************************************
//!The goal of this command is to detect as many targets (maximum MaxTg)
// as possible in passive mode.
uint8_t init(uint8_t *UID , uint8_t *ATQ)   //! Request InListPassive
{
  Serial.flush();

  dataTX[0] = 0x04; // Length
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4;
  dataTX[3] = 0x4A; // Code
  dataTX[4] = 0x01; //MaxTarget
  dataTX[5] = 0x00; //BaudRate = 106Kbps
  dataTX[6] = 0x00; // Clear checkSum position
  checkSum(dataTX); 

  sendTX(dataTX , 7 ,23);

  for (int i = 17; i < (21) ; i++){
    _UID[i-17] = dataRX[i];
    UID[i-17] = _UID[i-17];
  }

  ATQ[0] = dataRX[13];
  ATQ[1] = dataRX[14];

  if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x4B) & (dataRX[11] == 0x01)) {
    return 0;
  } 
  else {
    return 1;
  }
}
//**********************************************************************
//!A block must be authenticated before read and write operations
uint8_t authenticate(uint8_t *UID, uint8_t blockAddress, uint8_t *keyAccess)
{
  dataTX[0] = 0x0F;
  lengthCheckSum(dataTX);
  dataTX[2] = 0xD4;
  dataTX[3] = 0x40; // inDataEchange
  dataTX[4] = 0x01; //Number of targets
  dataTX[5] = 0x60; // Authentication code
  dataTX[6] = blockAddress;

  for (int i = 0; i < 6 ; i++) {
    dataTX[i + 7] = keyAccess[i];
  }

  dataTX[13] = UID[0];  
  dataTX[14] = UID[1];
  dataTX[15] = UID[2];  
  dataTX[16] = UID[3];
  dataTX[17] = 0x00;
  checkSum(dataTX);
  sendTX(dataTX , 18 ,14);

  if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x41) & (dataRX[11] == 0x00)) {
    return 0;
  } 
  else {
    return 1;
  }
}
//**********************************************************************
//!Write 16 bytes in address .
uint8_t writeData(uint8_t address, uint8_t *blockData)  //!Writing
{
  Serial.print("                ");
  dataTX[0] = 0x15;
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4;
  dataTX[3] = 0x40;  //inDataEchange CODE
  dataTX[4] = 0x01;  //Number of targets
  dataTX[5] = 0xA0; //Write Command
  dataTX[6] = address; //Address		

    for (int i = 0; i < 16; i++) {
    dataTX[i+7] = blockData[i];
  }

  dataTX[23] = 0x00;
  checkSum(dataTX);
  sendTX(dataTX , 24 ,14);  		

  if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x41) & (dataRX[11] == 0x00)) {
    return 0;
  } 
  else {
    return 1;
  }
}
//**********************************************************************
//!Read 16 bytes from  address .
uint8_t readData(uint8_t address, uint8_t *readData) //!Reading
{
  Serial.print("                ");		

  dataTX[0] = 0x05;
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4; // Code
  dataTX[3] = 0x40; // Code
  dataTX[4] = 0x01; // Number of targets
  dataTX[5] = 0x30; //ReadCode
  dataTX[6] = address;  //Read address
  dataTX[7] = 0x00;
  checkSum(dataTX);
  sendTX(dataTX , 8, 30);
  memset(readData, 0x00, 16);  

  if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x41) & (dataRX[11] == 0x00)) {
    for (int i = 12; i < 28; i++) {
      readData[i-12] = dataRX[i];
    }
    return 0;
  } 
  else {
    return 1;
  }
}
//**********************************************************************
//!The PN532 sends back the version of the embedded firmware.
bool getFirmware(void)  //! It is needed to launch a simple command to sycnchronize
{
  Serial.print("                ");

  memset(dataTX, 0x00, 35);
  dataTX[0] = 0x02; // Length
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4; // CODE
  dataTX[3] = 0x02; //TFI
  checkSum(dataTX); //0x2A; //Checksum   

  sendTX(dataTX , 5 , 17);
  Serial.print("\n");
  Serial.print("Your Firmware version is : ");

  for (int i = 11; i < (15) ; i++){
    Serial.print(dataRX[i], HEX);
    Serial.print(" ");
  }
  Serial.print("\n");
}

//**********************************************************************
//!Print data stored in vectors .
void print(uint8_t * _data, uint8_t length)
{
  for (int i = 0; i < length ; i++){
    Serial.print(_data[i], HEX);
    Serial.print(" ");
  }
  Serial.print("\n");
}
//**********************************************************************
//!This command is used to set internal parameters of the PN532,
bool configureSAM(void)//! Configure the SAM
{
  Serial.print("               ");

  dataTX[0] = 0x05; //Length
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4;
  dataTX[3] = 0x14;
  dataTX[4] = 0x01; //Normal mode
  dataTX[5] = 0x14; // TimeOUT
  dataTX[6] = 0x00; // IRQ
  dataTX[7] = 0x00; // Clean checkSum position
  checkSum(dataTX);

  sendTX(dataTX , 8, 13);
}
//**********************************************************************
//!Send data stored in dataTX
void sendTX(uint8_t *dataTX, uint8_t length, uint8_t outLength)
{
  Serial.print(char(0x00));
  Serial.print(char(0x00));
  Serial.print(char(0xFF)); 

  for (int i = 0; i < length; i++) {
    Serial.print(char(dataTX[i]));
  }

  Serial.print(char(0x00));
  getACK();
  waitResponse();    // 1C - receive response
  getData(outLength);
}
//**********************************************************************
//!Wait for ACK response and stores it in the dataRX buffer
void getACK(void)
{
  delay(5);
  waitResponse();
  for (int i = 0; i < 5 ; i++) {
    dataRX[i] = Serial.read();
  }
}
//**********************************************************************
//!Wait the response of the module
void waitResponse(void)
{
  int val = 0xFF;
  int cont = 0x00;
  while(val != 0x00) {
    val = Serial.read();
    delay(5);
    cont ++;
  }
}
//**********************************************************************
//!Get data from the module
void getData(uint8_t outLength)
{
  for (int i=5; i < outLength; i++) {
    dataRX[i] = Serial.read(); // read data from the module.
  }
}
//**********************************************************************
//!Calculates the checksum and stores it in dataTX buffer
void checkSum(uint8_t *dataTX)
{
  for (int i = 0; i < dataTX[0] ; i++) {
    dataTX[dataTX[0] + 2] += dataTX[i + 2];
  }
  byte(dataTX[dataTX[0] + 2]= - dataTX[dataTX[0] + 2]);
}
//**********************************************************************
//!Calculates the length checksum and sotres it in the buffer.
uint8_t lengthCheckSum(uint8_t *dataTX)
{
  dataTX[1] = byte(0x100 - dataTX[0]);
}
//**********************************************************************
//compare 2 arrays
uint8_t equalUIDs(uint8_t *UID1 , uint8_t *UID2)

{

  if (memcmp(UID1, UID2, 4) == 0) return 0; 
  else return 1;

}
//**********************************************************************
//set RGB LED colour
void setColour(uint8_t r, uint8_t g, uint8_t b){

  analogWrite(RED,r);
  analogWrite(GREEN,g);
  analogWrite(BLUE,b);

}

        

Raspberry Pi:

Code:
			
/*  
 *  RFID 13.56 MHz / NFC Module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.0
 *  Design:            David GascĂłn 
 *  Implementation:    Victor Boria
 */
 
#include "arduPi.h"


//define constants
#define RED 6
#define GREEN 10
#define BLUE 11
#define BUZZ 9


struct worker {
	
  char name[17];
  uint8_t acces_level;
  uint8_t visits;
  uint8_t UID[4];
};

//create and initilize users
worker user[3];

//RFID needed
uint8_t dataRX[35];//Receive buffer.
uint8_t dataTX[35];//Transmit buffer.
uint8_t _UID[4]; // stores the UID (unique identifier) of a card.
uint8_t blockData[] =	{
  0x10, 0x11,  0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};//Data to write (16 bytes).
uint8_t keyAccess[] = {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };// stores the key or password.
uint8_t address = 0x04;//Address to read.
uint8_t visits_address = 0x05;//Address to read.
uint8_t ATQ[2];//Answer to request
uint8_t state1;//state of the process
uint8_t state2;
uint8_t aux[17];//Auxiliar buffer. 
uint8_t aux1[] = {0x64,0x9E,0xCD,0xEA};
uint8_t aux2[] = {0xA4,0x03,0xCE,0xEA};
uint8_t aux3[] = {0x34,0x2C,0xCB,0xEA};

uint8_t init(uint8_t *UID , uint8_t *ATQ);
uint8_t authenticate(uint8_t *UID, uint8_t blockAddress, uint8_t *keyAccess);
uint8_t writeData(uint8_t address, uint8_t *blockData);
uint8_t readData(uint8_t address, uint8_t *readData);
bool getFirmware(void);
void print(uint8_t * _data, uint8_t length);
bool configureSAM(void);
void sendTX(uint8_t *dataTX, uint8_t length, uint8_t outLength);
void getACK(void);
void waitResponse(void);
void getData(uint8_t outLength);
void checkSum(uint8_t *dataTX);
uint8_t lengthCheckSum(uint8_t *dataTX);
uint8_t equalUIDs(uint8_t *UID1 , uint8_t *UID2);
void setColour(bool r, bool g, bool b);

void setup() {

  pinMode(RED,OUTPUT);
  pinMode(GREEN,OUTPUT);
  pinMode(BLUE,OUTPUT);
  digitalWrite(BUZZ,HIGH);
  
  digitalWrite(RED, HIGH);
  digitalWrite(GREEN, HIGH);
  digitalWrite(BLUE, HIGH);
  
  digitalWrite(BUZZ, HIGH);
  delay(100);
  digitalWrite(BUZZ, 0);
  delay(100);
  digitalWrite(BUZZ, HIGH);
  delay(100);
  digitalWrite(BUZZ, 0);
  printf("SecureSys Keeps safe all\n");
  delay(2000);
  Serial.begin(115200);
  //initiate users
  strcpy(user[0].name, "Lewis Marvin");
  user[0].UID[0] = 0x64;
  user[0].UID[1] = 0x9E;
  user[0].UID[2] = 0xCD;
  user[0].UID[3] = 0xEA;
  print(user[0].UID,4);
  user[0].acces_level = 3;
  user[0].visits = 0;
  strcpy(user[1].name, "Mark Bean");
  user[1].UID[0] = 0xA4;
  user[1].UID[1] = 0x03;
  user[1].UID[2] = 0xCE;
  user[1].UID[3] = 0xEA;
  print(user[1].UID,4);
  user[1].acces_level = 1;
  user[1].visits = 0;
  strcpy(user[2].name, "George Slaughter");
  user[2].UID[0] = 0x34;
  user[2].UID[1] = 0x2C;
  user[2].UID[2] = 0xCB;
  user[2].UID[3] = 0xEA;
  print(user[2].UID,4);
  user[2].acces_level = 2;
  user[2].visits = 0;
  getFirmware();
  configureSAM();

}

void loop() {


  printf("Scanning...\n");
  //Blue LED
  digitalWrite(RED, 1);
  digitalWrite(GREEN, 1);
  digitalWrite(BLUE, 0);
  
  //bucle lectura tarjeta
  init(_UID, ATQ);

  printf("The Card UID : %d\n", _UID);
  
  
  //search user
  boolean found = false;
  byte user_found;
  for(byte i = 0; i<3; i++){

    if (!equalUIDs(user[i].UID,_UID)){
      print(user[i].UID,4);
      print(_UID , 4);
      
      printf("User: %s\n", user[i].name);
      found = true;
      user_found = i;
      state1 = authenticate(_UID, address, keyAccess);
      state2 = readData(address, aux);
      for (byte j=0; j<5; j++){
		//Turn off LED
        digitalWrite(RED, HIGH);
        digitalWrite(GREEN, HIGH);
        digitalWrite(BLUE, HIGH);
        delay(200);
        
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, LOW);
        digitalWrite(BLUE, LOW);
        delay(200);
      }
    }
    //Green LED
    digitalWrite(RED, HIGH);
    digitalWrite(GREEN, LOW);
    digitalWrite(BLUE, HIGH);
  }
  if (found){
    /////////////////////////////////////////////////////////////
    //Auntenticate a block with his keyAccess


    if ( state1 == 0) {

      printf("Correct card...\n");
      delay(1000);

    } 

    /////////////////////////////////////////////////////////////
    //Read from address after authentication


    if (state2 == 0) {

      user[user_found].visits++;
      
      printf("You've been here %d times today\n", user[user_found].visits);

      
      printf("Access level: %d\n", user[user_found].acces_level);

      switch(user[user_found].acces_level){

      case 1:
        
        printf("Access denied!\n");
        //Red LED
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, HIGH);
        digitalWrite(BLUE, HIGH);
        digitalWrite(BUZZ, HIGH);
        delay(1000);
        digitalWrite(BUZZ, LOW);
        break;

      case 2:

        
        printf("Access granted! Go ahead!\n");
        //Blue LED
        digitalWrite(RED, 1);
        digitalWrite(GREEN, 1);
        digitalWrite(BLUE, 0);
        
        digitalWrite(BUZZ, HIGH);
        delay(100);
        digitalWrite(BUZZ, LOW);
        delay(100);
        digitalWrite(BUZZ, HIGH);
        delay(100);
        digitalWrite(BUZZ, LOW);
        break;

      case 3:
        
        printf("Total access! Go ahead!\n");
        //Green LED
        digitalWrite(RED, HIGH);
        digitalWrite(GREEN, LOW);
        digitalWrite(BLUE, HIGH);
        
        digitalWrite(BUZZ, HIGH);
        delay(100);
        digitalWrite(BUZZ, LOW);
        delay(100);
        digitalWrite(BUZZ, HIGH);
        delay(100);
        digitalWrite(BUZZ, LOW);
        break;
      }

    } 
    else {

      printf("Couldn't read. Wave card again\n");
      //Red LED
      digitalWrite(RED, 0);
      digitalWrite(GREEN, HIGH);
      digitalWrite(BLUE, HIGH);

    }

  } 
  else {

    
    printf("UID not found. Please leave\n");
    //Red LED
    digitalWrite(RED, 0);
    digitalWrite(GREEN, HIGH);
    digitalWrite(BLUE, HIGH);

  }


}


//**********************************************************************
//!The goal of this command is to detect as many targets (maximum MaxTg)
// as possible in passive mode.
uint8_t init(uint8_t *UID , uint8_t *ATQ)   //! Request InListPassive
{
  Serial.flush();

  dataTX[0] = 0x04; // Length
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4;
  dataTX[3] = 0x4A; // Code
  dataTX[4] = 0x01; //MaxTarget
  dataTX[5] = 0x00; //BaudRate = 106Kbps
  dataTX[6] = 0x00; // Clear checkSum position
  checkSum(dataTX); 

  sendTX(dataTX , 7 ,23);

  for (int i = 17; i < (21) ; i++){
    _UID[i-17] = dataRX[i];
    UID[i-17] = _UID[i-17];
  }

  ATQ[0] = dataRX[13];
  ATQ[1] = dataRX[14];

  if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x4B) & (dataRX[11] == 0x01)) {
    return 0;
  } 
  else {
    return 1;
  }
}
//**********************************************************************
//!A block must be authenticated before read and write operations
uint8_t authenticate(uint8_t *UID, uint8_t blockAddress, uint8_t *keyAccess)
{
  dataTX[0] = 0x0F;
  lengthCheckSum(dataTX);
  dataTX[2] = 0xD4;
  dataTX[3] = 0x40; // inDataEchange
  dataTX[4] = 0x01; //Number of targets
  dataTX[5] = 0x60; // Authentication code
  dataTX[6] = blockAddress;

  for (int i = 0; i < 6 ; i++) {
    dataTX[i + 7] = keyAccess[i];
  }

  dataTX[13] = UID[0];  
  dataTX[14] = UID[1];
  dataTX[15] = UID[2];  
  dataTX[16] = UID[3];
  dataTX[17] = 0x00;
  checkSum(dataTX);
  sendTX(dataTX , 18 ,14);

  if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x41) & (dataRX[11] == 0x00)) {
    return 0;
  } 
  else {
    return 1;
  }
}
//**********************************************************************
//!Write 16 bytes in address .
uint8_t writeData(uint8_t address, uint8_t *blockData)  //!Writing
{
  //Serial.print("                ");
  dataTX[0] = 0x15;
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4;
  dataTX[3] = 0x40;  //inDataEchange CODE
  dataTX[4] = 0x01;  //Number of targets
  dataTX[5] = 0xA0; //Write Command
  dataTX[6] = address; //Address		

    for (int i = 0; i < 16; i++) {
    dataTX[i+7] = blockData[i];
  }

  dataTX[23] = 0x00;
  checkSum(dataTX);
  sendTX(dataTX , 24 ,14);  		

  if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x41) & (dataRX[11] == 0x00)) {
    return 0;
  } 
  else {
    return 1;
  }
}
//**********************************************************************
//!Read 16 bytes from  address .
uint8_t readData(uint8_t address, uint8_t *readData) //!Reading
{
  //Serial.print("                ");		

  dataTX[0] = 0x05;
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4; // Code
  dataTX[3] = 0x40; // Code
  dataTX[4] = 0x01; // Number of targets
  dataTX[5] = 0x30; //ReadCode
  dataTX[6] = address;  //Read address
  dataTX[7] = 0x00;
  checkSum(dataTX);
  sendTX(dataTX , 8, 30);
  memset(readData, 0x00, 16);  

  if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x41) & (dataRX[11] == 0x00)) {
    for (int i = 12; i < 28; i++) {
      readData[i-12] = dataRX[i];
    }
    return 0;
  } 
  else {
    return 1;
  }
}
//**********************************************************************
//!The PN532 sends back the version of the embedded firmware.
bool getFirmware(void)  //! It is needed to launch a simple command to sycnchronize
{
  //Serial.print("                ");

  memset(dataTX, 0x00, 35);
  dataTX[0] = 0x02; // Length
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4; // CODE
  dataTX[3] = 0x02; //TFI
  checkSum(dataTX); //0x2A; //Checksum   

  sendTX(dataTX , 5 , 17);

  printf("\nYour Firmware version is : ");

  for (int i = 11; i < (15) ; i++){
    printf("%x", dataRX[i]);
    printf(" ");
  }
  printf("\n");
}

//**********************************************************************
//!Print data stored in vectors .
void print(uint8_t * _data, uint8_t length)
{
	for (int i = 0; i < length ; i++){
		printf("%x",_data[i]);
		printf(" ");
	}
	printf("\n");
}
//**********************************************************************
//!This command is used to set internal parameters of the PN532,
bool configureSAM(void)//! Configure the SAM
{
  //Serial.print("               ");

  dataTX[0] = 0x05; //Length
  lengthCheckSum(dataTX); // Length Checksum
  dataTX[2] = 0xD4;
  dataTX[3] = 0x14;
  dataTX[4] = 0x01; //Normal mode
  dataTX[5] = 0x14; // TimeOUT
  dataTX[6] = 0x00; // IRQ
  dataTX[7] = 0x00; // Clean checkSum position
  checkSum(dataTX);

  sendTX(dataTX , 8, 13);
}
//**********************************************************************
//!Send data stored in dataTX
void sendTX(uint8_t *dataTX, uint8_t length, uint8_t outLength)
{
	Serial.print(0x00, BYTE);
	Serial.print(0x00, BYTE);
	Serial.print(0xFF, BYTE); 

	for (int i = 0; i < length; i++) {
		Serial.print(dataTX[i], BYTE);
	}

	Serial.print(0x00, BYTE);
	getACK();
	waitResponse();// Receive response
	getData(outLength);
}
//**********************************************************************
//!Wait for ACK response and stores it in the dataRX buffer
void getACK(void)
{
  delay(5);
  waitResponse();
  for (int i = 0; i < 5 ; i++) {
    dataRX[i] = Serial.read();
  }
}
//**********************************************************************
//!Wait the response of the module
void waitResponse(void)
{
  int val = 0xFF;
  int cont = 0x00;
  while(val != 0x00) {
    val = Serial.read();
    delay(5);
    cont ++;
  }
}
//**********************************************************************
//!Get data from the module
void getData(uint8_t outLength)
{
  for (int i=5; i < outLength; i++) {
    dataRX[i] = Serial.read(); // read data from the module.
  }
}
//**********************************************************************
//!Calculates the checksum and stores it in dataTX buffer
void checkSum(uint8_t *dataTX)
{
  for (int i = 0; i < dataTX[0] ; i++) {
    dataTX[dataTX[0] + 2] += dataTX[i + 2];
  }
  byte(dataTX[dataTX[0] + 2]= - dataTX[dataTX[0] + 2]);
}
//**********************************************************************
//!Calculates the length checksum and sotres it in the buffer.
uint8_t lengthCheckSum(uint8_t *dataTX)
{
  dataTX[1] = byte(0x100 - dataTX[0]);
}
//**********************************************************************
//compare 2 arrays
uint8_t equalUIDs(uint8_t *UID1 , uint8_t *UID2)

{

  if (memcmp(UID1, UID2, 4) == 0) return 0; 
  else return 1;

}
//**********************************************************************



int main (){
	setup();
	while(1){
		loop();
	}
	return (0);
}

        

Intel Galileo:

Code:
			
/*  
 *  RFID 13.56 MHz / NFC Module
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.0
 *  Design:            David GascĂłn 
 *  Implementation:    Jorge Casanova, Luis MartĂ­n
 */
 
// include the library code:
#include <LiquidCrystal.h>


//define constants
#define RED 6
#define GREEN 10
#define BLUE 11
#define BUZZ 9

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 8, 5, 4, 3, 2);

struct worker {
  
  char name[16];
  uint8_t acces_level;
  uint8_t visits;
  uint8_t UID[4];
  
};

struct RGB{
      
      uint8_t r;
      uint8_t g;
      uint8_t b;
      
    };

  //create and initilize users
  worker user[3];

  //colours
  
  RGB orange = {0,225,255};
  RGB lime = {64, 0, 255};
  RGB cyan = {255, 79, 9};
  RGB off = {255,255,255};
  RGB red = {0,255,255};
  RGB white = {0,0,0};
  RGB purple = {100,255,100};


  //RFID needed
  
  uint8_t dataRX[35];//Receive buffer.
  uint8_t dataTX[35];//Transmit buffer.
  uint8_t _UID[4]; // stores the UID (unique identifier) of a card.
  uint8_t blockData[] =	{0x10, 0x11,  0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};//Data to write (16 bytes).
  uint8_t keyAccess[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };// stores the key or password.
  uint8_t address = 0x04;//Address to read.
  uint8_t ATQ[2];//Answer to request
  uint8_t state1;//state of the process
  uint8_t state2;
  uint8_t aux[16];//Auxiliar buffer. 
  uint8_t aux1[] = {0x64,0x9E,0xCD,0xEA};
  uint8_t aux2[] = {0xA4,0x03,0xCE,0xEA};
  uint8_t aux3[] = {0x34,0x2C,0xCB,0xEA};
  
void setup() {

  pinMode(RED,OUTPUT);
  pinMode(GREEN,OUTPUT);
  pinMode(BLUE,OUTPUT);
  analogWrite(BUZZ,128);
  delay(100);
  analogWrite(BUZZ,0);
  lcd.begin(16, 2);
  lcd.print("SecureSys");
  lcd.setCursor(0,2);
  lcd.print("Keeps safe all");
  delay(3000);
  //initialize serial comm port at 115200bps
  Serial.begin(115200);
  //initialize uart at 115200bps
  Serial1.begin(115200);
  //initialize users
  strcpy(user[0].name, "Lewis Marvin    ");
  user[0].UID[0] = 0x64;
  user[0].UID[1] = 0x9E;
  user[0].UID[2] = 0xCD;
  user[0].UID[3] = 0xEA;
  print(user[0].UID,4);
  user[0].acces_level = 3;
  user[0].visits = 0;
  strcpy(user[1].name, "Mark Bean       ");
  user[1].UID[0] = 0xA4;
  user[1].UID[1] = 0x03;
  user[1].UID[2] = 0xCE;
  user[1].UID[3] = 0xEA;
  print(user[1].UID,4);
  user[1].acces_level = 1;
  user[1].visits = 0;
  strcpy(user[2].name, "George Slaughter");
  user[2].UID[0] = 0x34;
  user[2].UID[1] = 0x2C;
  user[2].UID[2] = 0xCB;
  user[2].UID[3] = 0xEA;
  print(user[2].UID,4);
  user[2].acces_level = 2;
  user[2].visits = 0;
  getFirmware();
  configureSAM();
  
}

void loop() {
  
  lcd.clear();
  lcd.print("Scanning...");
  setColour(lime.r,lime.g,lime.b);
  
  //reading card loop
  init(_UID, ATQ);
   
  Serial.print( "The Card UID : ");
  print(_UID , 4);
  //search user
  boolean found = false;
  byte user_found;
  for(byte i = 0; i<3; i++){
    //check if it is a "known" card by reading the UID
    if (!equalUIDs(user[i].UID,_UID)){
      print(user[i].UID,4);
      print(_UID , 4);
      lcd.clear();
      lcd.print("User:");
      lcd.setCursor(0,2);
      lcd.print(user[i].name);
      found = true;
      user_found = i;
      state1 = authenticate(_UID, address, keyAccess);
      state2 = readData(address, aux);
      for (byte j=0; j<5; j++){
        setColour(off.r,off.g,off.b);
        delay(200);
        setColour(white.r,white.g,white.b);
        delay(200);
      }
    }
    setColour(lime.r,lime.g,lime.b);
  }
  if (found){
  /////////////////////////////////////////////////////////////
  //Auntenticate a block with his keyAccess
  

	if ( state1 == 0) {
  
	  lcd.clear();
          lcd.print("Correct card...");
          delay(1000);
          
	} else {
  
          

	}
	/////////////////////////////////////////////////////////////
	//Read from address after authentication

		Serial.print("\n");

		if (state2 == 0) {
                  
                  user[user_found].visits++;
                  lcd.clear();
                  lcd.print("You've been here");
                  lcd.setCursor(0,2);
                  lcd.print(user[user_found].visits);
                  lcd.setCursor(4,2);
                  lcd.print("times today");
                  delay(3000);
                  lcd.clear();
                  lcd.print("Acces level:");
                  lcd.setCursor(0,2);
                  lcd.print(user[user_found].acces_level);
                  delay(3000);
                  switch(user[user_found].acces_level){
                  
                  case 1:
                    lcd.clear();
                    lcd.print("Acces denied!");
                    setColour(red.r,red.g,red.b);
                    delay(1000);
                    analogWrite(BUZZ,78);
                    delay(1000);
                    analogWrite(BUZZ,0);
                    break;
                  
                  case 2:
                  
                    lcd.clear();
                    lcd.print("Acces granted!");
                    lcd.setCursor(0,2);
                    lcd.print("Go ahead!");
                    setColour(cyan.r, cyan.g, cyan.b);
                    delay(2000);
                    analogWrite(BUZZ,128);
                    delay(100);
                    analogWrite(BUZZ,0);
                    delay(100);
                    analogWrite(BUZZ,128);
                    delay(100);
                    analogWrite(BUZZ,0);
                    break;
                    
                  case 3:
                  
                    lcd.clear();
                    lcd.print("Total acces!");
                    lcd.setCursor(0,2);
                    lcd.print("Go ahead!");
                    setColour(purple.r, purple.g, purple.b);
                    delay(2000);
                    analogWrite(BUZZ,128);
                    delay(100);
                    analogWrite(BUZZ,0);
                    delay(100);
                    analogWrite(BUZZ,128);
                    delay(100);
                    analogWrite(BUZZ,0);
                    break;
                  }
        
		} else {
		  
                  lcd.clear();
                  lcd.print("Couldn't read");
                  lcd.setCursor(0,2);
                  lcd.print("Wave card again");
                  setColour(orange.r, orange.g, orange.b);
                  delay(3000);
                  
		}

  } else {
    
    lcd.clear();
    lcd.print("UID not found");
    lcd.setCursor(0,2);
    lcd.print("Please leave");
    setColour(red.r, red.g, red.b);
    delay(3000);
    
  }
  
  
}


//**********************************************************************
//!The goal of this command is to detect as many targets (maximum MaxTg)
// as possible in passive mode.
uint8_t init(uint8_t *UID , uint8_t *ATQ)   //! Request InListPassive
{
	Serial1.flush();

	dataTX[0] = 0x04; // Length
	lengthCheckSum(dataTX); // Length Checksum
	dataTX[2] = 0xD4;
	dataTX[3] = 0x4A; // Code
	dataTX[4] = 0x01; //MaxTarget
	dataTX[5] = 0x00; //BaudRate = 106Kbps
	dataTX[6] = 0x00; // Clear checkSum position
	checkSum(dataTX); 

	sendTX(dataTX , 7 ,23);

	for (int i = 17; i < (21) ; i++){
		_UID[i-17] = dataRX[i];
		UID[i-17] = _UID[i-17];
	}

	ATQ[0] = dataRX[13];
	ATQ[1] = dataRX[14];

	if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x4B) & (dataRX[11] == 0x01)) {
		return 0;
	} else {
		return 1;
	}
}
//**********************************************************************
 //!A block must be authenticated before read and write operations
uint8_t authenticate(uint8_t *UID, uint8_t blockAddress, uint8_t *keyAccess)
{
	dataTX[0] = 0x0F;
	lengthCheckSum(dataTX);
	dataTX[2] = 0xD4;
	dataTX[3] = 0x40; // inDataEchange
	dataTX[4] = 0x01; //Number of targets
	dataTX[5] = 0x60; // Authentication code
	dataTX[6] = blockAddress;

	for (int i = 0; i < 6 ; i++) {
		dataTX[i + 7] = keyAccess[i];
	}

	dataTX[13] = UID[0];  dataTX[14] = UID[1];
	dataTX[15] = UID[2];  dataTX[16] = UID[3];
	dataTX[17] = 0x00;
	checkSum(dataTX);
	sendTX(dataTX , 18 ,14);

	if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x41) & (dataRX[11] == 0x00)) {
		return 0;
	} else {
		return 1;
	}
}
//**********************************************************************
//!Write 16 bytes in address .
uint8_t writeData(uint8_t address, uint8_t *blockData)  //!Writing
{
	Serial1.print("                ");
	dataTX[0] = 0x15;
	lengthCheckSum(dataTX); // Length Checksum
	dataTX[2] = 0xD4;
	dataTX[3] = 0x40;  //inDataEchange CODE
	dataTX[4] = 0x01;  //Number of targets
	dataTX[5] = 0xA0; //Write Command
	dataTX[6] = address; //Address		

	for (int i = 0; i < 16; i++) {
		dataTX[i+7] = blockData[i];
	}

	dataTX[23] = 0x00;
	checkSum(dataTX);
	sendTX(dataTX , 24 ,14);  		

	if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x41) & (dataRX[11] == 0x00)) {
		return 0;
	} else {
		return 1;
	}
}
//**********************************************************************
//!Read 16 bytes from  address .
uint8_t readData(uint8_t address, uint8_t *readData) //!Reading
{
	Serial1.print("                ");		

	dataTX[0] = 0x05;
	lengthCheckSum(dataTX); // Length Checksum
	dataTX[2] = 0xD4; // Code
	dataTX[3] = 0x40; // Code
	dataTX[4] = 0x01; // Number of targets
	dataTX[5] = 0x30; //ReadCode
	dataTX[6] = address;  //Read address
	dataTX[7] = 0x00;
	checkSum(dataTX);
	sendTX(dataTX , 8, 30);
	memset(readData, 0x00, 16);  

	if ((dataRX[9]== 0xD5) & (dataRX[10] == 0x41) & (dataRX[11] == 0x00)) {
		for (int i = 12; i < 28; i++) {
			readData[i-12] = dataRX[i];
		}
		return 0;
	} else {
		return 1;
	}
}
//**********************************************************************
//!The PN532 sends back the version of the embedded firmware.
bool getFirmware(void)  //! It is needed to launch a simple command to sycnchronize
{
	Serial1.print("                ");

	memset(dataTX, 0x00, 35);
	dataTX[0] = 0x02; // Length
	lengthCheckSum(dataTX); // Length Checksum
	dataTX[2] = 0xD4; // CODE
	dataTX[3] = 0x02; //TFI
	checkSum(dataTX); //0x2A; //Checksum   

	sendTX(dataTX , 5 , 17);
	Serial.print("\n");
	Serial.print("Your Firmware version is : ");

	for (int i = 11; i < (15) ; i++){
		Serial.print(dataRX[i], HEX);
		Serial.print(" ");
	}
	Serial.print("\n");
}

//**********************************************************************
//!Print data stored in vectors .
void print(uint8_t * _data, uint8_t length)
{
	for (int i = 0; i < length ; i++){
		Serial.print(_data[i], HEX);
		Serial.print(" ");
	}
	Serial.print("\n");
}
//**********************************************************************
//!This command is used to set internal parameters of the PN532,
bool configureSAM(void)//! Configure the SAM
{
	Serial1.print("               ");

	dataTX[0] = 0x05; //Length
	lengthCheckSum(dataTX); // Length Checksum
	dataTX[2] = 0xD4;
	dataTX[3] = 0x14;
	dataTX[4] = 0x01; //Normal mode
	dataTX[5] = 0x14; // TimeOUT
	dataTX[6] = 0x00; // IRQ
	dataTX[7] = 0x00; // Clean checkSum position
	checkSum(dataTX);

	sendTX(dataTX , 8, 13);
}
//**********************************************************************
//!Send data stored in dataTX
void sendTX(uint8_t *dataTX, uint8_t length, uint8_t outLength)
{
	Serial1.print(char(0x00));
	Serial1.print(char(0x00));
	Serial1.print(char(0xFF)); 

	for (int i = 0; i < length; i++) {
		Serial1.print(char(dataTX[i]));
	}

	Serial1.print(char(0x00));
	getACK();
	waitResponse();    // 1C - receive response
	getData(outLength);
}
//**********************************************************************
//!Wait for ACK response and stores it in the dataRX buffer
void getACK(void)
{
	delay(5);
	waitResponse();
	for (int i = 0; i < 5 ; i++) {
		dataRX[i] = Serial1.read();
	}
}
//**********************************************************************
//!Wait the response of the module
void waitResponse(void)
{
	int val = 0xFF;
	int cont = 0x00;
	while(val != 0x00) {
		val = Serial1.read();
		delay(5);
		cont ++;
	}
}
//**********************************************************************
//!Get data from the module
void getData(uint8_t outLength)
{
	for (int i=5; i < outLength; i++) {
		dataRX[i] = Serial1.read(); // read data from the module.
	}
}
//**********************************************************************
//!Calculates the checksum and stores it in dataTX buffer
void checkSum(uint8_t *dataTX)
{
	for (int i = 0; i < dataTX[0] ; i++) {
		dataTX[dataTX[0] + 2] += dataTX[i + 2];
	}
	byte(dataTX[dataTX[0] + 2]= - dataTX[dataTX[0] + 2]);
}
//**********************************************************************
//!Calculates the length checksum and sotres it in the buffer.
uint8_t lengthCheckSum(uint8_t *dataTX)
{
	dataTX[1] = byte(0x100 - dataTX[0]);
}
//**********************************************************************
//compare 2 arrays
 uint8_t equalUIDs(uint8_t *UID1 , uint8_t *UID2)

	{

		if (memcmp(UID1, UID2, 4) == 0) return 0; else return 1;

	}
//**********************************************************************
//
void setColour(uint8_t r, uint8_t g, uint8_t b){

  analogWrite(RED,r);
  analogWrite(GREEN,g);
  analogWrite(BLUE,b);

}