Checker
17.11.28
요즘은 문서작업 할 것이 많아 바쁘네요. 작업에 진전이 그다지 없었습니다.
시간이 많지 않아서 RC522 쓰기를 이용해 타입을 구분해보는 작업을 하려고 합니다.
우선 모듈을 연결하고 태그를 2개 준비했습니다.
소스코드는 RC522 라이브러리에서 가져왔습니다.
코드를 대강 분석해보면 RFID TAG의 어느파트에 데이터를 쓰는지 알 수 있습니다.
readBytesUntil 은 해당 문자가 나올때까지 데이터를 읽는 함수인데, 이 녀석을 이용하여 시리얼 통신에서 보낸 ‘#’ 문자를 포함한 데이터를 버퍼에 담고, 그 데이터를 RFID TAG에 쓰는 방식입니다. 저는 RFID 타입 파트를 1번 블럭주소에 입력했고
RFID 옵션 파트를 4번에 입력했습니다.
** 코드를 보면 블럭주소 1에만 입력하는게 아니라 2에도 하는것처럼 보이는데, readBytesUntil() 에서 받는 버퍼는 34바이트 배열이고 write 할때는 16바이트 입니다. 1번 블럭에 16바이트를 쓰고 이후에 2번 블럭에 이어서 쓰는 것이라서 length를 구한 후 빈공간을 공란으로 채워서 1,2에 담는 것입니다.**
#include <SPI.h> #include <MFRC522.h> constexpr uint8_t RST_PIN = 9; // Configurable, see typical pin layout above constexpr uint8_t 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 SPI.begin(); // Init SPI bus mfrc522.PCD_Init(); // Init MFRC522 card Serial.println(F("Write personal data on a MIFARE PICC ")); } void loop() { // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory. MFRC522::MIFARE_Key key; for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; // Look for new cards if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } // Select one of the cards if ( ! mfrc522.PICC_ReadCardSerial()) { return; } Serial.print(F("Card UID:")); //Dump UID for (byte i = 0; i < mfrc522.uid.size; i++) { Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(mfrc522.uid.uidByte[i], HEX); } Serial.print(F(" PICC type: ")); // Dump PICC type MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); Serial.println(mfrc522.PICC_GetTypeName(piccType)); byte buffer[34]; byte block; MFRC522::StatusCode status; byte len; Serial.setTimeout(20000L) ; // wait until 20 seconds for input from serial // Ask personal data: Family name Serial.println(F("RFID 타입을 입력하세요. 마지막에 '#'을 붙이세요")); len = Serial.readBytesUntil('#', (char *) buffer, 30) ; // read family name from serial for (byte i = len; i < 30; i++) buffer[i] = ' '; // pad with spaces block = 1; //Serial.println(F("Authenticating using key A...")); status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid)); if (status != MFRC522::STATUS_OK) { Serial.print(F("PCD_Authenticate() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } else Serial.println(F("PCD_Authenticate() success: ")); // Write block status = mfrc522.MIFARE_Write(block, buffer, 16); if (status != MFRC522::STATUS_OK) { Serial.print(F("MIFARE_Write() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } else Serial.println(F("MIFARE_Write() success: ")); block = 2; //Serial.println(F("Authenticating using key A...")); status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid)); if (status != MFRC522::STATUS_OK) { Serial.print(F("PCD_Authenticate() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } // Write block status = mfrc522.MIFARE_Write(block, &buffer[16], 16); if (status != MFRC522::STATUS_OK) { Serial.print(F("MIFARE_Write() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } else Serial.println(F("MIFARE_Write() success: ")); Serial.println(F("RIFD 옵션을 입력하세요. 마지막에 '#'을 붙이세요")); len = Serial.readBytesUntil('#', (char *) buffer, 20) ; // read first name from serial for (byte i = len; i < 20; i++) buffer[i] = ' '; // pad with spaces block = 4; //Serial.println(F("Authenticating using key A...")); status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid)); if (status != MFRC522::STATUS_OK) { Serial.print(F("PCD_Authenticate() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } // Write block status = mfrc522.MIFARE_Write(block, buffer, 16); if (status != MFRC522::STATUS_OK) { Serial.print(F("MIFARE_Write() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } else Serial.println(F("MIFARE_Write() success: ")); block = 5; //Serial.println(F("Authenticating using key A...")); status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid)); if (status != MFRC522::STATUS_OK) { Serial.print(F("PCD_Authenticate() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } // Write block status = mfrc522.MIFARE_Write(block, &buffer[16], 16); if (status != MFRC522::STATUS_OK) { Serial.print(F("MIFARE_Write() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } else Serial.println(F("MIFARE_Write() success: ")); Serial.println(" "); mfrc522.PICC_HaltA(); // Halt PICC mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD } |
위의 코드를 이용하여 두개의 태그를
타입 : A / 옵션 : TAEWOO
타입 : B / 옵션 : EXERCISE
라고 입력했습니다.
아래는 읽기 라이브러리 소스코드 입니다.
#include <SPI.h> #include <MFRC522.h> constexpr uint8_t RST_PIN = 9; // Configurable, see typical pin layout above constexpr uint8_t 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 SPI.begin(); // Init SPI bus mfrc522.PCD_Init(); // Init MFRC522 card Serial.println(F("Read personal data on a MIFARE PICC:")); //shows in serial that it is ready to read } //*****************************************************************************************// void loop() { // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory. MFRC522::MIFARE_Key key; for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; //some variables we need byte block; byte len; MFRC522::StatusCode status; //------------------------------------------- // Look for new cards if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } // Select one of the cards if ( ! mfrc522.PICC_ReadCardSerial()) { return; } Serial.println(F("**Card Detected:**")); //------------------------------------------- mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid)); //dump some details about the card //mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); //uncomment this to see all blocks in hex //---------------------------------------- 타입얻기 byte buffer1[18]; block = 1; len = 18; status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid)); //line 834 if (status != MFRC522::STATUS_OK) { Serial.print(F("Authentication failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_Read(block, buffer1, &len); if (status != MFRC522::STATUS_OK) { Serial.print(F("Reading failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } // 타입 프린트 하기 Serial.print(F("타입 : ")); for (uint8_t i = 0; i < 16; i++) { if (buffer1[i] != 32) { // 32가 ' ' 공란의 바이트 값 Serial.write(buffer1[i]); } } Serial.println(); //------------------------------------------- byte buffer2[18]; block = 4; //------------------------------------------- 옵션 얻기 status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid)); //line 834 of MFRC522.cpp file if (status != MFRC522::STATUS_OK) { Serial.print(F("Authentication failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_Read(block, buffer2, &len); if (status != MFRC522::STATUS_OK) { Serial.print(F("Reading failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } //옵션 프린트하기 Serial.print("옵션 : "); for (uint8_t i = 0; i < 16; i++) { if (buffer2[i] != 32) { Serial.write(buffer2[i]); } } //---------------------------------------- Serial.println(F("\n**End Reading**\n")); delay(1000); //change value if you want to read cards faster mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); } //***************************************************************************************// |
위의 코드로 리딩을 해보니 결과는 이렇습니다. 옵션: 하고 왜 줄 바꿈이 일어나는지는 잘 모르겠습니다. 시리얼 모니터에서 텍스트를 보낼 때, 캐리지 리턴, 라인피드가 입력돼서 그렇네요.
아래와 같이 코드를 마구잡이로 수정해서 태그의 값에 따라서 분기를 줬습니다.
String buffer1Str;
Serial.print(F("타입 : ")); for (uint8_t i = 0; i < 16; i++) { if (buffer1[i] != 32) { // 32가 ' ' 공란의 바이트 값 Serial.write(buffer1[i]); } else { buffer1[i] = '\0'; buffer1Str = String((char*)buffer1); break; } } Serial.println(); if (buffer1Str.equals("A")) { Serial.println(F("타입 A 입니다.")); } else if (buffer1Str.equals("B")){ Serial.println(F("타입 B 입니다.")); } |
결과화면입니다. 이제 RC522를 통해 분기를 줄 수 있네요.