My Cart

How to Store and Read Data on RFID Tags Using Smart Cards Kit (RFID 125KHz)

Difficulty Level: Intermediate -

1. Introduction

This tutorial allows the user to store the measure taken from the LDR in the RFID cards. When 8 measures has been taken, the RFID module will read them and they will be shown on the LCD.

Ingredients:

    - 1 x Smart Cards Kit (RFID 125KHz):
    • 1x Platform
    • 1x RFID 125KHz
    • 1x GPRS antenna
    • 1x LDR
    • 1x 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 LDR with the resistor, 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 the LDR to GND and the other LDR leg to a resistor, connect also this point to Analog 0 in the Xbee Shield. The other resistor leg has to be connected to 5 volt.

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);


//Global variables
byte lecture[8];
byte card = -1;
byte counter = 0;
byte meassures[8];


void setup() {

  lcd.begin(16, 2);
  lcd.print("SM125 125khz");
  lcd.setCursor(0, 2);
  lcd.print("RFID Start");
  delay(2000);
  Serial.begin(19200);
  setParam();
  delay(200);
  Serial.flush();
  lcd.clear();
  lcd.print("Waiting card...");
  setAutoMode();//keeps shield reading to detect whenever a card waves close to the antenna
  delay(1000);
  //flush serial manually
  while (Serial.available() > 0) {
    Serial.read();
  }
  //initialize meassures
  for (byte i = 0; i < 8 ; i++) {
    meassures[i] = 0;
  }
}

void loop() {
  //wait for cards 8 times to save data read from A0
  while (counter < 8) {
    while (Serial.available()) {
      meassures[counter] = analogRead(0) * 5 / 1024.0;
      meassures[counter] = meassures[counter] - 0.5;
      meassures[counter] = meassures[counter] / 0.01;
      if (findCard(counter)) {

        lcd.clear();
        lcd.print("Card written!");
        counter++;
        delay(1000);
        lcd.clear();
        lcd.print("Waiting card...");

      }
    }
  }
  //sets automode to wait for card to read it
  setAutoMode();
  while (Serial.available()) {
    if (Serial.read() == 0x01) {//fixed header value
      Serial.read();
      if (Serial.read() == 0x10) {
        Serial.read();//ignore config block
        Serial.read();
        Serial.read();
        Serial.read();
        lcd.clear();
        lcd.print("Data recorded");
        lcd.setCursor(0, 2);
        for (byte i = 0; i < 8; i++) {
          lcd.print(Serial.read(), HEX);
          delay(10);
        }

      }
    }
  }
}

// ***This cards do not have UID, we will save different data in their block2
// so we can identify them***
boolean findCard(byte times) {

  if (Serial.read() == 0x01) { //fixed header value
    lcd.clear();
    lcd.print("Card found");
    lcd.setCursor(0, 2);
    delay(1000);
    lcd.clear();
    lcd.print(" Place the card");
    lcd.setCursor(0, 2);
    lcd.print("over the antenna");
    delay(1500);
    byte len = Serial.read();//message lenght
    delay(10);
    for (byte j = 0; j < 5; j++) {//ignore cmd and config block
      Serial.read();
      delay(10);
    }
    for (byte j = 0; j < 8; j++) {
      lecture [j] = Serial.read();//blocks 2 and 3 will be our storage
      delay(10);
    }
    //discard other data
    delay(500);
    while (Serial.available() > 0) {
      Serial.read();
    }
    boolean done = false;
    while (!done) {
      lcd.clear();
      lcd.print("Checking");
      lcd.setCursor(0, 2);
      lcd.print("writting");
      //write both blocks
      sendCmdWrite(0x02, meassures[0], meassures[1], meassures[2], meassures[3]);
      delay(600);
      sendCmdWrite(0x03, meassures[4], meassures[5], meassures[6], meassures[7]);
      delay(600);
      //read blocks written
      sendReadCommand(0x01, 0x03);
      byte* dataRead = dataResponse();
      //Check response to locate the second block content
      byte count = 0;
      boolean go_on = true;
      while (go_on) {

        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 (counter > 100) {
          sendReadCommand(0x01, 0x02);
          dataRead = dataResponse();
          count = 0;
        }
      }
      for (int i = count + 4; i < count + (4 * 3); i++) {
        lecture [i - (count + 4)] = dataRead[i];
        lcd.clear();
        lcd.print("Checking");
      }
      //compare data from meassures with data read for matches
      
        if (meassures[times] == lecture[times]) {
          done = true;
        } else done = false;

      //if data does not match it will try to write card again
    }
    lcd.clear();
    lcd.print("Done!");
    delay(1000);
    while (Serial.available() > 0) {
      Serial.read();
    }
    return true;


  }
  return false;
}


byte setParam () {
  //Calculate checksum of all bytes except header
  byte msglength = 0x06;
  byte checksum = 0x01 + msglength + 0x40 + 0x32 + 0x64 + 0x5A + 0x1E + 0x60;

  //Build and execute command
  byte paramcommand[10] = {0xFF, 0x01, msglength, 0x40, 0x32, 0x64, 0x5A, 0x1E, 0x60, checksum};

  // send the request bytes
  for (byte i = 0; i < 10; i++) {
    Serial.write(paramcommand[i]);
  }
  //flush buffer *critical*
  while (Serial.available() > 0) {
    Serial.read();
  }
  //give some time to module to do its stuff
  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 setAutoMode () {
  //Calculate checksum of all bytes except header
  byte msglength = 0x09;
  byte checksum = 0x01 + msglength + 0x87 + 0x01 + 0x01 + 0x03;

  //Build and execute command
  byte cmdToExecute[13] = {0xFF, 0x01, msglength, 0x87, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, checksum};

  // send the request bytes
  for (int m = 0; m < 13; m++) {
    Serial.write(cmdToExecute[m]);
  }
  //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;
}

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;
}

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;
}
        

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"

//Global variables
byte lecture[8];
byte card = -1;
byte counter = 0;
byte meassures[8];

boolean findCard(byte times);
byte setParam ();
byte setAutoMode ();
byte sendCmdWrite (byte block, byte byte1, byte byte2, byte byte3, byte byte4);
byte sendReadCommand (byte mode, byte blocks);
byte* dataResponse();

void setup() {

  pinMode(0, INPUT);

  printf("SM125 125khz\n");
  printf("RFID Start\n");
  delay(2000);
  Serial.begin(19200);
  setParam();
  delay(200);
  Serial.flush();
  printf("Waiting card...\n");
  setAutoMode(); //keeps shield reading to detect whenever a card waves close to the antenna
  delay(1000);
  //flush serial manually
  while (Serial.available() > 0) {
    Serial.read();
  }
  //initialize meassures
  for (byte i = 0; i < 8 ; i++) {
    meassures[i] = 0;
  }
}

void loop() {
  //wait for cards 8 times to save data read from A0
  while (counter < 8) {
    while (Serial.available()) {
     meassures[counter] = analogRead(0)>>2;
      if (findCard(counter)) {

        printf("Card written!\n");
        counter++;
        delay(1000);
        printf("Waiting card...\n");

      }
    }
  }
  //sets automode to wait for card to read it
  setAutoMode();
  while (Serial.available()) {
    if (Serial.read() == 0x01) {//fixed header value
      Serial.read();
      if (Serial.read() == 0x10) {
        Serial.read();//ignore config block
        Serial.read();
        Serial.read();
        Serial.read();
        printf("Data recorded\n");
        for (byte i = 0; i < 8; i++) {
          printf("%i\n",Serial.read());
          delay(10);
        }

      }
    }
  }
}

// ***This cards do not have UID, we will save different data in their block2
// so we can identify them***
boolean findCard(byte times) {

  if (Serial.read() == 0x01) { //fixed header value
    printf("Card found\n");
    delay(1000);
    printf(" Place the card over the antenna\n");
    delay(1500);
    byte len = Serial.read(); //message lenght
    delay(10);
    for (byte j = 0; j < 5; j++) {//ignore cmd and config block
      Serial.read();
      delay(10);
    }
    for (byte j = 0; j < 8; j++) {
      lecture [j] = Serial.read();//blocks 2 and 3 will be our storage
      delay(10);
    }
    //discard other data
    delay(500);
    while (Serial.available() > 0) {
      Serial.read();
    }
    boolean done = false;
    while (!done) {
      printf("Checking\n");
      printf("writting\n");
      //write both blocks
      sendCmdWrite(0x02, meassures[0], meassures[1], meassures[2], meassures[3]);
      delay(600);
      sendCmdWrite(0x03, meassures[4], meassures[5], meassures[6], meassures[7]);
      delay(600);
      //read blocks written
      sendReadCommand(0x01, 0x03);
      byte* dataRead = dataResponse();
      //Check response to locate the second block content
      byte count = 0;
      boolean go_on = true;
      while (go_on) {

		
        if (dataRead[count] == 0x52) {
          if (dataRead[count + 1] == 0x58) {
            if (dataRead[count + 2] == 0x8B) {
              if (dataRead[count + 3] == 0x45) {
                printf("while\n");
                go_on = false;
              } else count++;
            } else count++;
          } else count++;
        } else count++;
        if (counter > 100) {
          sendReadCommand(0x01, 0x02);
          dataRead = dataResponse();
          count = 0;
        }
      }
      for (int i = count + 4; i < count + (4 * 3); i++) {
        lecture [i - (count + 4)] = dataRead[i];
        printf("Checking\n");
      }
      //compare data from meassures with data read for matches
      
        if (meassures[times] == lecture[times]) {
          done = true;
        } else done = false;

      //if data does not match it will try to write card again
    }
    printf("Done!\n");
    delay(1000);
    while (Serial.available() > 0) {
      Serial.read();
    }
    return true;


  }
  return false;
}


byte setParam () {
  //Calculate checksum of all bytes except header
  byte msglength = 0x06;
  byte checksum = 0x01 + msglength + 0x40 + 0x32 + 0x64 + 0x5A + 0x1E + 0x60;

  //Build and execute command
  byte paramcommand[10] = {0xFF, 0x01, msglength, 0x40, 0x32, 0x64, 0x5A, 0x1E, 0x60, checksum};

  // send the request bytes
  for (byte i = 0; i < 10; i++) {
    Serial.write(paramcommand[i]);
  }
  //flush buffer *critical*
  while (Serial.available() > 0) {
    Serial.read();
  }
  //give some time to module to do its stuff
  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 setAutoMode () {
  //Calculate checksum of all bytes except header
  byte msglength = 0x09;
  byte checksum = 0x01 + msglength + 0x87 + 0x01 + 0x01 + 0x03;

  //Build and execute command
  byte cmdToExecute[13] = {0xFF, 0x01, msglength, 0x87, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, checksum};

  // send the request bytes
  for (int m = 0; m < 13; m++) {
    Serial.write(cmdToExecute[m]);
  }
  //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;
}

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;
}

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;
}

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);


//Global variables
byte lecture[8];
byte card = -1;
byte counter = 0;
byte meassures[8];


void setup() {

  lcd.begin(16, 2);
  lcd.print("SM125 125khz");
  lcd.setCursor(0, 2);
  lcd.print("RFID Start");
  delay(2000);
  Serial.begin(19200);
  Serial1.begin(19200);
  setParam();
  delay(200);
  Serial1.flush();
  lcd.clear();
  lcd.print("Waiting card...");
  setAutoMode();//keeps shield reading to detect whenever a card waves close to the antenna
  delay(1000);
  //flush serial manually
  while (Serial1.available() > 0) {
    Serial1.read();
  }
  //initialize meassures
  for (byte i = 0; i < 8 ; i++) {
    meassures[i] = 0;
  }
}

void loop() {
  //wait for cards 8 times to save data read from A0
  while (counter < 8) {
    while (Serial1.available()) {
      meassures[counter] = analogRead(0)>>2;
      if (findCard(counter)) {

        lcd.clear();
        lcd.print("Card written!");
        counter++;
        delay(1000);
        lcd.clear();
        lcd.print("Waiting card...");

      }
    }
  }
  //sets automode to wait for card to read it
  setAutoMode();
  while (Serial1.available()) {
    if (Serial1.read() == 0x01) {//fixed header value
      Serial1.read();
      if (Serial1.read() == 0x10) {
        Serial1.read();//ignore config block
        Serial1.read();
        Serial1.read();
        Serial1.read();
        lcd.clear();
        lcd.print("Data recorded");
        lcd.setCursor(0, 2);
        for (byte i = 0; i < 8; i++) {
          lcd.print(Serial1.read(), HEX);
          delay(10);
        }

      }
    }
  }
}

// ***This cards do not have UID, we will save different data in their block2
// so we can identify them***
boolean findCard(byte times) {

  if (Serial1.read() == 0x01) { //fixed header value
    lcd.clear();
    lcd.print("Card found");
    lcd.setCursor(0, 2);
    delay(1000);
    lcd.clear();
    lcd.print(" Place the card");
    lcd.setCursor(0, 2);
    lcd.print("over the antenna");
    delay(1500);
    byte len = Serial1.read();//message lenght
    delay(10);
    for (byte j = 0; j < 5; j++) {//ignore cmd and config block
      Serial1.read();
      delay(10);
    }
    for (byte j = 0; j < 8; j++) {
      lecture [j] = Serial1.read();//blocks 2 and 3 will be our storage
      delay(10);
    }
    //discard other data
    delay(500);
    while (Serial1.available() > 0) {
      Serial1.read();
    }
    boolean done = false;
    while (!done) {
      lcd.clear();
      lcd.print("Checking");
      lcd.setCursor(0, 2);
      lcd.print("writting");
      //write both blocks
      sendCmdWrite(0x02, meassures[0], meassures[1], meassures[2], meassures[3]);
      delay(600);
      sendCmdWrite(0x03, meassures[4], meassures[5], meassures[6], meassures[7]);
      delay(600);
      //read blocks written
      sendReadCommand(0x01, 0x03);
      byte* dataRead = dataResponse();
      //Check response to locate the second block content
      byte count = 0;
      boolean go_on = true;
      while (go_on) {

        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 (counter > 100) {
          sendReadCommand(0x01, 0x02);
          dataRead = dataResponse();
          count = 0;
        }
      }
      for (int i = count + 4; i < count + (4 * 3); i++) {
        lecture [i - (count + 4)] = dataRead[i];
        lcd.clear();
        lcd.print("Checking");
      }
      //compare data from meassures with data read for matches
      
        if (meassures[times] == lecture[times]) {
          done = true;
        } else done = false;

      //if data does not match it will try to write card again
    }
    lcd.clear();
    lcd.print("Done!");
    delay(1000);
    while (Serial1.available() > 0) {
      Serial1.read();
    }
    return true;


  }
  return false;
}


byte setParam () {
  //Calculate checksum of all bytes except header
  byte msglength = 0x06;
  byte checksum = 0x01 + msglength + 0x40 + 0x32 + 0x64 + 0x5A + 0x1E + 0x60;

  //Build and execute command
  byte paramcommand[10] = {0xFF, 0x01, msglength, 0x40, 0x32, 0x64, 0x5A, 0x1E, 0x60, checksum};

  // send the request bytes
  for (byte i = 0; i < 10; i++) {
    Serial1.write(paramcommand[i]);
  }
  //flush buffer *critical*
  while (Serial1.available() > 0) {
    Serial1.read();
  }
  //give some time to module to do its stuff
  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 setAutoMode () {
  //Calculate checksum of all bytes except header
  byte msglength = 0x09;
  byte checksum = 0x01 + msglength + 0x87 + 0x01 + 0x01 + 0x03;

  //Build and execute command
  byte cmdToExecute[13] = {0xFF, 0x01, msglength, 0x87, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, checksum};

  // send the request bytes
  for (int m = 0; m < 13; m++) {
    Serial1.write(cmdToExecute[m]);
  }
  //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;
}

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;
}

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;
}
		

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: