본문으로 이동
주 메뉴
주 메뉴
사이드바로 이동
숨기기
둘러보기
대문
최근 바뀜
임의의 문서로
미디어위키 도움말
특수 문서 목록
학교의 모든 지식. SMwiki
검색
검색
보이기
로그인
개인 도구
로그인
로그아웃한 편집자를 위한 문서
더 알아보기
기여
토론
아두이노:RFID(13.56MHz)
편집하기
문서
토론
한국어
읽기
편집
원본 편집
역사 보기
도구
도구
사이드바로 이동
숨기기
동작
읽기
편집
원본 편집
역사 보기
일반
여기를 가리키는 문서
가리키는 글의 최근 바뀜
파일 올리기
문서 정보
보이기
사이드바로 이동
숨기기
Sam
(
토론
|
기여
)
님의 2026년 9월 8일 (화) 07:17 판
(
→
연결 예시
)
(
차이
)
← 이전 판
|
최신판
(
차이
) |
다음 판 →
(
차이
)
경고: 이 문서의 오래된 판을 편집하고 있습니다.
이것을 게시하면, 이 판 이후로 바뀐 모든 편집이 사라집니다.
경고:
로그인하지 않았습니다. 편집을 하면 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 == 코드 작성 예시 == === 일반 읽기 === === 읽고 쓰기 === <syntaxhighlight lang="c++"> ```cpp #include <SPI.h> #include <MFRC522.h> // ======================================== // 핀 설정 // ======================================== constexpr uint8_t RST_PIN = 9; constexpr uint8_t SS_PIN = 10; constexpr uint8_t BUTTON_PIN = 2; // RC522 객체 MFRC522 mfrc522(SS_PIN, RST_PIN); // ======================================== // MIFARE Classic 설정 // ======================================== // MIFARE Classic 1K constexpr uint8_t TOTAL_BLOCKS = 64; // 한 블록은 16바이트 constexpr uint8_t BLOCK_SIZE = 16; // 기본 Key A MFRC522::MIFARE_Key key; // 읽어 둔 카드 데이터 byte cardData[TOTAL_BLOCKS][BLOCK_SIZE]; // 데이터를 읽었는지 여부 bool dataReady = false; // ======================================== // 초기화 // ======================================== void setup() { Serial.begin(9600); while (!Serial); // 버튼 설정 // 버튼을 누르면 LOW pinMode(BUTTON_PIN, INPUT_PULLUP); // SPI 시작 SPI.begin(); // RC522 초기화 mfrc522.PCD_Init(); // 기본 Key A = FF FF FF FF FF FF for (byte i = 0; i < 6; i++) { key.keyByte[i] = 0xFF; } Serial.println(F("================================")); Serial.println(F("RC522 RFID Reader / Writer")); Serial.println(F("================================")); Serial.println(F("READ mode")); Serial.println(F("Scan a MIFARE Classic card.")); } // ======================================== // 메인 루프 // ======================================== void loop() { // 새로운 카드가 없으면 대기 if (!mfrc522.PICC_IsNewCardPresent()) { return; } // 카드 선택 if (!mfrc522.PICC_ReadCardSerial()) { return; } // 카드 정보 출력 printCardInfo(); // 버튼 상태에 따라 동작 if (digitalRead(BUTTON_PIN) == LOW) { // ================================ // WRITE MODE // ================================ Serial.println(); Serial.println(F("[WRITE MODE]")); if (!dataReady) { Serial.println( F("No card data has been stored yet.") ); } else { writeCard(); } } else { // ================================ // READ MODE // ================================ Serial.println(); Serial.println(F("[READ MODE]")); readCard(); } // 카드 통신 종료 mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); Serial.println(); Serial.println(F("-------------------------------")); delay(1000); } // ======================================== // 카드 정보 출력 // ======================================== void printCardInfo() { MFRC522::PICC_Type piccType; piccType = mfrc522.PICC_GetType( mfrc522.uid.sak ); Serial.println(); Serial.println(F("===== CARD INFO =====")); // 카드 종류 Serial.print(F("Type : ")); Serial.println( mfrc522.PICC_GetTypeName(piccType) ); // SAK Serial.print(F("SAK : 0x")); if (mfrc522.uid.sak < 0x10) { Serial.print("0"); } Serial.println( mfrc522.uid.sak, HEX ); // UID 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 ); Serial.print(" "); } Serial.println(); // UID 길이 Serial.print(F("UID size : ")); Serial.print(mfrc522.uid.size); Serial.println(F(" bytes")); Serial.println(F("=====================")); } // ======================================== // 카드 읽기 // ======================================== void readCard() { MFRC522::PICC_Type piccType; piccType = mfrc522.PICC_GetType( mfrc522.uid.sak ); // MIFARE Classic인지 확인 if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) { Serial.println( F("This card is not a MIFARE Classic card.") ); return; } // MIFARE Classic 1K만 처리 if (piccType != MFRC522::PICC_TYPE_MIFARE_1K) { Serial.println( F("This example supports MIFARE Classic 1K.") ); return; } Serial.println(); Serial.println(F("Reading card...")); bool success = true; // MIFARE Classic 1K // 64 blocks = 16 sectors × 4 blocks for (byte block = 0; block < TOTAL_BLOCKS; block++) { // 블록 0은 UID/제조사 영역이므로 읽기만 함 // 섹터 트레일러(3, 7, 11, ...)는 // 인증키와 접근조건을 포함하므로 저장하지 않음 if (block % 4 == 3) { continue; } // 해당 섹터 인증 if (!authenticateBlock(block)) { Serial.print(F("Authentication failed: block ")); Serial.println(block); success = false; continue; } byte buffer[18]; byte size = sizeof(buffer); // 블록 읽기 MFRC522::StatusCode status; status = mfrc522.MIFARE_Read( block, buffer, &size ); if (status != MFRC522::STATUS_OK) { Serial.print(F("Read failed: block ")); Serial.println(block); success = false; continue; } // 읽은 데이터 저장 for (byte i = 0; i < BLOCK_SIZE; i++) { cardData[block][i] = buffer[i]; } // 시리얼 모니터에 출력 printBlock(block, buffer); } mfrc522.PCD_StopCrypto1(); if (success) { dataReady = true; Serial.println(); Serial.println( F("Card data stored in memory.") ); Serial.println( F("Press the button and scan another card to write.") ); } else { Serial.println(); Serial.println( F("Some blocks could not be read.") ); } } // ======================================== // 카드 쓰기 // ======================================== void writeCard() { MFRC522::PICC_Type piccType; piccType = mfrc522.PICC_GetType( mfrc522.uid.sak ); // MIFARE Classic 1K인지 확인 if (piccType != MFRC522::PICC_TYPE_MIFARE_1K) { Serial.println( F("Target card is not MIFARE Classic 1K.") ); return; } Serial.println(); Serial.println( F("Writing stored data to card...") ); bool success = true; for (byte block = 0; block < TOTAL_BLOCKS; block++) { // -------------------------------- // 쓰면 안 되는 영역 // -------------------------------- // Block 0: // UID + 제조사 정보 if (block == 0) { continue; } // Sector Trailer: // 3, 7, 11, 15, ... // // Key A // Access Bits // Key B // // 는 복사하지 않는다. if (block % 4 == 3) { continue; } // 해당 섹터 인증 if (!authenticateBlock(block)) { Serial.print( F("Authentication failed: block ") ); Serial.println(block); success = false; continue; } // 16바이트 데이터 기록 MFRC522::StatusCode status; status = mfrc522.MIFARE_Write( block, cardData[block], BLOCK_SIZE ); if (status != MFRC522::STATUS_OK) { Serial.print( F("Write failed: block ") ); Serial.println(block); success = false; continue; } Serial.print(F("Written block ")); Serial.println(block); } mfrc522.PCD_StopCrypto1(); Serial.println(); if (success) { Serial.println( F("Write completed.") ); } else { Serial.println( F("Write completed with errors.") ); } } // ======================================== // MIFARE 블록 인증 // ======================================== bool authenticateBlock(byte block) { 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(F("Authentication error: ")); Serial.println( mfrc522.GetStatusCodeName(status) ); return false; } return true; } // ======================================== // 블록 데이터 출력 // ======================================== void printBlock( byte block, byte *buffer ) { Serial.print(F("Block ")); if (block < 10) { Serial.print(" "); } Serial.print(block); Serial.print(F(" : ")); for (byte i = 0; i < BLOCK_SIZE; i++) { if (buffer[i] < 0x10) { Serial.print("0"); } Serial.print( buffer[i], HEX ); Serial.print(" "); } Serial.println(); } ``` </syntaxhighlight>
요약:
학교의 모든 지식. SMwiki에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 라이선스로 배포된다는 점을 유의해 주세요(자세한 내용에 대해서는
학교의 모든 지식. SMwiki:저작권
문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요.
또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다.
저작권이 있는 내용을 허가 없이 저장하지 마세요!
취소
편집 도움말
(새 창에서 열림)
이 문서에 포함된 문서:
틀:아두이노
(
편집
)
검색
검색
아두이노:RFID(13.56MHz)
편집하기
새 주제