My Cart

How to Change Keys on RFID Tags Using Smart Cards Kit (NFC/RFID 13.56MHz)

Difficulty Level: Intermediate -

1. Introduction

This tutorial allows the user to change keys on RFID cards. Also you can read the cards if the key is correct. Each button has a function assigned: enter to change key mode (then you can write your new key with this 4 buttons), save new key and read card.

Ingredients:

    - 1 x Smart Cards Kit (NFC/RFID 13.56MHz):
    • 1x Platform
    • 1x NFC/RFID 13.56MHz
    • 4x Buttons
    • 4x 220Ω resistors
    • 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 buttons with the resistors 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. Then, connect digital pin 10, 11, 12 and 13 to one leg of each pushbutton. That same leg of the button connects through a pull-down resistor to ground. The other leg of the button connects to the 5 volts supply.

When the pushbutton is open (unpressed) there is no connection between the two legs of the pushbutton, so the pin is connected to ground (through the pull-down resistor) and reads as LOW, or 0. When the button is closed (pressed), it makes a connection between its two legs, connecting the pin to 5 volts, so that the pin read as HIGH, or 1.

WARNING: In Raspberry Pi, GPIO voltage levels are 3.3 V and are not 5 V tolerant. There is no over-voltage protection on the board. Digital inputs use a 3V3 logic level and are not tolerant of 5V levels, such as you might find on a 5V powered Arduino. Extreme caution when working with GPIO, you may damage your Raspberry Pi, your equipment and potentially yourself and others. Doing so is at your own risk!

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Ă­
 */

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 or password:
//password digits go from 1 to 4 and they are stored in the first 8 nibbles as hex {0xXX,0xXX,0xXX,0xXX,0xFF,0xFF}
unsigned char keyOld[]= {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};// Old key access(use the last one stored)
unsigned char keyA[]= {
  0x43, 0x34, 0x34, 0x43, 0xFF, 0xFF};//NEW KEY ACCESS
unsigned char keyB[]= {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//Secundary KEY ACCESS
unsigned char digit[8];//stores digits read from the buttons
unsigned char temp;
//only edit config if strong knowledge about the RFID/NFC module
unsigned char config[] = {
  0xFF, 0x07, 0x80, 0x69};
uint8_t key_address = 7;
uint8_t read_adress = 4;

void setup()
{
  // start serial port 115200 bps:
  Serial.begin(115200);
  Serial.print("RFID/NFC @ 13.56 MHz module started");
  delay(1000);
  //! It is needed to launch a simple command to sycnchronize
  getFirmware();
  configureSAM();
  delay(1000); 
  Serial.println("Welcome");
  Serial.println("To set a new password push '1'");
  Serial.println("To enter a password push '2'");
  Serial.println("To read data push '3'");
  Serial.flush();
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(12,OUTPUT);

}

void loop()
{


  if (digitalRead(10)){

    saveNewPass();//when buttoon 1 pushed starts the keyA writting

  }
  if (digitalRead(11)){

    saveOldPass();//stores the keyA to read the tag

  }
  if (digitalRead(12)){

    printData();//reads data from tag and prints it throgh serial

  }
} 


//**********************************************************************
//!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) {
    val = Serial.read();
    delay(5);
    cont ++;  
    if (cont>=1000){
      val = 0;
    }
  }
}
//**********************************************************************
//!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]);
}
//**********************************************************************
//Changes both keys and access conditions to one card's sector
uint8_t setKeys(uint8_t *CardID,uint8_t *keyOld,uint8_t *keyA,uint8_t *keyB,uint8_t *config,uint8_t *data,uint8_t add)
{
  uint8_t state = 1; 

  if (((add+1) % 4) == 0){
    state = authenticate(CardID , add, keyOld);
    if (state == 0) {
      for (int i = 0; i < 6; i++) {
        data[i] = keyA[i];
        data[i+ 10] = keyB[i];
      }

      for (int i = 0; i < 4 ; i++) {
        data[i + 6] = config[i];
      }
      state = writeData(add, data);
    }
  }
  return state;
}
//**********************************************************************
//This function stores in "keyA[]" the new password and sets it into the tag
void saveNewPass()
{

  Serial.print("Enter the new password: ");
  delay(300);
  /////////////////////////////////////////////////////////////
  //Read digital pins from 10 to 13 until it has recorded 8 beats
  byte pass_lenght = 8;
  byte i = 0;
  while(i<pass_lenght){
    //get a 1 to the password
    if (digitalRead(10)){

      digit[i] = digitalRead(10)*1;
      Serial.print(digit[i]*1);
      i++;
      delay(500);
    }
    //get a 2 to the password
    if ( digitalRead(11) ){

      digit[i] = digitalRead(11)*2;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
    //get a 3 to the password
    if ( digitalRead(12)){

      digit[i] = digitalRead(12)*3;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
    //get a 4 to the password
    if ( digitalRead(13)){

      digit[i] = digitalRead(13)*4;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
  }
  Serial.println();
  /////////////////////////////////////////////////////////////
  //Stores data from buttons in "keyA" so the password is located
  //into the first 4 bytes
  for (byte i = 1; i <= 4; i++){
    temp = digit[(i*2)-2]<<4;
    keyA[i-1] = temp;
    Serial.print(temp>>4,HEX);
    temp = digit[(i*2)-1];
    keyA[i-1] |= temp;
    Serial.print(temp,HEX);
    Serial.print(" ");
  }
  delay(100);
  Serial.print("\r\n++++++++++++++++++++++++++++++++++++");
  // **** init the RFID/NFC reader
  state = init(_CardID, aux);
  if (aux[0] == aux[1]) {// if so, there is no card on the EM field
    Serial.print("\r\nRequest error - no card found");
  } 
  else { // a card was found

    Serial.print("\r\nRequest | Answer: ");
    print(aux, 2);  //show the ATQ

    Serial.print("\r\nAnticollSelect: ");
    Serial.print(state, HEX);//show the status of the executed init command(should be 0)
    Serial.print(" | Answer: ");
    print(_CardID, 4); //show the UID (Unique IDentifier) of the read card (4 bytes)

    //Write new key in block then authenticate this address and get the new value
    state = setKeys(_CardID, keyOld, keyA, keyB, config, aux, key_address);
    Serial.print("\r\n**write new key, state: ");
    Serial.print(state, HEX);

    if (state == 0) {
      Serial.print(" --> correct key change ");
      for (byte i=0; i<8;i++){

        keyOld[i] = keyA[i];

      }
    } 
    else {
      Serial.print(" --> ** ERROR: keys not changed ** ");
    }	 // ###### check block 3/7/11/15 (the keys will return 0s)
    // **** authenticate again, now with the new key A

    state = authenticate(_CardID, key_address , keyA);
    Serial.print("\r\n**Authentication block: ");
    Serial.print(state, HEX);

    if (state == 0) {
      Serial.print(" --> correct authentication ");
    }
    else {
      Serial.print(" --> ** ERROR: bad authentication ** ");
    }

  }
  Serial.println();
}

//**********************************************************************
//This function stores in "keyOld[]" the password used to access the card
//both to read or set a new key
void saveOldPass()
{

  Serial.print("Enter the password: ");
  delay(500);
  /////////////////////////////////////////////////////////////
  //Read digital pins from 10 to 13 until it has recorded 8 beats
  byte pass_lenght = 8;
  byte i = 0;
  //keep reading buttons until get the 8 digit password
  while(i<pass_lenght){

    //get a 1 to the password
    if (digitalRead(10)){

      digit[i] = digitalRead(10)*1;
      Serial.print(digit[i]*1);
      i++;
      delay(500);
    }
    //get a 2 to the password
    if ( digitalRead(11) ){

      digit[i] = digitalRead(11)*2;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
    //get a 3 to the password
    if ( digitalRead(12)){

      digit[i] = digitalRead(12)*3;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
    //get a 4 to the password
    if ( digitalRead(13)){

      digit[i] = digitalRead(13)*4;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
  }
  Serial.println();
  /////////////////////////////////////////////////////////////
  //Stores data from buttons in "keyOld" so the password is located
  //into the first 4 bytes
  for (byte i = 1; i <= 4; i++){
    temp = digit[(i*2)-2]<<4;
    keyOld[i-1] = temp;
    Serial.print(temp>>4,HEX);
    temp = digit[(i*2)-1];
    keyOld[i-1] |= temp;
    Serial.print(temp,HEX);
    Serial.print(" ");
  }
  Serial.println();
}

//**********************************************************************
//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, read_adress, keyOld);
  Serial.print("\n");

  if ( state == 0) {
    Serial.println("Authentication block OK");
  } 
  else {
    Serial.println("Authentication failed");
  }
  /////////////////////////////////////////////////////////////
  //Read from address after authentication
  state = readData(read_adress, 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"


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 or password:
//password digits go from 1 to 4 and they are stored in the first 8 nibbles as hex {0xXX,0xXX,0xXX,0xXX,0xFF,0xFF}
unsigned char keyOld[]= {
  0x44, 0x44, 0x44, 0x44, 0xFF, 0xFF};// Old key access(use the last one stored)
unsigned char keyA[]= {
  0x43, 0x34, 0x34, 0x43, 0xFF, 0xFF};//NEW KEY ACCESS
unsigned char keyB[]= {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//Secundary KEY ACCESS
unsigned char digit[8];//stores digits read from the buttons
unsigned char temp;
//only edit config if strong knowledge about the RFID/NFC module
unsigned char config[] = {
  0xFF, 0x07, 0x80, 0x69};
uint8_t key_address = 7;
uint8_t read_adress = 4;

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);
uint8_t setKeys(uint8_t *CardID,uint8_t *keyOld,uint8_t *keyA,uint8_t *keyB,uint8_t *config,uint8_t *data,uint8_t add);
void saveNewPass();
void saveOldPass();
void printData();

void setup()
{
  // start serial port 115200 bps:
  pinMode(9, INPUT);
  pinMode(11, INPUT);
  pinMode(12, INPUT);
  pinMode(13, INPUT);
  
  Serial.begin(115200);
  
  printf("RFID/NFC @ 13.56 MHz module started\n");
  delay(1000);
  //! It is needed to launch a simple command to sycnchronize
  getFirmware();
  configureSAM();
  delay(1000); 
  printf("Welcome\n");
  printf("To set a new password push '1'\n");
  printf("To enter a password push '2'\n");
  printf("To read data push '3'\n");
  Serial.flush();

}

void loop()
{

  if (digitalRead(9)){
    saveNewPass();//when buttoon 1 pushed starts the keyA writting

  }
  if (digitalRead(11)){
    saveOldPass();//stores the keyA to read the tag

  }
  if (digitalRead(12)){
    printData();//reads data from tag and prints it throgh serial

  }
} 


//**********************************************************************
//!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");

  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 ++;  
    if (cont>=1000){
      val = 0;
    }
  }
}
//**********************************************************************
//!Get data from the module
void getData(uint8_t outLength)
{
	int i = 5;
  //for (int i=5; i < outLength; i++) {
  while (i < outLength){
    dataRX[i] = Serial.read(); // read data from the module.
    i++;
    //printf("%i\n",i);
    delay(5);
  }
}
//**********************************************************************
//!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]);
}
//**********************************************************************
//Changes both keys and access conditions to one card's sector
uint8_t setKeys(uint8_t *CardID,uint8_t *keyOld,uint8_t *keyA,uint8_t *keyB,uint8_t *config,uint8_t *data,uint8_t add)
{
  uint8_t state = 1; 

  if (((add+1) % 4) == 0){
    state = authenticate(CardID , add, keyOld);
    if (state == 0) {
      for (int i = 0; i < 6; i++) {
        data[i] = keyA[i];
        data[i+ 10] = keyB[i];
      }

      for (int i = 0; i < 4 ; i++) {
        data[i + 6] = config[i];
      }
      state = writeData(add, data);
    }
  }
  return state;
}

//**********************************************************************
//This function stores in "keyA[]" the new password and sets it into the tag
void saveNewPass()
{

  printf("Enter the new password: \n");
  delay(300);
  /////////////////////////////////////////////////////////////
  //Read digital pins from 10 to 13 until it has recorded 8 beats
  byte pass_lenght = 8;
  byte i = 0;
  while(i<pass_lenght){
    //get a 1 to the password
    if (digitalRead(9)){

      digit[i] = digitalRead(9)*1;
      char aux = digit[i]*1;
      //print
      printf("%i\n",aux);
      i++;
      delay(500);
    }
    //get a 2 to the password
    if ( digitalRead(11) ){

      digit[i] = digitalRead(11)*2;
      printf("%i\n",digit[i]);
      i++;
      delay(500);
    }
    //get a 3 to the password
    if ( digitalRead(12)){

      digit[i] = digitalRead(12)*3;
      printf("%i\n",digit[i]);
      i++;
      delay(500);
    }
    //get a 4 to the password
    if ( digitalRead(13)){

      digit[i] = digitalRead(13)*4;
      printf("%i\n",digit[i]);
      i++;
      delay(500);
    }
  }
  //Serial.println();
  /////////////////////////////////////////////////////////////
  //Stores data from buttons in "keyA" so the password is located
  //into the first 4 bytes
  for (byte i = 1; i <= 4; i++){
    temp = digit[(i*2)-2]<<4;
    keyA[i-1] = temp;
    Serial.print(temp>>4,HEX);
    temp = digit[(i*2)-1];
    keyA[i-1] |= temp;
    Serial.print(temp,HEX);
    printf(" ");
  }
  printf("Ready to save the new key...\n");
  delay(100);
  printf("\r\n++++++++++++++++++++++++++++++++++++");
  // **** init the RFID/NFC reader
  state = init(_CardID, aux);
  if (aux[0] == aux[1]) {// if so, there is no card on the EM field
    printf("\r\nRequest error - no card found\n");
  } 
  else { // a card was found

    printf("\r\nRequest | Answer: \n");
    print(aux, 2);  //show the ATQ

    printf("\r\nAnticollSelect: \n");
    Serial.print(state, HEX);//show the status of the executed init command(should be 0)
    printf(" | Answer: \n");
    print(_CardID, 4); //show the UID (Unique IDentifier) of the read card (4 bytes)

    //Write new key in block then authenticate this address and get the new value
    state = setKeys(_CardID, keyOld, keyA, keyB, config, aux, key_address);
    printf("\r\n**write new key, state: \n");
    Serial.print(state, HEX);

    if (state == 0) {
      printf(" --> correct key change \n");
      for (byte i=0; i<8;i++){

        keyOld[i] = keyA[i];

      }
    } 
    else {
      printf(" --> ** ERROR: keys not changed ** \n");
    }	 // ###### check block 3/7/11/15 (the keys will return 0s)
    // **** authenticate again, now with the new key A

    state = authenticate(_CardID, key_address , keyA);
    printf("\r\n**Authentication block: \n");
    Serial.print(state, HEX);

    if (state == 0) {
      printf(" --> correct authentication \n");
    }
    else {
      printf(" --> ** ERROR: bad authentication ** \n");
    }

  }
  printf(" \n");
  printf("To set a new password push '1'\n");
  printf("To enter a password push '2'\n");
  printf("To read data push '3'\n");
  //Serial.println();
}

//**********************************************************************
//This function stores in "keyOld[]" the password used to access the card
//both to read or set a new key
void saveOldPass()
{

  printf("Enter the password: \n");
  delay(500);
  /////////////////////////////////////////////////////////////
  //Read digital pins from 10 to 13 until it has recorded 8 beats
  byte pass_lenght = 8;
  byte i = 0;
  //keep reading buttons until get the 8 digit password
  while(i<pass_lenght){

    //get a 1 to the password
    if (digitalRead(9)){

      digit[i] = digitalRead(9)*1;
      printf("%i\n",digit[i]);
      i++;
      delay(500);
    }
    //get a 2 to the password
    if ( digitalRead(11) ){

      digit[i] = digitalRead(11)*2;
      printf("%i\n",digit[i]);
      i++;
      delay(500);
    }
    //get a 3 to the password
    if ( digitalRead(12)){

      digit[i] = digitalRead(12)*3;
      printf("%i\n",digit[i]);
      i++;
      delay(500);
    }
    //get a 4 to the password
    if ( digitalRead(13)){
        
      digit[i] = digitalRead(13)*4;
      printf("%i\n",digit[i]);  
      i++;
      delay(500);
    }
  }
  //Serial.println();
  /////////////////////////////////////////////////////////////
  //Stores data from buttons in "keyOld" so the password is located
  //into the first 4 bytes
  for (byte i = 1; i <= 4; i++){
    temp = digit[(i*2)-2]<<4;
    keyOld[i-1] = temp;
    Serial.print(temp>>4,HEX);
    temp = digit[(i*2)-1];
    keyOld[i-1] |= temp;
    Serial.print(temp,HEX);
    printf(" \n");
  }
  printf("To set a new password push '1'\n");
  printf("To enter a password push '2'\n");
  printf("To read data push '3'\n");
  //Serial.println();
}

//**********************************************************************
//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, read_adress, keyOld);
  printf("\n");

  if (state == 0) {
    printf("Authentication block OK\n");
    state = readData(read_adress, aux);
    printf("\n");
    
    for (int i=0; i<=15; i++){
      printf("\n");
      printf("Data read:%x\n",aux [i]);
    /*print(aux , 16);
    printf("\n");*/
    }
  } 
  else {
    printf("Authentication failed\n");
  }
  /////////////////////////////////////////////////////////////
  //Read from address after authentication

  if (state == 0) {
    printf("\nRead block OK\n");
  } 
  else {
    printf("Read failed\n");
  }
  
  printf(" \n");
  printf("To set a new password push '1'\n");
  printf("To enter a password push '2'\n");
  printf("To read data push '3'\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
 */

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 or password:
//password digits go from 1 to 4 and they are stored in the first 8 nibbles as hex {0xXX,0xXX,0xXX,0xXX,0xFF,0xFF}
unsigned char keyOld[]= {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};// Old key access(use the last one stored)
unsigned char keyA[]= {
  0x43, 0x34, 0x34, 0x43, 0xFF, 0xFF};//NEW KEY ACCESS
unsigned char keyB[]= {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};//Secundary KEY ACCESS
unsigned char digit[8];//stores digits read from the buttons
unsigned char temp;
//only edit config if strong knowledge about the RFID/NFC module
unsigned char config[] = {
  0xFF, 0x07, 0x80, 0x69};
uint8_t key_address = 7;
uint8_t read_adress = 4;

void setup()
{
  // start serial port 115200 bps:
  Serial.begin(115200);
  Serial1.begin(115200);
  Serial.print("RFID/NFC @ 13.56 MHz module started");
  delay(1000);
  //! It is needed to launch a simple command to sycnchronize
  getFirmware();
  configureSAM();
  delay(1000); 
  Serial.println("Welcome");
  Serial.println("To set a new password push '1'");
  Serial.println("To enter a password push '2'");
  Serial.println("To read data push '3'");
  Serial1.flush();
  pinMode(10,INPUT);
  pinMode(11,INPUT);
  pinMode(12,INPUT);

}

void loop()
{


  if (digitalRead(10)){

    saveNewPass();//when buttoon 1 pushed starts the keyA writting

  }
  if (digitalRead(11)){

    saveOldPass();//stores the keyA to read the tag

  }
  if (digitalRead(12)){

    printData();//reads data from tag and prints it throgh serial

  }
} 


//**********************************************************************
//!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) {
    val = Serial1.read();
    delay(5);
    cont ++;  
    if (cont>=1000){
      val = 0;
    }
  }
}
//**********************************************************************
//!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]);
}
//**********************************************************************
//Changes both keys and access conditions to one card sector
uint8_t setKeys(uint8_t *CardID,uint8_t *keyOld,uint8_t *keyA,uint8_t *keyB,uint8_t *config,uint8_t *data,uint8_t add)
{
  uint8_t state = 1; 

  if (((add+1) % 4) == 0){
    state = authenticate(CardID , add, keyOld);
    if (state == 0) {
      for (int i = 0; i < 6; i++) {
        data[i] = keyA[i];
        data[i+ 10] = keyB[i];
      }

      for (int i = 0; i < 4 ; i++) {
        data[i + 6] = config[i];
      }
      state = writeData(add, data);
    }
  }
  return state;
}
//**********************************************************************
//This function stores in "keyA[]" the new password and sets it into the tag
void saveNewPass()
{

  Serial.print("Enter the new password: ");
  delay(300);
  /////////////////////////////////////////////////////////////
  //Read digital pins from 10 to 13 until it has recorded 8 beats
  byte pass_lenght = 8;
  byte i = 0;
  while(i<pass_lenght){
    //get a 1 to the password
    if (digitalRead(10)){

      digit[i] = digitalRead(10)*1;
      Serial.print(digit[i]*1);
      i++;
      delay(500);
    }
    //get a 2 to the password
    if ( digitalRead(11) ){

      digit[i] = digitalRead(11)*2;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
    //get a 3 to the password
    if ( digitalRead(12)){

      digit[i] = digitalRead(12)*3;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
    //get a 4 to the password
    if ( digitalRead(13)){

      digit[i] = digitalRead(13)*4;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
  }
  Serial.println();
  /////////////////////////////////////////////////////////////
  //Stores data from buttons in "keyA" so the password is located
  //into the first 4 bytes
  for (byte i = 1; i <= 4; i++){
    temp = digit[(i*2)-2]<<4;
    keyA[i-1] = temp;
    Serial.print(temp>>4,HEX);
    temp = digit[(i*2)-1];
    keyA[i-1] |= temp;
    Serial.print(temp,HEX);
    Serial.print(" ");
  }
  delay(100);
  Serial.print("\r\n++++++++++++++++++++++++++++++++++++");
  // **** init the RFID/NFC reader
  state = init(_CardID, aux);
  if (aux[0] == aux[1]) {// if so, there is no card on the EM field
    Serial.print("\r\nRequest error - no card found");
  } 
  else { // a card was found

    Serial.print("\r\nRequest | Answer: ");
    print(aux, 2);  //show the ATQ

    Serial.print("\r\nAnticollSelect: ");
    Serial.print(state, HEX);//show the status of the executed init command(should be 0)
    Serial.print(" | Answer: ");
    print(_CardID, 4); //show the UID (Unique IDentifier) of the read card (4 bytes)

    //Write new key in block then authenticate this address and get the new value
    state = setKeys(_CardID, keyOld, keyA, keyB, config, aux, key_address);
    Serial.print("\r\n**write new key, state: ");
    Serial.print(state, HEX);

    if (state == 0) {
      Serial.print(" --> correct key change ");
      for (byte i=0; i<8;i++){

        keyOld[i] = keyA[i];

      }
    } 
    else {
      Serial.print(" --> ** ERROR: keys not changed ** ");
    }	 // ###### check block 3/7/11/15 (the keys will return 0s)
    // **** authenticate again, now with the new key A

    state = authenticate(_CardID, key_address , keyA);
    Serial.print("\r\n**Authentication block: ");
    Serial.print(state, HEX);

    if (state == 0) {
      Serial.print(" --> correct authentication ");
    }
    else {
      Serial.print(" --> ** ERROR: bad authentication ** ");
    }

  }
  Serial1.println();
}

//**********************************************************************
//This function stores in "keyOld[]" the password used to access the card
//both to read or set a new key
void saveOldPass()
{

  Serial.print("Enter the password: ");
  delay(500);
  /////////////////////////////////////////////////////////////
  //Read digital pins from 10 to 13 until it has recorded 8 beats
  byte pass_lenght = 8;
  byte i = 0;
  //keep reading buttons until get the 8 digit password
  while(i<pass_lenght){

    //get a 1 to the password
    if (digitalRead(10)){

      digit[i] = digitalRead(10)*1;
      Serial.print(digit[i]*1);
      i++;
      delay(500);
    }
    //get a 2 to the password
    if ( digitalRead(11) ){

      digit[i] = digitalRead(11)*2;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
    //get a 3 to the password
    if ( digitalRead(12)){

      digit[i] = digitalRead(12)*3;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
    //get a 4 to the password
    if ( digitalRead(13)){

      digit[i] = digitalRead(13)*4;
      Serial.print(digit[i]);
      i++;
      delay(500);
    }
  }
  Serial1.println();
  /////////////////////////////////////////////////////////////
  //Stores data from buttons in "keyOld" so the password is located
  //into the first 4 bytes
  for (byte i = 1; i <= 4; i++){
    temp = digit[(i*2)-2]<<4;
    keyOld[i-1] = temp;
    Serial.print(temp>>4,HEX);
    temp = digit[(i*2)-1];
    keyOld[i-1] |= temp;
    Serial.print(temp,HEX);
    Serial.print(" ");
  }
  Serial.println();
}

//**********************************************************************
//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, read_adress, keyOld);
  Serial.print("\n");

  if ( state == 0) {
    Serial.println("Authentication block OK");
  } 
  else {
    Serial.println("Authentication failed");
  }
  /////////////////////////////////////////////////////////////
  //Read from address after authentication
  state = readData(read_adress, 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");
}

	
		

Links and Documentation

Related Tutorials



If you are interested in Internet of Things (IoT) or M2M projects check our open source sensor platform Waspmote which counts with more than 100 sensors available to use 'off the shelf', a complete API with hundreds of ready to use codes and a low consumption mode of just 0.7µA to ensure years of battery life.

Know more at:

Get the Starter Kits at: