My Cart

How to Control a Servo with an RFID Tag Using Smart Cards Kit (NFC/RFID 13.56MHz)

Difficulty Level: Expert -

1. Introduction

This tutorial allows the user to move the servo (open and close a barrier) if the key of the RFID card is correct.

Ingredients:

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 servo in the breadboard as you can see in the next diagram.

Connect Black/Brown wire of the servo to GND, Red wire to 5 volt and the remaining wire, Yellow/Orange, to pin 9 of Arduino.

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 <Servo.h>.

#define CLOSED_DOOR 90
#define OPEN_DOOR 180

uint8_t dataRX[35];//Receive buffer.
uint8_t dataTX[35];//Transmit buffer.
//stores the status of the executed command:
short state;
//auxiliar buffer:
unsigned char aux[16];
//stores the UID (unique identifier) of a card:
unsigned char _CardID[4];
//stores the key
unsigned char key[]= {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};// Old key access.
//password stored in block 4 to check before open the door
uint8_t password[]= {
  0x10, 0x11,  0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
//open the door
boolean door_open = false;
//only edit config if strong knowledge about the RFID/NFC module
unsigned char config[] = {
  0xFF, 0x07, 0x80, 0x69};
//key block
uint8_t key_address = 7;
//block where password is stored
uint8_t password_address = 4;
//variable to check time lapse
uint32_t time;
//Servo constructor
Servo garage_door;


void setup()
{
  // start serial port 115200 bps:
  Serial.begin(115200);
  Serial.print("RFID/NFC @ 13.56 MHz module started");
  delay(1000);

  Serial.flush();
  //drive servo to its initial position
  garage_door.attach(9);
  garage_door.write(CLOSED_DOOR);
  //give some time servo to respond
  delay(500);
}

void loop()
{
  //need to detach servo to use RFID
  garage_door.detach();
  //! It is needed to launch a simple command to sycnchronize
  getFirmware();
  configureSAM();
  Serial.println("Welcome");
  Serial.println("Ready to check card");
  init(_CardID, aux);
  /////////////////////////////////////////////////////////////
  //Auntenticate a block with his keyAccess
  state = authenticate(_CardID, password_address, key);
  if ( state == 0) {
    Serial.print("\n");
    Serial.print( "The UID : ");
    print(_CardID , 4);
    Serial.print("\n");
    Serial.println("Authentication block OK");
  } 
  else {
    Serial.println("Authentication failed");
  }
  /////////////////////////////////////////////////////////////
  //Read from address after authentication
  state = readData(password_address, aux);
  Serial.print("\n");
  //
  if (state == 0) {
    Serial.println("Checking card password");
    for (byte i = 0; i<16; i++){
      if ( aux[i] == password[i]){
        //if data read from block matches with password, open the door
        door_open = true;

      } 
      else {
        //if data read from block does not match with password, keep it close
        door_open = false;
        i = 16;

      }
    }

  } 
  else {

    Serial.println("Read failed, wave the card again please");
  }

  delay(2000);
  time = millis();
  //open the door 5 seconds
  if (door_open){
    //attach the servo to move the door
    garage_door.attach(9);
    //writes the angle corresponding to open the door
    garage_door.write(OPEN_DOOR);
    while (door_open){    
      //wait for 5 seconds
      if (millis()-time > 5000) door_open = false;
    }
    //close the door
    garage_door.write(CLOSED_DOOR);
    //give some time servo to respond
    delay(500);
  }

}

//**********************************************************************
//!The goal of this command is to detect as many targets (maximum MaxTg)
//  as possible in passive mode.
uint8_t init(uint8_t *CardID , 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++){
    _CardID[i-17] = dataRX[i];
    CardID[i-17] = _CardID[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 *CardID, 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] = CardID[0];  
  dataTX[14] = CardID[1];
  dataTX[15] = CardID[2];  
  dataTX[16] = CardID[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) { //Wait for 0x00 response
    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]);
}
//**********************************************************************
//Prints via serial data read from the TAG in block "read_adress"
void printData()
{
  Serial.print("\n");
  Serial.println("Ready to read...");
  /////////////////////////////////////////////////////////////
  //Get the UID Identifier
  init(_CardID, aux);
  Serial.print("\n");
  Serial.print( "The UID : ");
  print(_CardID , 4);
  /////////////////////////////////////////////////////////////
  //Auntenticate a block with his keyAccess
  state = authenticate(_CardID, password_address, key);
  Serial.print("\n");

  if ( state == 0) {
    Serial.println("Authentication block OK");
  } 
  else {
    Serial.println("Authentication failed");
  }
  /////////////////////////////////////////////////////////////
  //Read from address after authentication
  state = readData(password_address, aux);
  Serial.print("\n");

  if (state == 0) {
    Serial.println("Read block OK");
  } 
  else {
    Serial.println("Read failed");
  }

  Serial.print("\n");
  Serial.print("Data read: ");
  print(aux , 16);
  Serial.print("\n");
}


        

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:    Jorge Casanova, Luis MartĂ­n
 */
 
#include "arduPi.h"

//#include <Servo.h>

//#define CLOSED_DOOR 0.9
//#define OPEN_DOOR 2.1

int SERVO = 9;

int servoState = LOW;     

unsigned long previousMillis = 0;   


uint8_t dataRX[35];//Receive buffer.
uint8_t dataTX[35];//Transmit buffer.
//stores the status of the executed command:
short state;
//auxiliar buffer:
unsigned char aux[16];
//stores the UID (unique identifier) of a card:
unsigned char _CardID[4];
//stores the key
unsigned char key[]= {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};// Old key access.
//password stored in block 4 to check before open the door
uint8_t password[]= {
  0x10, 0x11,  0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
//open the door
boolean door_open = false;
//only edit config if strong knowledge about the RFID/NFC module
unsigned char config[] = {
  0xFF, 0x07, 0x80, 0x69};
//key block
uint8_t key_address = 7;
//block where password is stored
uint8_t password_address = 4;
//variable to check time lapse
uint32_t timead;
//Servo constructor
//Servo garage_door;

uint8_t init(uint8_t *CardID , uint8_t *ATQ);
uint8_t authenticate(uint8_t *CardID, 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);
void printData();

const long CLOSED_DOOR = 0.9;
const long OPEN_DOOR = 2.1;

void setup()
{
  
  pinMode(SERVO, OUTPUT);
  // start serial port 115200 bps:
  Serial.begin(115200);
  //Serial.print("RFID/NFC @ 13.56 MHz module started");
  printf("RFID/NFC @ 13.56 MHz module started\n");
  //delay(1000);

  Serial.flush();
  //drive servo to its initial position
  
  
  int tiempo = millis();
  while (millis()-tiempo < 1000) {
	  
  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis >= CLOSED_DOOR) {
    previousMillis = currentMillis;   

    if (servoState == LOW)
      servoState = HIGH;
    else
      servoState = LOW;
    digitalWrite(SERVO, servoState);
  }
}
}

void loop() {
  unsigned long currentMillis = millis();
  //need to detach servo to use RFID
  //garage_door.detach();
  // ! It is needed to launch a simple command to sycnchronize
  getFirmware();
  configureSAM();
  printf("Welcome\n");
  printf("Ready to check card\n");
  init(_CardID, aux);
  /////////////////////////////////////////////////////////////
  //Auntenticate a block with his keyAccess
  state = authenticate(_CardID, password_address, key);
  if ( state == 0) {
    
    printf("\n");
    printf( "The UID : ");
    print(_CardID , 4);
    printf("\n");
    printf("Authentication block OK\n");
  } 
  else {
    printf("Authentication failed\n");
  }
  /////////////////////////////////////////////////////////////
  //Read from address after authentication
  state = readData(password_address, aux);
  printf("\n");
  //
  if (state == 0) {
    printf("Checking card password\n");
    for (byte i = 0; i<16; i++){
      if ( aux[i] == password[i]){
        //if data read from block matches with password, open the door
        door_open = true;
      } 
      else {
        //if data read from block does not match with password, keep it close
        door_open = false;
        i = 16;
      }
    }

  } 
  else {

    printf("Read failed, wave the card again please\n");
  }

  delay(2000);
  timead = millis();
  //open the door 5 seconds
  if (door_open){
    //attach the servo to move the door
    //garage_door.attach(9);
    //writes the angle corresponding to open the door
   int tiempo1 = millis(); 
  while (millis()-tiempo1 < 1000) {
	  
  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis >= OPEN_DOOR) {
    previousMillis = currentMillis;   

    if (servoState == LOW)
      servoState = HIGH;
    else
      servoState = LOW;
    digitalWrite(SERVO, servoState);
  }
}
  
    while (door_open){    
      //wait for 5 seconds
      if (millis()-timead > 5000) door_open = false;
    }
    //close the door
    int tiempo2 = millis();
   while (millis()-tiempo2 < 1000) {
	  
  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis >= CLOSED_DOOR) {
    previousMillis = currentMillis;   

    if (servoState == LOW)
      servoState = HIGH;
    else
      servoState = LOW;
    digitalWrite(SERVO, servoState);
  }
}
  
    //give some time servo to respond
    delay(500);
  }

}

//**********************************************************************
//!The goal of this command is to detect as many targets (maximum MaxTg)
//  as possible in passive mode.
uint8_t init(uint8_t *CardID , 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++){
    _CardID[i-17] = dataRX[i];
    CardID[i-17] = _CardID[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 *CardID, 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] = CardID[0];  
  dataTX[14] = CardID[1];
  dataTX[15] = CardID[2];  
  dataTX[16] = CardID[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
{
  printf("                \n");
  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
{
  printf("                \n");		

  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
{
  printf("                \n");		
  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("\n");
  printf("Your Firmware version is : \n");

  for (int i = 11; i < (15) ; i++){
    Serial.print(dataRX[i], HEX);
    printf(" \n");
  }
  printf("\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);
    printf(" \n");
  }
  printf("\n");
}
//**********************************************************************
//!This command is used to set internal parameters of the PN532,
bool configureSAM(void)//! Configure the SAM
{
  printf("               \n");
  printf("configureSAM\n");
  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) { //Wait for 0x00 response
    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]);
}
//**********************************************************************
//Prints via serial data read from the TAG in block "read_adress"
void printData()
{
  printf("\n");
  printf("Ready to read...\n");
  /////////////////////////////////////////////////////////////
  //Get the UID Identifier
  init(_CardID, aux);
  printf("\n");
  printf( "The UID : \n");
  print(_CardID , 4);
  /////////////////////////////////////////////////////////////
  //Auntenticate a block with his keyAccess
  state = authenticate(_CardID, password_address, key);
  printf("\n");

  if ( state == 0) {
    printf("Authentication block OK\n");
  } 
  else {
    printf("Authentication failed\n");
  }
  /////////////////////////////////////////////////////////////
  //Read from address after authentication
  state = readData(password_address, aux);
  printf("\n");

  if (state == 0) {
    printf("Read block OK\n");
  } 
  else {
    printf("Read failed\n");
  }

  printf("\n");
  printf("Data read: \n");
  print(aux , 16);
  printf("\n");
}


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 <Servo.h>

#define CLOSED_DOOR 0
#define OPEN_DOOR 180

uint8_t dataRX[35];//Receive buffer.
uint8_t dataTX[35];//Transmit buffer.
//stores the status of the executed command:
short state;
//auxiliar buffer:
unsigned char aux[16];
//stores the UID (unique identifier) of a card:
unsigned char _CardID[4];
//stores the key
unsigned char key[]= {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};// Old key access.
//password stored in block 4 to check before open the door
uint8_t password[]= {
  0x10, 0x11,  0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
//open the door
boolean door_open = false;
//only edit config if strong knowledge about the RFID/NFC module
unsigned char config[] = {
  0xFF, 0x07, 0x80, 0x69};
//key block
uint8_t key_address = 7;
//block where password is stored
uint8_t password_address = 4;
//variable to check time lapse
uint32_t timead;
//Servo constructor
Servo garage_door;


void setup()
{  
  // start serial port 115200 bps:
  Serial.begin(115200);	//pc comm serial
  Serial1.begin(115200);//uart comm with rfid module
  Serial.print("RFID/NFC @ 13.56 MHz module started");
  delay(1000);

  Serial1.flush();
  //drive servo to its initial position
  garage_door.attach(9);
  garage_door.write(CLOSED_DOOR);
  //give some time to servo to respond
  delay(500);
  // It is needed to launch a simple command to sycnchronize
  getFirmware();
  configureSAM();
}

void loop()
{
  Serial.println();
  Serial.println("Welcome");
  Serial.println("Ready to check card");
  init(_CardID, aux);
  /////////////////////////////////////////////////////////////
  //Auntenticate a block with his keyAccess
  state = authenticate(_CardID, password_address, key);
  if ( state == 0) {
    Serial.print("\n");
    Serial.print( "The UID : ");
    print(_CardID , 4);
    Serial.print("\n");
    Serial.println("Authentication block OK");
  } 
  else {
    Serial.println("Authentication failed");
  }
  /////////////////////////////////////////////////////////////
  //Read from address after authentication
  state = readData(password_address, aux);
  Serial.print("\n");
  //
  if (state == 0) {
    Serial.println("Checking card password");
    for (byte i = 0; i<16; i++){
      if ( aux[i] == password[i]){
        //if data read from block matches with password, open the door
        door_open = true;
        Serial.println("Abriendo");

      } 
      else {
        //if data read from block does not match with password, keep it close
        door_open = false;
        i = 16;
        Serial.println("Fallo");

      }
    }

  } 
  else {

    Serial.println("Read failed, wave the card again please");
  }

  delay(2000);
  timead = millis();
  //open the door 5 seconds
  if (door_open){   
    //writes the angle corresponding to open the door
    garage_door.write(OPEN_DOOR);  
    while (door_open){    
      //wait for 5 seconds
      if (millis()-timead > 5000) door_open = false;
    }
    //close the door
    garage_door.write(CLOSED_DOOR);
    //give some time servo to respond
    delay(500);
  }

}

//**********************************************************************
//!The goal of this command is to detect as many targets (maximum MaxTg)
//  as possible in passive mode.
uint8_t init(uint8_t *CardID , 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++){
    _CardID[i-17] = dataRX[i];
    CardID[i-17] = _CardID[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 *CardID, 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] = CardID[0];  
  dataTX[14] = CardID[1];
  dataTX[15] = CardID[2];  
  dataTX[16] = CardID[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) { //Wait for 0x00 response
    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]);
}
//**********************************************************************
//Prints via serial data read from the TAG in block "read_adress"
void printData()
{
  Serial.print("\n");
  Serial.println("Ready to read...");
  /////////////////////////////////////////////////////////////
  //Get the UID Identifier
  init(_CardID, aux);
  Serial.print("\n");
  Serial.print( "The UID : ");
  print(_CardID , 4);
  /////////////////////////////////////////////////////////////
  //Auntenticate a block with his keyAccess
  state = authenticate(_CardID, password_address, key);
  Serial.print("\n");

  if ( state == 0) {
    Serial.println("Authentication block OK");
  } 
  else {
    Serial.println("Authentication failed");
  }
  /////////////////////////////////////////////////////////////
  //Read from address after authentication
  state = readData(password_address, aux);
  Serial.print("\n");

  if (state == 0) {
    Serial.println("Read block OK");
  } 
  else {
    Serial.println("Read failed");
  }

  Serial.print("\n");
  Serial.print("Data read: ");
  print(aux , 16);
  Serial.print("\n");
}