My Cart

How to Change Keys on RFID Tags Using Smart Cards Kit (RFID 125KHz)

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 3 buttons), save new key and read card.

Ingredients:

    - 1 x Smart Cards Kit (RFID 125KHz):
    • 1x Platform
    • 1x RFID 125KHz
    • 1x GPRS antenna
    • 3x Buttons
    • 3x 220Ω resistors
    • 1x LCD
    • 1x Potentiometer
    • 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 125kHz 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, 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. Finally connect 3 buttons to pin 8, 9 and 10 with a resistor to GND in each button. Connect the buttons to 5 volt with another wire to power them.

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 125kHz 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 <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


//Integer to hold commands received from serial monitor
int received = 0;
unsigned char digit[8];//stores digits read from the buttons
byte lecture[8];
//stores bytes to write in card
byte password[4];

void setup() {
  //Start serial
  lcd.begin(16, 2);
  lcd.print("SM125 125khz");
  lcd.setCursor(0, 2);
  lcd.print("RFID Start");
  Serial.begin(19200);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
}

void loop() {

  //Save a new password to write in the card
  if (digitalRead(8)) {
    lcd.clear();
    lcd.print("Enter password");
    lcd.setCursor(0, 2);
    delay(500);
    /////////////////////////////////////////////////////////////
    //Read digital pins from 8 to 10 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(8)) {

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

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

        digit[i] = digitalRead(10) * 3;
        lcd.print(digit[i]);
        i++;
        delay(500);
      }

    }
    delay(1000);
    lcd.clear();
    lcd.print("SM125 125khz");
    lcd.setCursor(0, 2);
    lcd.print("RFID Start");
  }

  //Read second block that will be our password
  if (digitalRead(9)) {

    lcd.clear();
    lcd.print("Read T5557");
    lcd.setCursor(0, 2);
    lcd.print("Password");
    delay(500);
    //0x01 = Byte Track Mode – Manchester RF/64
    //0x02 = Read Blocks 1-2
    sendReadCommand(0x01, 0x02);
    delay(1000);
    //read the card data, returned as a byte array
    byte* dataRead = dataResponse();
    //Check response to locate the second block content
    byte counter = 0;
    boolean go_on = true;
    while (go_on) {

      if (dataRead[counter] == 0x52) {
        if (dataRead[counter + 1] == 0x58) {
          if (dataRead[counter + 2] == 0x8B) {
            if (dataRead[counter + 3] == 0x45) {
              go_on = false;
            } else counter++;
          } else counter++;
        } else counter++;
      } else counter++;
      if (counter > 100) {
        sendReadCommand(0x01, 0x02);
        dataRead = dataResponse();
        counter = 0;
      }
    }
    lcd.clear();
    //Print second block data "Password"
    for (byte i = counter + 4; i < counter + (4 * 2); i++) {
      lcd.print(dataRead[i], HEX);
    }
    //stop reading
    delay(1000);
    stopRead();
    lcd.clear();
    lcd.print("SM125 125khz");
    lcd.setCursor(0, 2);
    lcd.print("RFID Start");

  }

  //Write second block that will be our password with digit[]
  if (digitalRead(10)) {
    lcd.clear();
    lcd.print("Write T5557");
    lcd.setCursor(0, 2);
    lcd.print("Password");
    writeCard();
    delay(1000);
    lcd.clear();
    lcd.print("SM125 125khz");
    lcd.setCursor(0, 2);
    lcd.print("RFID Start");
  }

  Serial.flush();

}


void writeCard() {

  boolean done = false;
  while (!done) {
    lcd.clear();
    lcd.print("Checking");
    lcd.setCursor(0, 2);
    lcd.print("writting");
    sendCmdWrite(0x02, (digit[0] << 4) | digit[1], (digit[2] << 4) | digit[3], (digit[4] << 4) | digit[5], (digit[6] << 4) | digit[7]);//write card
    delay(600);
    sendReadCommand(0x01, 0x02);
    byte* dataRead = dataResponse();//get data read
    byte count = 0;
    boolean go_on = true;
    //get second block position within T55x7Response
    while (go_on) {
      delay(50);
      if (dataRead[count] == 0x52) {
        if (dataRead[count + 1] == 0x58) {
          if (dataRead[count + 2] == 0x8B) {
            if (dataRead[count + 3] == 0x45) {
              go_on = false;
            } else count++;
          } else count++;
        } else count++;
      } else count++;
      if (count > 100) {
        sendReadCommand(0x01, 0x02);
        dataRead = dataResponse();
        count = 0;
      }
    }
    for (byte i = count + 4; i < count + (4 * 2); i++) {
      lecture [(i - (count + 4)) * 2] = dataRead[i] >> 4;
      lecture [(i - (count + 4)) * 2 + 1] = dataRead[i] & 0x0F;
      lcd.clear();
      lcd.print("Checking");
    }
    lcd.clear();
    //check if block read matches with password wrote
    for (byte j = 0; j < 8; j++) {
      if (lecture[j] == digit[j]) {
        done = true;
      } else done = false;

    }
  }
  lcd.clear();
  lcd.print("Done!");
  delay(1000);
  //flush serial port manually
  while (Serial.available() > 0) {
    Serial.read();
  }

}

byte sendReadCommand (byte mode, byte blocks) {

  //lenght of message (read command(0x10), mode and blocks)
  byte msglenght = 0x03;
  //Calculate checksum of all bytes except header
  byte checksum = 0x01 + msglenght + 0x10 + mode + blocks;

  //Build and execute command
  byte command[7] = {0xFF, 0x01, msglenght, 0x10, mode, blocks, checksum};
  Serial.flush();
  // send the request bytes
  for (byte i = 0; i < 7; i++) {
    Serial.write(command[i]);
    delay(1);
  }
  //flush buffer *critical*
  while (Serial.available() > 0) {
    Serial.read();
  }
  //give some time to module to do its stuff     
  delay(500);

  //moduile will return (FF,01,99,9B) if everything went ok
  //verify successful completion of command
  if (Serial.read() == 0xFF) {
    if (Serial.read() == 0x01) {
      if (Serial.read() == 0x01) {
        if (Serial.read() == 0x99) {
          if (Serial.read() == 0x9B) {
            return 0;
          }
          else return 1;
        }
        else return 1;
      }
      else return 1;
    }
    else return 1;
  }
  else return 1;
}

byte* dataResponse() {
  //due to sm125 datasheet response structure is:
  //FF 01 XX 10 52 58 8B 45 blocks 98
  //4byte (header,reserved,length(XX),cmd), 4 byte fist blobk(config), blocks read + checksum
  //Create null byte array to return if command exits abnormally or no data is received
  static byte nullReturn[1] = {0x00};

  //Get reponse data from SM125
  if (Serial.available()) {
    byte header = Serial.read();
    byte reserved = Serial.read();
    byte msglength = Serial.read();

    //Convert hex length to integer for use in for loop and byte array definition
    int intlength = (int)msglength;

    //Create byte array, size = payload length + header(3) +  first byte length(1)
    int size = intlength + 4;
    static byte response[256];
    for (byte i = 0; i < sizeof(response) - 1; i++) {

      response[i] = 0;

    }

    //drop in existing data
    response[0] = msglength + 0x04;
    response[1] = reserved;
    response[2] = reserved;
    response[3] = msglength;
    response[4] = Serial.read(); //response command

    //Get SM125 response payload
    for (int i = 0; i < intlength - 1; i++) {          //response is length - 1 because the command is included
      response[i + 5] = Serial.read();
      delay(10);
    }

    //Add in the checksum
    response[intlength + 4] = Serial.read();

    //Return received data
    return response;
  }
  return nullReturn;
}

byte stopRead() {
  // send the request bytes
  byte stopread[] = {0xFF, 0x01, 0x01, 0x12, 0x14};
  for (byte i = 0; i < 5; i++) {
    Serial.write(stopread[i]);
  }

  //flush the RFID Serial port
  while (Serial.available() > 0) {
    Serial.read();
  }
  delay(500);
  //verify successful completion of command
  if (Serial.read() == 0xFF) {
    if (Serial.read() == 0x01) {
      if (Serial.read() == 0x01) {
        if (Serial.read() == 0x99) {
          if (Serial.read() == 0x9B) {
            return 0;
          }
          else return 1;
        }
        else return 1;
      }
      else return 1;
    }
    else return 1;
  }
  else return 1;
}

byte sendCmdWrite (byte block, byte byte1, byte byte2, byte byte3, byte byte4) {
  //Calculate checksum of all bytes except header
  byte msglenght = 0x06;
  byte checksum = 0x01 + msglenght + 0x20 + block + byte1 + byte2 + byte3 + byte4;

  //Build and execute command
  byte cmdToExecute[10] = {0xFF, 0x01, msglenght, 0x20, block, byte1, byte2, byte3, byte4, checksum};
  delay(2000);
  // send the request bytes
  for (byte i = 0; i < 10; i++) {
    Serial.write(cmdToExecute[i]);
    delay(2);
  }
  //flush buffer *critical*
  while (Serial.available() > 0) {
    Serial.read();
  }

  delay(500);

  //verify successful completion of command
  if (Serial.read() == 0xFF) {
    if (Serial.read() == 0x01) {
      if (Serial.read() == 0x01) {
        if (Serial.read() == 0x99) {
          if (Serial.read() == 0x9B) {
            return 0;
          }
          else return 1;
        }
        else return 1;
      }
      else return 1;
    }
    else return 1;
  }
  else return 1;
}

        

Raspberry Pi:

Code:
/*  
 *  RFID 125kHz 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"

//Integer to hold commands received from serial monitor
int received = 0;
unsigned char digit[8];//stores digits read from the buttons
byte lecture[8];
//stores bytes to write in card
byte password[4];

void writeCard();
byte sendReadCommand (byte mode, byte blocks);
byte* dataResponse();
byte stopRead();
byte sendCmdWrite (byte block, byte byte1, byte byte2, byte byte3, byte byte4);

void setup() {
  //Start serial
  printf("SM125 125khz\n");
  printf("RFID Start\n");
  Serial.begin(19200);
  pinMode(8,INPUT);
  pinMode(9,INPUT);
  pinMode(10,INPUT);
}

void loop() {

  //Save a new password to write in the card
  if (digitalRead(8)) {
    printf("Enter password\n");
    delay(500);
    /////////////////////////////////////////////////////////////
    //Read digital pins from 8 to 10 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(8)) {

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

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

        digit[i] = digitalRead(10) * 3;
        printf("%i\n",digit[i]);
        i++;
        delay(500);
      }

    }
    delay(1000);
    printf("SM125 125khz\n");
    printf("RFID Start\n");
  }

  //Read second block that will be our password
  if (digitalRead(9)) {

    printf("Read T5557\n");
    printf("Password\n");
    delay(500);
    //0x01 = Byte Track Mode – Manchester RF/64
    //0x02 = Read Blocks 1-2
    sendReadCommand(0x01, 0x02);
    delay(1000);
    //read the card data, returned as a byte array
    byte* dataRead = dataResponse();
    //Check response to locate the second block content
    byte counter = 0;
    boolean go_on = true;
    while (go_on) {

      if (dataRead[counter] == 0x52) {
        if (dataRead[counter + 1] == 0x58) {
          if (dataRead[counter + 2] == 0x8B) {
            if (dataRead[counter + 3] == 0x45) {
              go_on = false;
            } else counter++;
          } else counter++;
        } else counter++;
      } else counter++;
      if (counter > 100) {
        sendReadCommand(0x01, 0x02);
        dataRead = dataResponse();
        counter = 0;
      }
    }
    //Print second block data "Password"
    for (byte i = counter + 4; i < counter + (4 * 2); i++) {
      printf("%x",dataRead[i]);
    }
    //stop reading
    delay(1000);
    stopRead();
    printf(" \n\n");
    printf("SM125 125khz\n");
    printf("RFID Start\n");

  }

  //Write second block that will be our password with digit[]
  if (digitalRead(10)) {
    printf("Write T5557\n");
    printf("Password\n");
    writeCard();
    delay(1000);
    printf("SM125 125khz\n");
    printf("RFID Start\n");
  }

  Serial.flush();

}


void writeCard() {

  boolean done = false;
  while (!done) {
    printf("Checking\n");
    printf("writting\n");
    sendCmdWrite(0x02, (digit[0] << 4) | digit[1], (digit[2] << 4) | digit[3], (digit[4] << 4) | digit[5], (digit[6] << 4) | digit[7]);//write card
    delay(600);
    sendReadCommand(0x01, 0x02);
    byte* dataRead = dataResponse();//get data read
    byte count = 0;
    boolean go_on = true;
    //get second block position within T55x7Response
    while (go_on) {
      delay(50);
      if (dataRead[count] == 0x52) {
        if (dataRead[count + 1] == 0x58) {
          if (dataRead[count + 2] == 0x8B) {
            if (dataRead[count + 3] == 0x45) {
              go_on = false;
            } else count++;
          } else count++;
        } else count++;
      } else count++;
      if (count > 100) {
        sendReadCommand(0x01, 0x02);
        dataRead = dataResponse();
        count = 0;
      }
    }
    for (byte i = count + 4; i < count + (4 * 2); i++) {
      lecture [(i - (count + 4)) * 2] = dataRead[i] >> 4;
      lecture [(i - (count + 4)) * 2 + 1] = dataRead[i] & 0x0F;
      printf("Checking\n");
    }
    //check if block read matches with password wrote
    for (byte j = 0; j < 8; j++) {
      if (lecture[j] == digit[j]) {
        done = true;
      } else done = false;

    }
  }
  printf("Done!\n");
  delay(1000);
  //flush serial port manually
  while (Serial.available() > 0) {
    Serial.read();
  }

}

byte sendReadCommand (byte mode, byte blocks) {

  //lenght of message (read command(0x10), mode and blocks)
  byte msglenght = 0x03;
  //Calculate checksum of all bytes except header
  byte checksum = 0x01 + msglenght + 0x10 + mode + blocks;

  //Build and execute command
  byte command[7] = {0xFF, 0x01, msglenght, 0x10, mode, blocks, checksum};
  Serial.flush();
  // send the request bytes
  for (byte i = 0; i < 7; i++) {
    Serial.write(command[i]);
    delay(1);
  }
  //flush buffer *critical*
  while (Serial.available() > 0) {
    Serial.read();
  }
  //give some time to module to do its stuff     
  delay(500);

  //moduile will return (FF,01,99,9B) if everything went ok
  //verify successful completion of command
  if (Serial.read() == 0xFF) {
    if (Serial.read() == 0x01) {
      if (Serial.read() == 0x01) {
        if (Serial.read() == 0x99) {
          if (Serial.read() == 0x9B) {
            return 0;
          }
          else return 1;
        }
        else return 1;
      }
      else return 1;
    }
    else return 1;
  }
  else return 1;
}

byte* dataResponse() {
  //due to sm125 datasheet response structure is:
  //FF 01 XX 10 52 58 8B 45 blocks 98
  //4byte (header,reserved,length(XX),cmd), 4 byte fist blobk(config), blocks read + checksum
  //Create null byte array to return if command exits abnormally or no data is received
  static byte nullReturn[1] = {0x00};

  //Get reponse data from SM125
  if (Serial.available()) {
    byte header = Serial.read();
    byte reserved = Serial.read();
    byte msglength = Serial.read();

    //Convert hex length to integer for use in for loop and byte array definition
    int intlength = (int)msglength;

    //Create byte array, size = payload length + header(3) +  first byte length(1)
    int size = intlength + 4;
    static byte response[256];
    for (byte i = 0; i < sizeof(response) - 1; i++) {

      response[i] = 0;

    }

    //drop in existing data
    response[0] = msglength + 0x04;
    response[1] = reserved;
    response[2] = reserved;
    response[3] = msglength;
    response[4] = Serial.read(); //response command

    //Get SM125 response payload
    for (int i = 0; i < intlength - 1; i++) {          //response is length - 1 because the command is included
      response[i + 5] = Serial.read();
      delay(10);
    }

    //Add in the checksum
    response[intlength + 4] = Serial.read();

    //Return received data
    return response;
  }
  return nullReturn;
}

byte stopRead() {
  // send the request bytes
  byte stopread[] = {0xFF, 0x01, 0x01, 0x12, 0x14};
  for (byte i = 0; i < 5; i++) {
    Serial.write(stopread[i]);
  }

  //flush the RFID Serial port
  while (Serial.available() > 0) {
    Serial.read();
  }
  delay(500);
  //verify successful completion of command
  if (Serial.read() == 0xFF) {
    if (Serial.read() == 0x01) {
      if (Serial.read() == 0x01) {
        if (Serial.read() == 0x99) {
          if (Serial.read() == 0x9B) {
            return 0;
          }
          else return 1;
        }
        else return 1;
      }
      else return 1;
    }
    else return 1;
  }
  else return 1;
}

byte sendCmdWrite (byte block, byte byte1, byte byte2, byte byte3, byte byte4) {
  //Calculate checksum of all bytes except header
  byte msglenght = 0x06;
  byte checksum = 0x01 + msglenght + 0x20 + block + byte1 + byte2 + byte3 + byte4;

  //Build and execute command
  byte cmdToExecute[10] = {0xFF, 0x01, msglenght, 0x20, block, byte1, byte2, byte3, byte4, checksum};
  delay(2000);
  // send the request bytes
  for (byte i = 0; i < 10; i++) {
    Serial.write(cmdToExecute[i]);
    delay(2);
  }
  //flush buffer *critical*
  while (Serial.available() > 0) {
    Serial.read();
  }

  delay(500);

  //verify successful completion of command
  if (Serial.read() == 0xFF) {
    if (Serial.read() == 0x01) {
      if (Serial.read() == 0x01) {
        if (Serial.read() == 0x99) {
          if (Serial.read() == 0x9B) {
            return 0;
          }
          else return 1;
        }
        else return 1;
      }
      else return 1;
    }
    else return 1;
  }
  else return 1;
}

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

        

Intel Galileo:

Code:
  
/*  
 *  RFID 125kHz 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 <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


//Integer to hold commands received from serial monitor
int received = 0;
unsigned char digit[8];//stores digits read from the buttons
byte lecture[8];
//stores bytes to write in card
byte password[4];

void setup() {
  //Start serial
  lcd.begin(16, 2);
  lcd.print("SM125 125khz");
  lcd.setCursor(0, 2);
  lcd.print("RFID Start");
  Serial.begin(19200);
  Serial1.begin(19200);
  pinMode(8,INPUT);
  pinMode(9,INPUT);
  pinMode(10,INPUT);
}

void loop() {

  //Save a new password to write in the card
  if (digitalRead(8)) {
    lcd.clear();
    lcd.print("Enter password");
    lcd.setCursor(0, 2);
    delay(500);
    /////////////////////////////////////////////////////////////
    //Read digital pins from 8 to 10 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(8)) {

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

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

        digit[i] = digitalRead(10) * 3;
        lcd.print(digit[i]);
        i++;
        delay(500);
      }

    }
    delay(1000);
    lcd.clear();
    lcd.print("SM125 125khz");
    lcd.setCursor(0, 2);
    lcd.print("RFID Start");
  }

  //Read second block that will be our password
  if (digitalRead(9)) {

    lcd.clear();
    lcd.print("Read T5557");
    lcd.setCursor(0, 2);
    lcd.print("Password");
    delay(500);
    //0x01 = Byte Track Mode – Manchester RF/64
    //0x02 = Read Blocks 1-2
    sendReadCommand(0x01, 0x02);
    delay(1000);
    //read the card data, returned as a byte array
    byte* dataRead = dataResponse();
    //Check response to locate the second block content
    byte counter = 0;
    boolean go_on = true;
    while (go_on) {

      if (dataRead[counter] == 0x52) {
        if (dataRead[counter + 1] == 0x58) {
          if (dataRead[counter + 2] == 0x8B) {
            if (dataRead[counter + 3] == 0x45) {
              go_on = false;
            } else counter++;
          } else counter++;
        } else counter++;
      } else counter++;
      if (counter > 100) {
        sendReadCommand(0x01, 0x02);
        dataRead = dataResponse();
        counter = 0;
      }
    }
    lcd.clear();
    //Print second block data "Password"
    for (byte i = counter + 4; i < counter + (4 * 2); i++) {
      lcd.print(dataRead[i], HEX);
    }
    //stop reading
    delay(1000);
    stopRead();
    lcd.clear();
    lcd.print("SM125 125khz");
    lcd.setCursor(0, 2);
    lcd.print("RFID Start");

  }

  //Write second block that will be our password with digit[]
  if (digitalRead(10)) {
    lcd.clear();
    lcd.print("Write T5557");
    lcd.setCursor(0, 2);
    lcd.print("Password");
    writeCard();
    delay(1000);
    lcd.clear();
    lcd.print("SM125 125khz");
    lcd.setCursor(0, 2);
    lcd.print("RFID Start");
  }

  Serial1.flush();

}


void writeCard() {

  boolean done = false;
  while (!done) {
    lcd.clear();
    lcd.print("Checking");
    lcd.setCursor(0, 2);
    lcd.print("writting");
    sendCmdWrite(0x02, (digit[0] << 4) | digit[1], (digit[2] << 4) | digit[3], (digit[4] << 4) | digit[5], (digit[6] << 4) | digit[7]);//write card
    delay(600);
    sendReadCommand(0x01, 0x02);
    byte* dataRead = dataResponse();//get data read
    byte count = 0;
    boolean go_on = true;
    //get second block position within T55x7Response
    while (go_on) {
      delay(50);
      if (dataRead[count] == 0x52) {
        if (dataRead[count + 1] == 0x58) {
          if (dataRead[count + 2] == 0x8B) {
            if (dataRead[count + 3] == 0x45) {
              go_on = false;
            } else count++;
          } else count++;
        } else count++;
      } else count++;
      if (count > 100) {
        sendReadCommand(0x01, 0x02);
        dataRead = dataResponse();
        count = 0;
      }
    }
    for (byte i = count + 4; i < count + (4 * 2); i++) {
      lecture [(i - (count + 4)) * 2] = dataRead[i] >> 4;
      lecture [(i - (count + 4)) * 2 + 1] = dataRead[i] & 0x0F;
      lcd.clear();
      lcd.print("Checking");
    }
    lcd.clear();
    //check if block read matches with password wrote
    for (byte j = 0; j < 8; j++) {
      if (lecture[j] == digit[j]) {
        done = true;
      } else done = false;

    }
  }
  lcd.clear();
  lcd.print("Done!");
  delay(1000);
  //flush serial port manually
  while (Serial1.available() > 0) {
    Serial1.read();
  }

}

byte sendReadCommand (byte mode, byte blocks) {

  //lenght of message (read command(0x10), mode and blocks)
  byte msglenght = 0x03;
  //Calculate checksum of all bytes except header
  byte checksum = 0x01 + msglenght + 0x10 + mode + blocks;

  //Build and execute command
  byte command[7] = {0xFF, 0x01, msglenght, 0x10, mode, blocks, checksum};
  Serial1.flush();
  // send the request bytes
  for (byte i = 0; i < 7; i++) {
    Serial1.write(command[i]);
    delay(1);
  }
  //flush buffer *critical*
  while (Serial1.available() > 0) {
    Serial1.read();
  }
  //give some time to module to do its stuff     
  delay(500);

  //moduile will return (FF,01,99,9B) if everything went ok
  //verify successful completion of command
  if (Serial1.read() == 0xFF) {
    if (Serial1.read() == 0x01) {
      if (Serial1.read() == 0x01) {
        if (Serial1.read() == 0x99) {
          if (Serial1.read() == 0x9B) {
            return 0;
          }
          else return 1;
        }
        else return 1;
      }
      else return 1;
    }
    else return 1;
  }
  else return 1;
}

byte* dataResponse() {
  //due to sm125 datasheet response structure is:
  //FF 01 XX 10 52 58 8B 45 blocks 98
  //4byte (header,reserved,length(XX),cmd), 4 byte fist blobk(config), blocks read + checksum
  //Create null byte array to return if command exits abnormally or no data is received
  static byte nullReturn[1] = {0x00};

  //Get reponse data from SM125
  if (Serial1.available()) {
    byte header = Serial1.read();
    byte reserved = Serial1.read();
    byte msglength = Serial1.read();

    //Convert hex length to integer for use in for loop and byte array definition
    int intlength = (int)msglength;

    //Create byte array, size = payload length + header(3) +  first byte length(1)
    int size = intlength + 4;
    static byte response[256];
    for (byte i = 0; i < sizeof(response) - 1; i++) {

      response[i] = 0;

    }

    //drop in existing data
    response[0] = msglength + 0x04;
    response[1] = reserved;
    response[2] = reserved;
    response[3] = msglength;
    response[4] = Serial1.read(); //response command

    //Get SM125 response payload
    for (int i = 0; i < intlength - 1; i++) {          //response is length - 1 because the command is included
      response[i + 5] = Serial1.read();
      delay(10);
    }

    //Add in the checksum
    response[intlength + 4] = Serial1.read();

    //Return received data
    return response;
  }
  return nullReturn;
}

byte stopRead() {
  // send the request bytes
  byte stopread[] = {0xFF, 0x01, 0x01, 0x12, 0x14};
  for (byte i = 0; i < 5; i++) {
    Serial1.write(stopread[i]);
  }

  //flush the RFID Serial port
  while (Serial1.available() > 0) {
    Serial1.read();
  }
  delay(500);
  //verify successful completion of command
  if (Serial1.read() == 0xFF) {
    if (Serial1.read() == 0x01) {
      if (Serial1.read() == 0x01) {
        if (Serial1.read() == 0x99) {
          if (Serial1.read() == 0x9B) {
            return 0;
          }
          else return 1;
        }
        else return 1;
      }
      else return 1;
    }
    else return 1;
  }
  else return 1;
}

byte sendCmdWrite (byte block, byte byte1, byte byte2, byte byte3, byte byte4) {
  //Calculate checksum of all bytes except header
  byte msglenght = 0x06;
  byte checksum = 0x01 + msglenght + 0x20 + block + byte1 + byte2 + byte3 + byte4;

  //Build and execute command
  byte cmdToExecute[10] = {0xFF, 0x01, msglenght, 0x20, block, byte1, byte2, byte3, byte4, checksum};
  delay(2000);
  // send the request bytes
  for (byte i = 0; i < 10; i++) {
    Serial1.write(cmdToExecute[i]);
    delay(2);
  }
  //flush buffer *critical*
  while (Serial1.available() > 0) {
    Serial1.read();
  }

  delay(500);

  //verify successful completion of command
  if (Serial1.read() == 0xFF) {
    if (Serial1.read() == 0x01) {
      if (Serial1.read() == 0x01) {
        if (Serial1.read() == 0x99) {
          if (Serial1.read() == 0x9B) {
            return 0;
          }
          else return 1;
        }
        else return 1;
      }
      else return 1;
    }
    else return 1;
  }
  else return 1;
}

		

Links and Documentation

Related Tutorials

Datasheets and Manuals



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: