[아두이노] RFID-RC522 제어

IOT/아두이노|2019. 5. 6. 09:00

아두이노] RFID-RC522 제어



오늘은 RFID-RC522 모듈을 살펴보고자 합니다. 이 모듈은 일상에서 교통카드, 출입문 카드, 도어락 카드와 같은 것들을 아두이노상에서 표현할 수 있는 모듈입니다. 카드에 등록된 정보를 RFID-RC522 리더기가 읽고 그 읽은 값을 통해서 우리는 여러가지를 표현할 수 있습니다. RFID 모듈은 통신 방식이 SPI여서 좀 까다롭습니다. I2C 모듈이면 좀 더 사용하기가 편할 텐데 말이죠. 실험에서는 카드 인식에 문제가 생겨서 아래 사진에서 보는 것처럼 열쇠 고리 모양 같은걸로 간단히 실험을 하였네요. 이제부터서 RFID-RC522 모듈을 아두이노 핀에 어떻게 연결하고 코딩할 때 필요한 MFRC522 라이브러리를 설치에 대해서 알아본 뒤에 라이브러리드 안에 있는 DumpInfo 예제를 통해서 카드 정보를 읽는 실험을 하겠습니다.


1. RFID-RC522





출처 : Fritzing

RFID-RC522 모습은 위 출처가 링크 된 곳에서 다운로드 하신 후 Fritzing에 등록하셔서 디자인 하시면 됩니다. 핀 번호는 위에서 부터 아래로 순서대로 아래 표를 참조하시면 되겠습니다.


SPI 통신을 하기 때문에 아두이노의 핀과 RFID-RC522 핀을 위 표처럼 연결하시면 됩니다. 어떤 RFID 모듈은 I2C통신을 하는 모듈이 있는데 그럴 경우는 아날로그 핀 A4, A5으로 연결하셔서 실험하시면 됩니다. 자신이 사용하는 모듈은 어떤 방식인지를 우선 구별하시고 핀을 연결하시면 됩니다.

2. RFID-RC522 회로도


  • 준비물 : RFID-RC522, 아두이노우노
  • 내용 : SPI 통신을 할 수 있게 핀은 연결한다.


선 연결이 좀 복잡해 보이지만 위 표를 보시고 선을 연결하시면 어렵지 않을 거라 생각됩니다. 그래도 이해가 안되시면 아래 스케메틱 회로도를 보고 선을 연결하시면 되겠습니다.



출처 : Fritzing

3. RFID-RC522 라이브러리 추가


rfid로 검색하시면 되는데 직접 MFRC522로 검색어로 검색하셔도 됩니다. 아래처럼 검색이 되면 이 라이브러리를 설치하시면 됩니다.


4. 코딩



MFRC522

#include <SPI.h>
#include <MFRC522.h>
  • MFRC522 mfrc522(SS_PIN, RST_PIN) : MFRC522 인스턴스화
  • SPI.begin() :SPI bus 초기화
  • mfrc522.PCD_Init() : MFRC522 초기화
  • mfrc522.PICC_IsNewCardPresent() : 새카드 확인
  • frc522.PICC_ReadCardSerial() : 하나의 카드읽기 확인
  • rfid.uid.uidByte[] : 읽은 카드 키값이 들어 있음

miguelbalboa의 라이브러리 안에 위 함수들이 있는데 여러가지 함수들이 있는데 가장 기본적인 것만 설명하기 때문에 꼭 기억해 주세요. 저도 이 라이브러리를 사용하여 간단히 테스트를 했지만 따로 만들고 싶은 것이 없어서 그냥 간단히 테스트만 했네요. 제대로 RFIC-RC522를 사용하기 위해서는 링크된 라이브러리에 가셔서 코딩을 제대로 이해하시고 사용하실 수 있을 꺼에요.

MFRC522 라이브러리를 설치하면 여러개의 예제가 있는 데 한번씩 다 사용해서 어떤 결과가 나오는지 확인 해보시기 바랍니다.

여러 예제들 중에서 소스 코딩이 짧아보이는 DumpInfo라는 예제가 있습니다. 카드 정보를 읽어와서 출력하는 예제인데 이걸로 정상 작동하는지 살펴 볼께요.

[소스] MFRC522의 예제 중 DumpInfo( 출처 : miguelbalboa의 라이브러리)

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

[실행]


리더기가 정상적으로 인식했네요.

소스 코딩을 보면 MFRC522의 객체변수를 mfrc522를 선언할 때 RST, SS Pin을 두개를 인자로 인스턴스화 하네요.

SPI.begin();            // Init SPI bus
mfrc522.PCD_Init();     // Init MFRC522

이렇게 해서 초기화 작업을 끝냈고 장상적으로 인식하는지 테스트가 진행 됩니다.

mfrc522.PCD_DumpVersionToSerial();

위 실행 결과에서 정상적으로 "Firmware Version: 0x88= (clone)" 라고 떴지만 인식을 안하면 실패한 에러 메세지가 출력 됩니다.

정상적으로 인식 했으니깐 카드를 읽을 준비를 합니다.

두개의 if문이 loop()함수에서 나옵니다.

mfrc522.PICC_IsNewCardPresent() 새카드 확인
mfrc522.PICC_ReadCardSerial() 카드 읽기

새로운 카드를 확인하면 다음 카드 읽기가 진행됩니다. 이 두 과정을 IF문으로 이렇게 표현하면 어떻게 동작 할까요.

if(!조건식) return ;

이 명령라인의 의미는 조건식이 거짓일 때 참이 됩니다. 족건식이 거짓이면 if문이 참이되어 return 명령을 만나는데 이 명령은 현재 명령 범위에서 아래 명령을 수행 할 필요 없이 다시 그 명령 범위를 빠져 나오라는 의미가 됩니다.

void loop(){
  if(!조건식) return ;
    명령문1;
    명령문2;
}

이렇게 되어 있으면 조건식이 거짓이면 return 명령으로 명령문1, 명령문 2를 수행하지 않고 빠져나와 종료된다고 생각하시면 돼요. loop()은 문한 반복이니깐 빠져나왔지만 loop()함수가 처음부터 다시 수행됨으로 if문의 조건식이 참인지 거짓인지 계속 무한 판정을 하게 됩니다. 이때 if문이 거짓이 되면 return 명령을 수행하지 않고 다음 명령문1, 명령문2가 수행되게 됩니다. 어떤 의미인지 아시겠죠.

위 소스에서 PICC_IsNewCardPresent()함수로 새카드인지 확인하고 카드가 확인되면 if문에서 새카드 확인되지 못할 때만 return 명령을 수행하기 때문에 확인되면 다음으로 넘어 갑니다. PICC_ReadCardSerial() 확인된 새카드를 읽게 됩니다. 읽게 되면은 if문에서 읽지 못할때 return 명령을 수행하기 때문에 읽었으니깐 다음 명령으로 넘어 가게 됩니다.

이렇게 두단계로 새카드 확인과 카드읽기로 락을 걸어놓은 것이죠.

mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

Dump 정보를 시리얼모니터로 출력시키는 명령입니다.

5. 결과


아래와 같이 카드를 리더기에 올려놓으면 카드의 정보를 읽어오게 됩니다.


5. RFID-RC522 인식이 에러 해결책


아래와 같은 메세지가 인식하지 못할 때 뜨게 됩니다.


첫번째, 인식 실패의 원인은 접촉 불량입니다. 처음에 잘 작동되더라도 나중에 쓰다보면 잘 인식하지 못합니다. 그래서 이 모듈을 사용하는 분들은 대부분 납땜을 많이 합니다.

두번째, 기존 아두이노에 이식 된 프로그램에 새로 업로드 한 프로그램과 그 사이에 리더기의 동작 에러가 발생 할 수 있습니다. 전원을 끄고 다시 접속해서 한번 문제가 생기면 사실 재 인식이 되지 않는 경우가 발생 합니다. 그럴 때 접촉 불량인가 하고 다시 연결선들을 점검하는데 혹시 이런 문제로 인해 인식을 못할 수 있으니깐요. 다른 프로그램을 아두이노에 업로해서 돌려 본 뒤에 다시 RFID-RC522 소스를 돌려보세요. 저도 방금 전 잘 인식되던게 인식 에러 상황을 만들려고 Gnd 선을 빼고 프로그램을 업로드 한뒤에 정상적으로 선 연결하고 업로드 했더니 RFID-RC522가 인식을 안하더군요. 선 접촉 불량인가 하고 삽질을 하다가 그냥 기본 예제인 Blink를 아두이노에 업로드 하고 나서 다시 RFID-RC522 소스를 업로드 하니깐 그때서야 정상적으로 인식이 되었습니다.

마무리


RFID-RC522 라이브러리가 참 쉽지 않는 라이브러리 입니다. 사용하는 함수들이 많은데 사실 라이브러리 파일을 찾아가서 안에 함수 내용이 정확히 어떻게 코딩되어 있는지 확인해야 그 의미를 이해할 수 있습니다. 저도 이 RFID 리더기를 사용할 때 좀 버겁습니다. 단지 카드를 대면 리더기가 읽으면 카드 UID값이 rfid.uid.uidByte[] 변수에 저장되는데 카드 UID 값을 기준으로 간단한 제어만 할 수 있습니다.

이 부품은 응용 범위가 많습니다. 일상에서 하루에 한번씩은 접해 보셨을 거라 생각됩니다. 교통카드 충전할 때 그 상황을 생각해보세요. 또는 매장에 물건을 살 때 택을 찍을 때를 상황을 떠올려 보세요. 도서관이나 회사 입구를 지나갈때 카드를 대고 지나가는 상황을 떠올려 보세요. 교통카드로 전철이나 버스를 타기 위해서 교통카드를 찍을 때를 떠올려 보세요. 집 출입문에 도어락을 떠올려보세요. 이외에도 많은 곳에서 이와 비슷한 것들이 많습니다.

RFID-RC522를 이용하시는 분들은 한번 이 모듈을 이용하여 어떤 것을 표현하고 싶은지 상상을 해보시고 재밌어 보이면 해당 라이브러리를 한번 열어보시고 그 함수의 로직이 어떻게 코딩되어 있는지 제대로 공부해보세요. 응용 분야가 많아서 아이디어만 있으면 꽤 괜찮은 작품들을 만들어 낼 수 있을 거라 생각됩니다.

댓글()