본문으로 이동
주 메뉴
주 메뉴
사이드바로 이동
숨기기
둘러보기
대문
최근 바뀜
임의의 문서로
미디어위키 도움말
특수 문서 목록
학교의 모든 지식. SMwiki
검색
검색
보이기
로그인
개인 도구
로그인
로그아웃한 편집자를 위한 문서
더 알아보기
기여
토론
아두이노:RFID(13.56MHz)
편집하기
문서
토론
한국어
읽기
편집
원본 편집
역사 보기
도구
도구
사이드바로 이동
숨기기
동작
읽기
편집
원본 편집
역사 보기
일반
여기를 가리키는 문서
가리키는 글의 최근 바뀜
파일 올리기
문서 정보
보이기
사이드바로 이동
숨기기
Sam
(
토론
|
기여
)
님의 2026년 9월 10일 (목) 07:47 판
(
→
코드 작성 예시
)
(
차이
)
← 이전 판
|
최신판
(
차이
) |
다음 판 →
(
차이
)
경고: 이 문서의 오래된 판을 편집하고 있습니다.
이것을 게시하면, 이 판 이후로 바뀐 모든 편집이 사라집니다.
경고:
로그인하지 않았습니다. 편집을 하면 IP 주소가 공개되게 됩니다.
로그인
하거나
계정을 생성하면
편집자가 사용자 이름으로 기록되고, 다른 장점도 있습니다.
스팸 방지 검사입니다. 이것을 입력하지
마세요
!
{{아두이노}} == 개요 == 아두이노로 RFID 13.56MHz 규격을 다루는 것에 관한 문서. RFID 자체에 관한 내용은 [[RFID]] 문서 참고 13.56 MHz 대역을 사용하는 RFID는 일반적으로 HF(High Frequency) RFID로 분류되며, 교통카드, 학생증, 사원증, 출입카드, 전자여권, NFC 태그 등에 활용된다. 아두이노에서는 RFID 리더 모듈을 연결하여 태그의 고유 식별번호인 UID를 읽거나, 지원되는 태그의 메모리에 데이터를 읽고 쓸 수 있다. == RFID 시스템의 구성 == RFID 시스템은 일반적으로 다음과 같이 구성된다. {| class="wikitable" |+ !요소 !설명 !비고 |- |'''태그(Tag)''' | * 카드, 열쇠고리, 스티커 등의 형태로 제작됨. * UID와 사용자 데이터를 저장할 수 있음. * 수동형 태그는 별도의 배터리 없이 리더가 만드는 전자기장으로부터 동작에 필요한 에너지를 얻음. | |- |'''리더(Reader)''' | * 태그와 무선으로 통신함. * 태그의 UID 또는 저장된 데이터를 읽음. * 일부 리더는 태그 메모리에 데이터를 기록할 수 있음. | |- |'''제어 장치''' | * 아두이노, ESP32, 라즈베리파이 등의 마이크로컨트롤러 또는 컴퓨터를 사용함. * RFID 리더로부터 받은 정보를 처리함. * LED, 부저, 디스플레이, 도어록 등의 장치를 제어할 수 있음. | |} === 작동 원리 === 13.56 MHz RFID의 기본 동작 과정은 다음과 같다. * RFID 리더가 13.56 MHz의 전자기장을 형성함. * 리더 가까이에 있는 수동형 태그가 전자기장으로부터 동작에 필요한 에너지를 얻음. * 리더가 태그에 명령을 전송함. * 태그가 UID 또는 저장된 데이터를 응답함. * 리더가 응답을 수신하여 아두이노 등의 제어 장치로 전달함. * 제어 장치가 UID 확인, 출입 허용, 출결 기록 등의 작업을 수행함. == 13.56MHz와 통신 규격의 구분 == 13.56 MHz는 RFID 통신에서 사용하는 반송파 주파수를 의미한다. 같은 13.56 MHz를 사용하더라도 모든 리더와 태그가 서로 호환되는 것은 아니다. == 모듈 선택 기준 == {| class="wikitable" !목적 !적합한 모듈 예시 !선택 이유 |- |저비용 입문 실습 |RC522 |배선과 UID 읽기 실습이 비교적 간단함. |- |스마트폰 NFC와의 연동 |PN532 또는 NFC 전용 모듈 |RC522보다 NFC 관련 지원 범위가 넓음. |- |ISO/IEC 15693 태그 실습 |해당 규격을 지원하는 리더 |RC522는 일반적으로 ISO/IEC 15693을 지원하지 않음. |- |다양한 종류의 13.56 MHz 태그 실험 |복수 규격을 지원하는 리더 |13.56 MHz라는 주파수만으로는 태그 호환성을 보장할 수 없음. |- |출입통제 보안 실험 |보안 기능을 지원하는 태그와 리더 |단순 UID 비교보다 인증 및 암호화 기능이 필요함. |} == 주의 사항 == * RFID 리더와 태그가 모두 13.56 MHz를 사용하더라도 통신 규격이 다르면 인식되지 않을 수 있음. * RC522 모듈은 일반적으로 3.3 V 전원을 사용함. * 안테나 주변에 금속이 있으면 인식 성능이 저하될 수 있음. * 태그와 리더의 방향 및 거리에 따라 인식 여부가 달라질 수 있음. * 하나의 리더가 모든 MIFARE 및 NFC 기능을 지원하는 것은 아님. * UID는 카드 종류에 따라 길이가 다를 수 있으므로 UID 길이를 고정하여 처리하지 않는 것이 좋음. * 결제카드나 실제 출입카드의 데이터를 임의로 읽거나 복제해서는 안 됨. * 실습에는 교육용으로 제공된 RFID 카드와 태그를 사용해야 함. == RFID와 NFC의 관계 == NFC는 13.56 MHz 대역을 사용하는 근거리 무선 통신 기술이다. RFID와 관련된 기술이지만, 모든 13.56 MHz RFID 장치가 NFC의 모든 기능을 지원하는 것은 아니다. 따라서 스마트폰과의 통신이 필요한 경우에는 단순히 13.56 MHz를 지원하는지만 확인하지 말고, 사용하는 모듈이 필요한 NFC 동작 모드와 태그 규격을 지원하는지 확인해야 한다. = 13.56 MHz의 주요 통신 규격 = 같은 주파수를 사용하는 태그와 리더라도 지원하는 통신 규격이 다르면 서로 통신할 수 없다. {| class="wikitable" style="text-align:center;" ! 규격 ! 분류 ! 사용 주파수 ! 주요 특징 ! 대표 기술 및 제품 ! 주요 용도 |- | ISO/IEC 14443 Type A | 근접형 | 13.56 MHz | Type A 방식의 변조, 부호화, 충돌 방지 및 카드 선택 절차를 사용함. | MIFARE Classic, MIFARE Ultralight, MIFARE DESFire, NTAG 계열 | 교통카드, 출입카드, 학생증, NFC 태그 |- | ISO/IEC 14443 Type B | 근접형 | 13.56 MHz | Type A와 같은 주파수를 사용하지만 변조, 부호화 및 초기화 방식이 다름. | Type B 비접촉식 스마트카드 | 전자신분증, 전자여권, 비접촉식 스마트카드 |- | FeliCa | 근접형 | 13.56 MHz | ISO/IEC 14443 Type A/B와는 다른 통신 방식을 사용하는 비접촉식 카드 기술임. | FeliCa 카드 및 모바일 FeliCa | 교통카드, 전자화폐, 출입관리 |- | ISO/IEC 15693 | 근방형 | 13.56 MHz | ISO/IEC 14443보다 비교적 먼 거리에서 태그를 식별하는 용도에 적합함. | ICODE, ST25TV 계열 | 도서 관리, 자산 관리, 문서 추적, 산업용 태그 |- | ISO/IEC 18000-3 | 품목 관리용 HF RFID | 13.56 MHz | 물품 식별과 관리를 위한 HF RFID 무선 인터페이스를 규정함. | 산업용 HF RFID 태그 | 물류, 재고 및 품목 관리 |- | NFC Forum 규격 | NFC (NFC 기기간 통신 가능) | 13.56 MHz | NFC 장치 간 상호 운용을 위한 태그 유형, 동작 방식 및 데이터 형식을 규정함. | NFC Forum Type 1~5 Tag, NDEF | 스마트폰 태그 인식, 정보 전달, 기기 연결 |} === ISO/IEC 14443 === ISO/IEC 14443은 13.56 MHz를 사용하는 근접형 비접촉식 카드 규격이다. 가까운 거리에서 카드를 인식하고 데이터를 빠르게 교환하는 용도에 적합하다. ISO/IEC 14443은 크게 Type A와 Type B로 구분된다. {| class="wikitable" !구분 !Type A !Type B |- |사용 주파수 |13.56 MHz |13.56 MHz |- |분류 |근접형 카드 |근접형 카드 |- |통신 방식 |Type A 방식의 변조, 부호화 및 초기화 절차 사용 |Type B 방식의 변조, 부호화 및 초기화 절차 사용 |- |대표 사례 |MIFARE 계열, 일부 NFC 태그 |전자신분증 및 비접촉식 스마트카드의 일부 |- |상호 호환성 |Type A만 지원하는 리더에서는 Type B 태그를 인식할 수 없음. |Type B만 |} = RC522 모듈 = 입문용으로 많이 사용하는 모듈. {| class="wikitable" !항목 !사양 |- |동작 주파수 |13.56 MHz |- |지원 규격 |ISO/IEC 14443 Type A |- |지원 태그 |MIFARE 및 NTAG 계열 |- |일반적인 전원 |3.3 V |- |대표 인식거리 |최대 약 50 mm |} {| class="wikitable" style="text-align:center;" !규격 ! RC522 지원 |- |ISO/IEC 14443 Type A | 지원 |- |ISO/IEC 14443 Type B | 미지원 |- |FeliCa | 미지원 |- |ISO/IEC 15693 | 미지원 |- |ISO/IEC 18000-3 | 미지원 |- |NFC Forum 규격 | 일부 Type A 태그만 제한적으로 인식 |} === 연결 예시 === https://javalab.org/wp-content/uploads/arduino_rfid_test_4.png {| class="wikitable" style="text-align:center; width:100%;" ! 아두이노 우노 R3 ! RFID-RC522 리더 !역할 |- | 3.3V | VCC |RC522에 3.3V 전원을 공급 |- | GND | GND |두 장치의 전압 기준을 통일하는 접지 |- | D13 | SCK |SPI 통신의 클록 신호 전송 |- | D12 | MISO |RC522가 읽은 데이터를 Arduino로 전송 |- | D11 | MOSI |Arduino가 명령과 데이터를 RC522로 전송 |- | D10 | SDA |통신할 RC522를 선택하는 장치 선택 신호 |- | D9 | RST |RC522를 초기화하거나 재시작하는 리셋 신호 |- |연결 안함 |IRQ |카드 감지 등의 사건을 알리는 인터럽트 신호 |} === 다룰 때 유의사항 === * 사용 중, 리더에 전원 공급이 끊기면 보드를 다시 시작 해야 제대로 작동한다. == 코드 작성 예시 == === 일반 읽기 === MFRC522 라이브러리 설치가 필요하다.<syntaxhighlight lang="c++">#include <Arduino.h> #include <SPI.h> #include <MFRC522.h> constexpr byte SS_PIN = 10; constexpr byte RST_PIN = 9; MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); Serial.println(F("RFID UID Reader Ready")); } void loop() { if (!mfrc522.PICC_IsNewCardPresent()) { return; } if (!mfrc522.PICC_ReadCardSerial()) { mfrc522.PCD_AntennaOff(); delay(10); mfrc522.PCD_AntennaOn(); return; } Serial.print(F("UID: ")); for (byte i = 0; i < mfrc522.uid.size; i++) { if (mfrc522.uid.uidByte[i] < 0x10) { Serial.print('0'); } Serial.print(mfrc522.uid.uidByte[i], HEX); if (i < mfrc522.uid.size - 1) { Serial.print(' '); } } Serial.println(); Serial.print(F("Type: ")); Serial.println(mfrc522.PICC_GetTypeName( mfrc522.PICC_GetType(mfrc522.uid.sak))); mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); Serial.println(); delay(200); }</syntaxhighlight> === 읽고 쓰기 === <syntaxhighlight lang="c++">#include <SPI.h> #include <MFRC522.h> #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); // ====================================================== // 저장할 태그 정보 // ====================================================== byte lastUID[10]; byte lastUIDSize = 0; byte lastBlock4[16]; bool hasLastTag = false; // ====================================================== // 모드 // ====================================================== enum Mode { READ_MODE, COMMAND_MODE, WRITE_MODE }; Mode mode = READ_MODE; // ====================================================== // UID 출력 // ====================================================== void printUID(byte *uid, byte uidSize) { Serial.print("UID : "); for (byte i = 0; i < uidSize; i++) { if (uid[i] < 0x10) Serial.print("0"); Serial.print(uid[i], HEX); if (i < uidSize - 1) Serial.print(" "); } Serial.println(); } // ====================================================== // UID 저장 // ====================================================== void saveUID() { lastUIDSize = mfrc522.uid.size; for (byte i = 0; i < lastUIDSize; i++) { lastUID[i] = mfrc522.uid.uidByte[i]; } } // ====================================================== // 블록 데이터 출력 // ====================================================== void printBlock(byte *buffer) { for (byte i = 0; i < 16; i++) { if (buffer[i] < 0x10) Serial.print("0"); Serial.print(buffer[i], HEX); Serial.print(" "); } Serial.println(); } // ====================================================== // 블록 4를 문자열로 출력 // ====================================================== void printBlockString(byte *buffer) { Serial.print("문자열 : "); for (byte i = 0; i < 16; i++) { if (buffer[i] >= 32 && buffer[i] <= 126) Serial.print((char)buffer[i]); } Serial.println(); } // ====================================================== // 기본 MIFARE Key // ====================================================== void setupDefaultKey(MFRC522::MIFARE_Key &key) { for (byte i = 0; i < 6; i++) { key.keyByte[i] = 0xFF; } } // ====================================================== // 태그 제거 대기 // ====================================================== void waitCardRemoval() { Serial.println(); Serial.println("태그를 떼세요..."); while (mfrc522.PICC_IsNewCardPresent()) { delay(100); } delay(300); } // ====================================================== // 명령 메뉴 // ====================================================== void showMenu() { Serial.println(); Serial.println("=============================="); Serial.println("무엇을 할까요?"); Serial.println(); Serial.println("r : 다음 태그 읽기"); Serial.println("w : 저장된 데이터 쓰기"); Serial.println("=============================="); } // ====================================================== // 태그 읽기 // ====================================================== void readTag() { Serial.println(); Serial.println("=============================="); Serial.println("태그를 대세요..."); Serial.println("=============================="); // 태그 대기 while (!mfrc522.PICC_IsNewCardPresent()) { delay(50); } // 태그 읽기 if (!mfrc522.PICC_ReadCardSerial()) { Serial.println("태그를 읽을 수 없습니다."); return; } Serial.println(); Serial.println("===== 태그 정보 ====="); // ---------------------------------------------------- // UID // ---------------------------------------------------- printUID( mfrc522.uid.uidByte, mfrc522.uid.size ); // UID 저장 saveUID(); // ---------------------------------------------------- // 카드 종류 // ---------------------------------------------------- MFRC522::PICC_Type piccType; piccType = mfrc522.PICC_GetType( mfrc522.uid.sak ); Serial.print("카드 종류 : "); Serial.println( mfrc522.PICC_GetTypeName(piccType) ); // ---------------------------------------------------- // UID 크기 // ---------------------------------------------------- Serial.print("UID 크기 : "); Serial.print(mfrc522.uid.size); Serial.println(" bytes"); // ---------------------------------------------------- // UID 변경 가능 여부 안내 // ---------------------------------------------------- Serial.println(); if ( piccType == MFRC522::PICC_TYPE_MIFARE_MINI || piccType == MFRC522::PICC_TYPE_MIFARE_1K || piccType == MFRC522::PICC_TYPE_MIFARE_4K ) { Serial.println( "UID : MIFARE Classic 계열" ); Serial.println( "UID 변경 : 일반 태그에서는 불가능" ); Serial.println( "※ CUID/UID-changeable 태그 여부는 별도 확인 필요" ); } else { Serial.println( "UID 변경 : 이 예제에서는 지원하지 않음" ); } // ---------------------------------------------------- // 블록 4 읽기 // ---------------------------------------------------- byte block = 4; byte buffer[18]; byte size = sizeof(buffer); MFRC522::MIFARE_Key key; setupDefaultKey(key); // 인증 MFRC522::StatusCode status; status = mfrc522.PCD_Authenticate( MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid) ); if (status != MFRC522::STATUS_OK) { Serial.print("블록 4 인증 실패 : "); Serial.println( mfrc522.GetStatusCodeName(status) ); } else { // 읽기 status = mfrc522.MIFARE_Read( block, buffer, &size ); if (status != MFRC522::STATUS_OK) { Serial.print("블록 4 읽기 실패 : "); Serial.println( mfrc522.GetStatusCodeName(status) ); } else { // 데이터 저장 for (byte i = 0; i < 16; i++) { lastBlock4[i] = buffer[i]; } Serial.println(); Serial.println("===== 블록 4 ====="); printBlock(buffer); printBlockString(buffer); hasLastTag = true; } } // 카드 종료 mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); // 태그 제거 waitCardRemoval(); // 메뉴 showMenu(); mode = COMMAND_MODE; } // ====================================================== // 블록 4 쓰기 // ====================================================== void writeBlock4() { if (!hasLastTag) { Serial.println(); Serial.println("저장된 태그 데이터가 없습니다."); mode = COMMAND_MODE; showMenu(); return; } Serial.println(); Serial.println("=============================="); Serial.println("===== 쓰기 모드 ====="); Serial.println("=============================="); Serial.println("저장된 데이터:"); printBlock(lastBlock4); printBlockString(lastBlock4); Serial.println(); Serial.println("새 태그를 대세요..."); // ---------------------------------------------------- // 새 태그 대기 // ---------------------------------------------------- while (!mfrc522.PICC_IsNewCardPresent()) { delay(50); } if (!mfrc522.PICC_ReadCardSerial()) { Serial.println("태그를 읽을 수 없습니다."); return; } Serial.println(); Serial.println("새 태그 감지!"); printUID( mfrc522.uid.uidByte, mfrc522.uid.size ); // ---------------------------------------------------- // 카드 종류 // ---------------------------------------------------- MFRC522::PICC_Type piccType; piccType = mfrc522.PICC_GetType( mfrc522.uid.sak ); Serial.print("카드 종류 : "); Serial.println( mfrc522.PICC_GetTypeName(piccType) ); // ---------------------------------------------------- // 블록 4 인증 // ---------------------------------------------------- byte block = 4; MFRC522::MIFARE_Key key; setupDefaultKey(key); MFRC522::StatusCode status; status = mfrc522.PCD_Authenticate( MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid) ); if (status != MFRC522::STATUS_OK) { Serial.print("인증 실패 : "); Serial.println( mfrc522.GetStatusCodeName(status) ); mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); return; } // ---------------------------------------------------- // 블록 4 쓰기 // ---------------------------------------------------- status = mfrc522.MIFARE_Write( block, lastBlock4, 16 ); if (status != MFRC522::STATUS_OK) { Serial.print("쓰기 실패 : "); Serial.println( mfrc522.GetStatusCodeName(status) ); } else { Serial.println(); Serial.println("******************************"); Serial.println("쓰기 성공!"); Serial.println("******************************"); } // 카드 종료 mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); waitCardRemoval(); showMenu(); mode = COMMAND_MODE; } // ====================================================== // SETUP // ====================================================== void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); delay(100); Serial.println(); Serial.println("================================"); Serial.println(" RC522 RFID 리더"); Serial.println("================================"); Serial.println(); Serial.println("준비 완료!"); Serial.println("첫 번째 태그를 대세요."); } // ====================================================== // LOOP // ====================================================== void loop() { // ---------------------------------------------------- // 태그 읽기 // ---------------------------------------------------- if (mode == READ_MODE) { readTag(); } // ---------------------------------------------------- // 명령 입력 // ---------------------------------------------------- else if (mode == COMMAND_MODE) { if (Serial.available()) { char command = Serial.read(); // 엔터 무시 if ( command == '\n' || command == '\r' ) { return; } // ---------------------------------------------- // r = 읽기 // ---------------------------------------------- if ( command == 'r' || command == 'R' ) { Serial.println(); Serial.println("'r' → 다음 태그 읽기"); mode = READ_MODE; } // ---------------------------------------------- // w = 쓰기 // ---------------------------------------------- else if ( command == 'w' || command == 'W' ) { Serial.println(); Serial.println("'w' → 저장된 데이터 쓰기"); mode = WRITE_MODE; } else { Serial.println(); Serial.println("r 또는 w를 입력하세요."); showMenu(); } } } // ---------------------------------------------------- // 쓰기 // ---------------------------------------------------- else if (mode == WRITE_MODE) { writeBlock4(); } }</syntaxhighlight>
요약:
학교의 모든 지식. SMwiki에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 라이선스로 배포된다는 점을 유의해 주세요(자세한 내용에 대해서는
학교의 모든 지식. SMwiki:저작권
문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요.
또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다.
저작권이 있는 내용을 허가 없이 저장하지 마세요!
취소
편집 도움말
(새 창에서 열림)
이 문서에 포함된 문서:
틀:아두이노
(
편집
)
검색
검색
아두이노:RFID(13.56MHz)
편집하기
새 주제