[MCU] RFID를 이용한 태그 인식

hyoin·2025년 11월 16일
post-thumbnail

이번 글에서는 RFID 기술과 MCU(마이크로컨트롤러)에서 RFID를 다루는 방법을 정리해 봤다.
특히, MFRC522 모듈을 이용해 RFID 태그를 읽고 쓰는 실습을 중심으로 작성했다.


1. RFID란?

RFID(Radio-Frequency IDentification)는 주파수를 이용해 ID를 식별하는 기술이다.
RFID 시스템은 크게 리더(Reader)태그(Tag)로 구성된다.

  • 리더: 태그의 ID를 읽고 데이터를 주고받는 장치
  • 태그: 리더가 인식할 수 있는 고유 ID와 데이터를 담고 있는 소형 칩

태그를 리더에 딱 맞춰서 붙일 필요는 없다. 비스듬히 놓여도 인식이 되지만, 너무 각도가 심하면 UID를 못 읽는 경우가 있다.


2. RFID 태그 구조와 메모리

태그에는 UID(Unique ID)사용자 데이터를 저장할 수 있는 메모리가 있다.
MFRC522 기준 메모리 구조는 아래와 같다:

  • 한 Sector: 4개의 Block
  • 한 Block: 16 Byte
  • 총 16 Sector → 16 × 4 = 64 Block
  • 보안 영역: Key A/B 없으면 읽기/쓰기 불가
  • UID는 첫 번째 섹터 첫 번째 블록에 저장되어 변경 불가

사용자는 나머지 블록에 데이터를 저장하거나 읽을 수 있다. 데이터 읽기/쓰기 전에는 반드시 인증 과정을 거쳐야 한다.

MFRC522의 메모리 정리:

SectorBlock인증 필요설명
00XUID 저장 블록, 읽기만 가능
01~3OKey A/B 필요, 보안 관련 데이터
1~150~3OKey A/B 필요, 사용자 지정 데이터

3. MCU와 RFID 통신: SPI

RFID 리더 모듈은 많은 데이터를 빠르게 주고받아야 하기 때문에 SPI(Serial Peripheral Interface) 통신을 사용한다.

SPI 기본 구조

역할
MOSIMCU → 모듈 데이터 전송
MISO모듈 → MCU 데이터 전송
SCK클록 신호, 데이터 타이밍 맞춤
SS통신할 슬레이브 선택

그리고 MFRC522에는 RST 핀이 있어 리셋과 통신 초기화를 담당한다.


4. MFRC522 실습

핀 연결

MFRC522 모듈과 Arduino Uno 연결 예시:

  • RST: 9
  • SS: 10
  • MOSI: 11
  • MISO: 12
  • SCK: 13
  • 3.3V: Vin 핀

참고: RST와 SS 외에는 모듈 내부적으로 핀이 이미 정해져 있으므로 변경할 필요가 없다. Arduino Uno가 아니라면 Arduino IDE에서 지정된 핀을 확인해야 한다.

클래스 사용법: MFRC522

여기에서 언급되는 클래스는 Arduino IDE에 있는 MFRC522.h에 정의된 클래스를 말한다.

  1. 모듈 초기화
#include <MFRC522.h>

const int RST_PIN = 9;
const int SS_PIN = 10;
MFRC522 rc522(SS_PIN, RST_PIN);

위에서 언급한 대로, 사용자가 직접 변경할 수 있는 핀은 SS, RST다 핀이다. 그러니 클래스에서 설정해 줘야 한다.

  1. 태그 감지 및 UID 읽기
if (!rc522.PICC_IsNewCardPresent()) return;
if (!rc522.PICC_ReadCardSerial()) return;

각각 새로운 카드가 존재하는지 여부, UID가 있는지를 확인하는 함수다. 이 코드가 있어야 MFRC522를 인식할 수 있다.

  1. 블록 인증
status = rc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, index, &key, &(rc522.uid));
if (status != MFRC522::STATUS_OK) 
{
    Serial.print("Authentication Failed: ");
    Serial.println(rc522.GetStatusCodeName(status));
    return;
}

write/read 함수를 쓰려면 인증이 필수적이다. index 위치의 key를 지정해주자.
참고로 따로 key를 설정하지 않았으면, key 값은 0xFF다.

  1. 데이터 쓰기
status = rc522.MIFARE_Write(index, (byte*)&data, length);
if (status != MFRC522::STATUS_OK) 
{
    Serial.print("Write Failed: ");
    Serial.println(rc522.GetStatusCodeName(status));
    return;
}

index 위치에서 length만큼 byte 단위로 작성한다. 아두이노 우노의 경우, 한 Block이 16Byte니 16byte로 설정했다.

  1. 데이터 읽기
byte buffer[18];
byte length = 18;

status = rc522.MIFARE_Read(index, buffer, &length);

if (status != MFRC522::STATUS_OK)
{
	Serial.print("Read Failed: ");
	Serial.println(rc522.GetStatusCodeName(status));
}

index 블록에서 length 만큼의 데이터를 읽어 buffer에 저장한다.
일반적으로 buffer는 체크섬/CRC 때문에 length보다 2~3Byte 더 크게 잡기에 18로 length를 지정했다.

5. 실습 시 주의사항

  • 태그를 너무 세게 밀거나 각도가 심하면 인식 실패 가능
  • 데이터 읽기/쓰기 전 반드시 인증 필요
  • SPI 속도, 전원 연결 상태, 모듈 초기화 여부 체크
profile
배워야 할 게 많은 개발자... 하지만 공부를 포기하지 않지!!

0개의 댓글