#include <LiquidCrystal.h> //Include LCD library LiquidCrystal lcd(8,9,4,5,6,7); //declare an object of LiquidCrystal, define pins responsible for controlling LCD char button_1 = 10; //Define pin 10 as button_1 char button_2 = 11; //Define pin 11 as button_2 /*****MiFare commands*****/ char LED_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x01,0x07}; //Command to turn on MiFare module onboard LED char LED_OFF[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x00,0x06}; //Command to turn off MiFare module onboard LED char ANTENNA_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x0C,0x01,0x01,0x0C}; //Command to turn off MiFare module onboard antenna char READ_DEV[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x03,0x01,0x02}; //Command to read MiFare module device number char CARD_REQ[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x01,0x02,0x52,0x51}; //Command to request card type of MiFare card char ANTI_COL[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x02,02,00}; //Command for anti-collision char CARD_SEL[] = {0xAA,0xBB,0x09,0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00}; //Command to select specific MiFare card for access //Byte 0 to byte 12 of this command is initialized with 0x00, since have to obtain the NUID of the MiFare card scanned //Byte 8 to byte 11 of this command will filled with NUID (started with the lowest byte) of the MiFare card desire to access //Byte 12 of this command is checksum from byte 4 to byte 11 of this command may change for NUID different from that in this case //This array will be filled during the subroutine of the get_nuid() in this program char AUTHEN_SEC0[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65}; //Command to authenticate Sector 0 in memory of MiFare card char AUTHEN_SEC1[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x61}; //Command to authenticate Sector 1 in memory of MiFare card char READ_0[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x00,0x0A}; //Command to read Block 0 (manufacturer block in Sector 0) in memory of MiFare card char WRITE_4[] = {0xAA,0xBB,0x16,0x00,0x00,0x00,0x09,0x02,0x04,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x0F}; //Command to write data into Block 4 (in Sector 1) in memory of MiFare card //Data to be written (started with the lowest byte) is from byte 9 to 24, //total of 16 bytes data //Data is 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A //0x0B,0x0C,0x0D,0x0E,0x0F in this case //The last checksum byte of this command may change for data to written different from //that in this case char READ_4[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x04,0x0E}; //Command to read data in Block 4 (in Sector 1) in memory of MiFare card /*****************************/ unsigned char reply_buffer[26]; //Buffer to store data received from MiFare module when a certain command is sent (maximum is 26 bytes in this case) unsigned char NUID[4]; //Array for storing NUID of a MiFare card char mode = 0; //Variable storing current mode of the program void setup() { pinMode(button_1,INPUT); //Configure pins button_1 & button_2 as inputs pinMode(button_2,INPUT); digitalWrite(button_1,HIGH); //Pull-up pins button_1 & button_2 digitalWrite(button_2,HIGH); Serial.begin(19200); //Initiallize UART serial communication with baudrate = 19200bps (default baudrate of MiFare module) lcd.begin(8,2); //Initialize the lcd object created as type 2 rows x 8 column lcd.print("MiFare"); //Print welcome message "MiFare Demo" on LCD lcd.setCursor(0,1); lcd.print("Demo"); delay(2000); lcd.clear(); } void loop() { lcd.setCursor(0,0); switch(mode) { case 0: //Blinking of the MiFare module onboard LED in at rate of 0.5 Hertz lcd.print("0.LED "); if(!digitalRead(button_2)) { while(!digitalRead(button_2)); while(1) { lcd.setCursor(0,1); lcd.print("LED ON "); led_on(); delay(1000); lcd.setCursor(0,1); lcd.print("LED OFF"); led_off(); delay(1000); } } break; case 1: //Read the device number of MiFare module lcd.print("1.DEV NO"); if(!digitalRead(button_2)) { while(!digitalRead(button_2)); read_dev(); lcd.setCursor(0,1); lcd_to_hex(reply_buffer[10]); //Byte 9 and byte 10 of replied bytes (started with lowest byte)contains MiFare module device number lcd_to_hex(reply_buffer[9]); while(1); } break; case 2: //Read the NUID of MiFare card lcd.print("2.NUID "); if(!digitalRead(button_2)) { while(!digitalRead(button_2)); get_nuid(); //NUID of MiFare card is stored in NUID[] array after execution of this subroutine //There is total of 4 bytes started with the lowest byte lcd.setCursor(0,1); for(int i = 3; i>=0; i--) { lcd_to_hex(NUID[i]); //Print out the NUID obtained on LCD } while(1); } break; case 3: //Read the data stored in Block 0 in Sector 0 in memory of MiFare card lcd.print("3.READ0 "); if(!digitalRead(button_2)) { while(!digitalRead(button_2)); read_0(); while(1) { //Byte 9 to byte 24 of the replied bytes contains data (started with the lowest byte) read from Block 0 in Sector 0 //Due to the small screen of the LCD used, the data is printed on LCD for twice. The lower 8 bytes (started with lowest byte of the lower 8 bytes) is printed at the first time //While the upper 8 bytes (started with lowest byte of the upper 8 bytes)is printed at the second time. lcd.clear(); lcd.setCursor(0,0); lcd.print("0 to 7"); lcd.setCursor(0,1); lcd.print("byte"); delay(2000); lcd.clear(); lcd.setCursor(0,0); for(int i = 0; i<4; i++) { lcd_to_hex(reply_buffer[9+i]); } lcd.setCursor(0,1); for(int i = 0; i<4; i++) { lcd_to_hex(reply_buffer[13+i]); } delay(5000); lcd.clear(); lcd.setCursor(0,0); lcd.print("8 to 15"); lcd.setCursor(0,1); lcd.print("byte"); delay(2000); lcd.clear(); lcd.setCursor(0,0); for(int i = 0; i<4; i++) { lcd_to_hex(reply_buffer[17+i]); } lcd.setCursor(0,1); for(int i = 0; i<4; i++) { lcd_to_hex(reply_buffer[21+i]); } delay(5000); } } break; case 4: //Write data into Block 4 in Sector 1 in memory of MiFare card lcd.print("4.WRT_4 "); if(!digitalRead(button_2)) { while(!digitalRead(button_2)); write_4(); lcd.setCursor(0,1); lcd.print("Success!"); //Print "Success" on LCD to indicate a success write while(1); } break; case 5: //Read the data stored in Block 4 in Sector 1 in memory of MiFare card lcd.print("5.READ_4"); if(!digitalRead(button_2)) { while(!digitalRead(button_2)); read_4(); while(1) { //Byte 9 to byte 24 of the replied bytes contains data (started with the lowest byte) read from Block 4 in Sector 1 //Due to the small screen of the LCD used, the data is printed on LCD for twice. The lower 8 bytes (started with lowest byte of the lower 8 bytes) is printed at the first time //While the upper 8 bytes (started with lowest byte of the upper 8 bytes) is printed at the second time lcd.clear(); lcd.setCursor(0,0); lcd.print("0 to 7"); lcd.setCursor(0,1); lcd.print("byte"); delay(2000); lcd.clear(); lcd.setCursor(0,0); for(int i = 0; i<4; i++) { lcd_to_hex(reply_buffer[9+i]); } lcd.setCursor(0,1); for(int i = 0; i<4; i++) { lcd_to_hex(reply_buffer[13+i]); } delay(5000); lcd.clear(); lcd.setCursor(0,0); lcd.print("8 to 15"); lcd.setCursor(0,1); lcd.print("byte"); delay(2000); lcd.clear(); lcd.setCursor(0,0); for(int i = 0; i<4; i++) { lcd_to_hex(reply_buffer[17+i]); } lcd.setCursor(0,1); for(int i = 0; i<4; i++) { lcd_to_hex(reply_buffer[21+i]); } delay(5000); } } break; default: break; } if(!digitalRead(button_1)) //Detect the pressing down of button_1, change mode accordingly { while(!digitalRead(button_1)); mode++; if(mode > 5) { mode = 0; } } } //Turn on MiFare module LED subroutine void led_on(void) { for(int i = 0; i<10; i++) { Serial.write(LED_ON[i]); } for(int i = 0; i<10; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Turn on MiFare module LED subroutine void led_off(void) { for(int i = 0; i<10; i++) { Serial.write(LED_OFF[i]); } for(int i = 0; i<10; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Read MiFare device number subroutine void read_dev(void) { for(int i = 0; i<9; i++) { Serial.write(READ_DEV[i]); } for(int i = 0; i<12; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Turn on antenna of MiFare module subroutine void antenna_on(void) { for(int i = 0; i<10; i++) { Serial.write(ANTENNA_ON[i]); } for(int i = 0; i<10; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Request MiFare card type subroutine void card_req(void) { for(int i = 0; i<10; i++) { Serial.write(CARD_REQ[i]); } for(int i = 0; i<12; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Perform Anti-Collison subroutine void anti_col(void) { for(int i = 0; i<9; i++) { Serial.write(ANTI_COL[i]); } for(int i = 0; i<14; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } //Byte 9 to byte 12 of replied bytes contains NUID of the MiFare card //Store them in NUID[] array for(int i = 0; i<4; i++) { NUID[i] = reply_buffer[9+i]; } } //Select MiFare card subroutine void card_sel(void) { for(int i = 0; i<13; i++) { Serial.write(CARD_SEL[i]); } for(int i = 0; i<11; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Authenticate Sector 0 in memory of MiFare card subroutine void authen_sec0(void) { for(int i = 0; i<17; i++) { Serial.write(AUTHEN_SEC0[i]); } for(int i = 0; i<10; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Authenticate Sector 1 in memory of MiFare card subroutine void authen_sec1(void) { for(int i = 0; i<17; i++) { Serial.write(AUTHEN_SEC1[i]); } for(int i = 0; i<10; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Read data from Block 0 (manufaturer block) in memory of MiFare card subroutine void read_0 (void) { get_nuid(); card_sel(); //Select MiFare card authen_sec0(); //Authenticate Sector 0 in memory of MiFare card for(int i = 0; i<10; i++) { Serial.write(READ_0[i]); } for(int i = 0; i<26; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Read data from Block 4 in memory of MiFare card subroutine void read_4(void) { get_nuid(); card_sel(); //Select MiFare card authen_sec1(); //Authenticate Sector 0 in memory of MiFare card for(int i = 0; i<10; i++) { Serial.write(READ_4[i]); } for(int i = 0; i<26; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Write data into from Block 4 in memory of MiFare card subroutine void write_4(void) { get_nuid(); card_sel(); //Select MiFare card authen_sec1(); //Authenticate Sector 0 in memory of MiFare card for(int i = 0; i<26; i++) { Serial.write(WRITE_4[i]); } for(int i = 0; i<10; i++) { while(!Serial.available()); reply_buffer[i] = Serial.read(); } } //Get NUID of MiFare card subroutine void get_nuid(void) { unsigned char xor_temp = 0; antenna_on(); //On the MiFare module onboard antenna card_req(); //Request card type of MiFare card anti_col(); //Perform anti-collision for(int i = 0; i<4; i++) //Fill up byte 8 to byte 11 of CARD_SEL[] with NUID { CARD_SEL[i+8] = NUID[i]; } for(int i = 0; i<8; i++) //Calculate the checksum of byte 4 to byte 11 of the CARD_SEL[] { xor_temp ^= CARD_SEL[4+i]; } CARD_SEL[12] = xor_temp; //Fill the checksum in byte 12 of CARD_SEL[] } //Print byte as hex numbers on LCD subroutine void lcd_to_hex(unsigned char byte_receive) { unsigned char byte_temp = 0; byte_temp = (byte_receive>>4) & 0x0F; lcd.print(byte_temp,HEX); byte_temp = byte_receive & 0x0F; lcd.print(byte_temp,HEX); }