본문으로 바로가기

아두이노(Arduino) 중급 RFID-RC522모듈 NFC기능 사용하기 #1 메인사진

 

안녕하세요. 애드라이프입니다.

정말 오랜만에 아두이노 포스팅을 하는것 같네요.

이번에 제가 준비한 녀석?은 RFID-RC522모듈입니다.

 

우선 실물부터 보시겠습니다.

RFID-RC522모듈 실물사진

 

제가 구입한 모듈은 납땜이 안되어있는 상태의

모듈입니다. 단가차이가 좀 나거든요.

그래도 납땜하기가 어려우신 분들은 땜된걸로

구입하시기 바랍니다.

 

납땜 후 RFID-RC522모듈 실물사진 

 

짜잔!! 저는 납땜하는데 아무런 문제가 없기때문에

바로 납땜해버렸죠!! 후훗!!

 

자! 이제 모듈도 사용할 준비가 되었습니다.

실제로 TEST하기 전에 간단하게 해당 모듈의

스팩을 살펴보도록 하겠습니다.


 

 

RFID

Radio-Frequency IDentification

 

전파를 이용해 먼 거리에서 정보를 인식하는 기술.

그 예와 기술에 대한 자세한 정보는 나무위키 참고!!

나무위키 <- 링크

 

우리가 사용하고자하는 RFID-RC522모듈은

동작전압 : +3.3V

소비전류 : 13~26mA

동작 주파수 : 13.56Mhz

지원하는 카드(tag) : Mifarel S50, Mifarel S70,

Mifare UltraLight, Mifare Pro, Mifare DESfire

 

오늘 TEST할 Tag는 아래보이는 하얀색 RFID CARD입니다.

이 카드는 1Kbyte의 데이터를 저장할 수 있습니다.

RFID CARD 실물

 

이번시간에는 RFID-RC522모듈을 통해서 

위 카드의 정보를 읽어오는 방법을 설명하겠습니다.

 

[ 하드웨어 구성 ]

RFID-RC522 배선도

RFID-RC522 아두이노(Arduino) UNO
RST 9
SPI SDA 10
SPI MOSI 11
SPI MISO 12
SPI SCK 13
VCC +3.3V
GND GND

 

위 배선도와 아래 표를 함께 보시면

이해하는데 어렵지 않을 것입니다.

 

회로구성은 마무리되었습니다.

우리가 읽고자 하는 RFID TAG는

총 64개의 블럭이 존재합니다.

그리고 블럭 4개씩 묶어 하나의 Sector를 구성하죠

그리고 Sector의 마지막 블럭은 키데이터를

지니고 있습니다.

 

좀 더 자세한 설명은 다음 포스팅에서 하도록하고

이번 포스팅에는 바로 프로그램으로 넘어가겠습니다.

 

아래 두가지 셈플코드를 다운받아 주세요.

 

< RFID 라이브러리 파일 >

AddicoreRFID.zip
0.01MB

< RFID Master 라이브러리 파일 >

rfid-master.zip
1.05MB

 

 

라이브러리 추가방법은 아래 링크를 참고해주세요.

아두이노 라이브러리 추가방법 <- 링크

 

아두이노IDE 개발환경 구축 4편 라이브러리 추가법(feat 헤더파일)

아두이노(Arduino) 개발환경 구축 - 라이브러리 추가법 애드라이프의 아두이노 모든 포스팅 리스트를 보고 싶으신 분은 공지를 읽어주세요. 안녕하세요. 애드라이프 입니다. 이번 포스팅에서는 자체적으로 개발되..

increase-life.tistory.com

라이브러리 추가가 끝나면 

추가한 라이브러리중 rfid-master폴더 안의

examples폴더에 DumpInfo.ino파일을

실행시켜서 아두이노에 업로드 합니다.

 

/*
 * --------------------------------------------------------------------------------------------------------------------
 * Example sketch/program showing how to read data from a PICC to serial.
 * --------------------------------------------------------------------------------------------------------------------
 * This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
 * 
 * Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
 * Reader on the Arduino SPI interface.
 * 
 * When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
 * then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When
 * you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
 * will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages
 * when removing the PICC from reading distance too early.
 * 
 * If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading).
 * So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all
 * details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so
 * keep the PICCs at reading distance until complete.
 * 
 * @license Released into the public domain.
 * 
 * Typical pin layout used:
 * -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno           Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 */

#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
	Serial.begin(9600);		// Initialize serial communications with the PC
	while (!Serial);		// Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
	SPI.begin();			// Init SPI bus
	mfrc522.PCD_Init();		// Init MFRC522
	mfrc522.PCD_DumpVersionToSerial();	// Show details of PCD - MFRC522 Card Reader details
	Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
	// Look for new cards
	if ( ! mfrc522.PICC_IsNewCardPresent()) {
		return;
	}

	// Select one of the cards
	if ( ! mfrc522.PICC_ReadCardSerial()) {
		return;
	}

	// Dump debug info about the card; PICC_HaltA() is automatically called
	mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

이렇게 되어있는 소스코드입니다.

업로드가 완료되고 시리얼 모니터를 실행시켜

결과가 아래와 같으면 성공적으로 정보를 읽어온것입니다.

 

RFID-RC522 rfid-master ample code 실행결과

 

이 수많은 데이터 중에서

정작쓰이는 데이터는 그렇게 많지 않습니다.

잘 생각해보면 우리가 이런 RFID기술을 쓰는 이유는

사용자를 구분하기 위해서가 아닐까요?

 

회사의 사원증이나 도서관의 출입증, 학생증 등등

그럼 카드마다 고유의 정보를 가지고 있고

해당 정보를 리더기에서 기억하고 있다가

허가를 해줄것인지 거부를 할것인지

정해주기만하면 우리도 얼마든지 RFID 기술을

응용 할 수 있다는 이야기다 됩니다.

 

 

 

여기서 간단하게 소량의 데이터를 가지고

위에서 말한 사용자 구분을 할 수있는 방법을 알려드립니다.

여기까지만 할 줄 알아도 졸업작품들에 응용하는데

어려움이 없을것이라 생각합니다!!

 

위에서 rfid-master에서 샘플코드를 가져왔다면

이번에는 AddicoreRFID폴더 안에서 Sample폴더의

Addicore_RFID_Example.ino를 실행시켜 업로드합니다.

// Example sketch to read the ID from an Addicore 13.56MHz RFID tag
// as found in the RFID AddiKit found at: 
// http://www.addicore.com/RFID-AddiKit-with-RC522-MIFARE-Module-RFID-Cards-p/126.htm

#include <AddicoreRFID.h>
#include <SPI.h>

#define	uchar	unsigned char
#define	uint	unsigned int

//4 bytes tag serial number, the first 5 bytes for the checksum byte
uchar serNumA[5];

uchar fifobytes;
uchar fifoValue;

AddicoreRFID myRFID; // create AddicoreRFID object to control the RFID module

/////////////////////////////////////////////////////////////////////
//set the pins
/////////////////////////////////////////////////////////////////////
const int chipSelectPin = 10;
const int NRSTPD = 5;

//Maximum length of the array
#define MAX_LEN 16

void setup() {                
   Serial.begin(9600);                        // RFID reader SOUT pin connected to Serial RX pin at 9600bps 
 
  // start the SPI library:
  SPI.begin();
  
  pinMode(chipSelectPin,OUTPUT);              // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin 
    digitalWrite(chipSelectPin, LOW);         // Activate the RFID reader
  pinMode(NRSTPD,OUTPUT);                     // Set digital pin 10 , Not Reset and Power-down
    digitalWrite(NRSTPD, HIGH);

  myRFID.AddicoreRFID_Init();  
}

void loop()
{
  	uchar i, tmp, checksum1;
	uchar status;
        uchar str[MAX_LEN];
        uchar RC_size;
        uchar blockAddr;	//Selection operation block address 0 to 63
        String mynum = "";

        str[1] = 0x4400;
	//Find tags, return tag type
	status = myRFID.AddicoreRFID_Request(PICC_REQIDL, str);	
	if (status == MI_OK)
	{
            Serial.println("RFID tag detected");
    	    Serial.print(str[0],BIN);
            Serial.print(" , ");
    	    Serial.print(str[1],BIN);
            Serial.println(" ");
	}

	//Anti-collision, return tag serial number 4 bytes
	status = myRFID.AddicoreRFID_Anticoll(str);
	if (status == MI_OK)
	{
            checksum1 = str[0] ^ str[1] ^ str[2] ^ str[3];
            Serial.println("The tag's number is  : ");
    	    //Serial.print(2);
    	    Serial.print(str[0]);
            Serial.print(" , ");
    	    Serial.print(str[1],BIN);
            Serial.print(" , ");
    	    Serial.print(str[2],BIN);
            Serial.print(" , ");
    	    Serial.print(str[3],BIN);
            Serial.print(" , ");
    	    Serial.print(str[4],BIN);
            Serial.print(" , ");
            Serial.println(checksum1,BIN);
            
            // Should really check all pairs, but for now we'll just use the first
            if(str[0] == 156)                      //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
            {
                Serial.print("Hello Craig!\n");
            } else if(str[0] == 244) {             //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
                Serial.print("Hello Erin!\n");
            }
            Serial.println();
            delay(1000);
	}
		
        myRFID.AddicoreRFID_Halt();		   //Command tag into hibernation              

}

 

위와 같은 코드입니다. 

해당 코드는 자신이 가지고 있는 카드정보를 

수정하기 전의 코드입니다.

이대로 실행해서 결과를 한번 보겠습니다.

Addicore_RFID_Example.ino 실행 결과

RFID-RC522 rfid-master ample code 실행결과를보면

제가 가지고 있는 RFID CARD의 UID는

0x22 0xA9 0x75 0x1D입니다.(HEX코드)

하지만 수정 전 Addicore_RFID_Example.ino의

마지막 부분을 보면 

if (status == MI_OK)
	{
            checksum1 = str[0] ^ str[1] ^ str[2] ^ str[3];
            Serial.println("The tag's number is  : ");
    	    //Serial.print(2);
    	    Serial.print(str[0]);
            Serial.print(" , ");
    	    Serial.print(str[1],BIN);
            Serial.print(" , ");
    	    Serial.print(str[2],BIN);
            Serial.print(" , ");
    	    Serial.print(str[3],BIN);
            Serial.print(" , ");
    	    Serial.print(str[4],BIN);
            Serial.print(" , ");
            Serial.println(checksum1,BIN);
            
            // Should really check all pairs, but for now we'll just use the first
            if(str[0] == 156)                      //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
            {
                Serial.print("Hello Craig!\n");
            } else if(str[0] == 244) {             //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
                Serial.print("Hello Erin!\n");
            }
            Serial.println();
            delay(1000);
	}

UID 첫번째 부분의 값이 156(10진수)일때와 244(10진수)일때

문구를 띄워주는 형식으로 되어있습니다.

그렇다면 이 부분을 자신이 가지고 있는 카드의 정보와

맞게 고처주면 사용자 구분을 할 수 있다는 이야기가됩니다.

 

 

 

밑에 UID비교부분과 표현되는 방식을 16진수로 바꾼

프로그램을 첨부하겠습니다.

(제 카드의 UID첫번째 부분이 0x22였으니 10진수로 34입니다.)

// Example sketch to read the ID from an Addicore 13.56MHz RFID tag
// as found in the RFID AddiKit found at: 
// http://www.addicore.com/RFID-AddiKit-with-RC522-MIFARE-Module-RFID-Cards-p/126.htm

#include <AddicoreRFID.h>
#include <SPI.h>

#define	uchar	unsigned char
#define	uint	unsigned int

//4 bytes tag serial number, the first 5 bytes for the checksum byte
uchar serNumA[5];

uchar fifobytes;
uchar fifoValue;

AddicoreRFID myRFID; // create AddicoreRFID object to control the RFID module

/////////////////////////////////////////////////////////////////////
//set the pins
/////////////////////////////////////////////////////////////////////
const int chipSelectPin = 10;
const int NRSTPD = 5;

//Maximum length of the array
#define MAX_LEN 16

void setup() {                
   Serial.begin(9600);                        // RFID reader SOUT pin connected to Serial RX pin at 9600bps 
 
  // start the SPI library:
  SPI.begin();
  
  pinMode(chipSelectPin,OUTPUT);              // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin 
    digitalWrite(chipSelectPin, LOW);         // Activate the RFID reader
  pinMode(NRSTPD,OUTPUT);                     // Set digital pin 10 , Not Reset and Power-down
    digitalWrite(NRSTPD, HIGH);

  myRFID.AddicoreRFID_Init();  
}

void loop()
{
  	uchar i, tmp, checksum1;
	uchar status;
        uchar str[MAX_LEN];
        uchar RC_size;
        uchar blockAddr;	//Selection operation block address 0 to 63
        String mynum = "";

        str[1] = 0x4400;
	//Find tags, return tag type
	status = myRFID.AddicoreRFID_Request(PICC_REQIDL, str);	
	if (status == MI_OK)
	{
            Serial.println("RFID tag detected");
    	    Serial.print(str[0],HEX);
            Serial.print(" , ");
    	    Serial.print(str[1],HEX);
            Serial.println(" ");
	}

	//Anti-collision, return tag serial number 4 bytes
	status = myRFID.AddicoreRFID_Anticoll(str);
	if (status == MI_OK)
	{
            checksum1 = str[0] ^ str[1] ^ str[2] ^ str[3];
            Serial.println("The tag's number is  : ");
    	    //Serial.print(2);
    	    Serial.print(str[0],HEX);
            Serial.print(" , ");
    	    Serial.print(str[1],HEX);
            Serial.print(" , ");
    	    Serial.print(str[2],HEX);
            Serial.print(" , ");
    	    Serial.print(str[3],HEX);
            Serial.print(" , ");
    	    Serial.print(str[4],HEX);
            Serial.print(" , ");
            Serial.println(checksum1,HEX);
            
            // Should really check all pairs, but for now we'll just use the first
            if(str[0] == 34)                      //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
            {
                Serial.print("Hello AddLife Studio!\n");
            } else if(str[0] == 244) {             //You can change this to the first byte of your tag by finding the card's ID through the Serial Monitor
                Serial.print("Hello Erin!\n");
            }
            else{
                Serial.print("Access Failure\n");
            }
            Serial.println();
            delay(1000);
	}
		
        myRFID.AddicoreRFID_Halt();		   //Command tag into hibernation              

}

 

수정된 프로그램의 결과를 보도록 하겠습니다.

자신의 카드에 맞게 수정된 Addicore_RFID_Example.ino 실행 결과

결과를 보면 표현방식이 바이너리방식에서 Hex로

변경되었고 첫번째 22를 판독하여 Hellow AddLife Studio

라는 문구를 띄우는데 성공하였습니다!!

 

바이너리방식에서 Hex방식으로 바꾼이유는

앞의 전체 블럭을 읽어오는 프로그램과 

표현방식을 동일하게 하여 좀더 보기 편하게

하기 위함입니다. :)

 

이번 포스팅은 여기까지 입니다.

다음 포스팅에서는 읽기뿐 아니라 쓰기까지 해볼 예정입니다.

그리고 이론에 대해서도 좀더 자세히 알아보겠습니다.

 

더욱 유익한 포스팅으로 돌아오겠습니다.

by 애드라이프

 

구독과 공감버튼 눌러주세요!!