RFID RDM6300 모듈의 기본 사용방법

RFID를 이용한 프로젝트를 진행하고 계신가요? 125kHz 주파수 대역에서 사용할 수 있는 가장 가성비 높은 모듈이 바로 RDM6300입니다. 이 글에서는 RDM6300의 기본 구성에서부터 아두이노와의 연결방법 그리고 간단한 예제코드까지 소개해 드리도록 하겠습니다. 이 글을 모두 읽으시면 RFID RDM6300 모듈의 기본 사용방법에 대해서 감을 잡으실 수 있을겁니다.

RFID RDM6300 모듈의 기본 사용방법

RDM6300은 125kHz 주파수 대역을 지원하는 RFID 모듈 중 하나입니다. 이 모듈은 125kHz 읽기전용 태그나 읽기/쓰기 카드로부터 값을 읽을 수 있습니다. 이 모듈이 제공하는 몇가지 특징은 다음과 같습니다.

  • 외부 안테나가 있습니다.
  • 최대 유효 거리 : 50mm
  • UART 인터페이스
  • 작은 크기

RDM6300모듈은 총 9개의 핀으로 구성되어 있으며 그 구성은 다음의 그림과 같습니다.

  • VCC : Module Power supply – 5V
  • GND : ground
  • RX : Data Receive pin
  • TX : Data Transmit pin
  • ANT1 : Antenna connection pin
  • ANT2 : Antenna connection pin
  • LED : LED pin – 이 핀은 주위에 태그가 없을 경우에는 HIGH값을 출력합니다. 주변에 태그가 위치하면 값이 LOW로 변경됩니다.

아두이노와 RDM6300 연결하기

그럼 아두이노와 RDM6300을 연결해 보도록 하겠습니다. 먼저 ANT1, ANT2번 핀은 코일형태로 제공된 안테나와 연결합니다. VCC는 5V 전원에, 그리고 GND는 아두이노의 GND에 각각 연결합니다. Rx핀은 8번핀에, Tx는 6번핀에 연결합니다. 연결을 그림으로 표현하면 다음과 같습니다.

코드 작성하기

다음과 같이 코드를 작성한 뒤 Arduino IDE를 이용해서 아두이노에 업로드 한 뒤 태그를 안테나 가까이에 가져가면 태그의 ID가 Serial Monitor에 출력되는 것을 확인할 수 있습니다.

/*
  RDM6300-125KHz-RFID
  modified on 20 Jan 2020
  by Amir Mohammad Shojaee @ Electropeak
  Home

  based on www.mschoeffler.de Arduino Examples
*/

#include <SoftwareSerial.h>

const int BUFFER_SIZE = 14; // RFID DATA FRAME FORMAT: 1byte head (value: 2), 10byte data (2byte version + 8byte tag), 2byte checksum, 1byte tail (value: 3)
const int DATA_SIZE = 10; // 10byte data (2byte version + 8byte tag)
const int DATA_VERSION_SIZE = 2; // 2byte version (actual meaning of these two bytes may vary)
const int DATA_TAG_SIZE = 8; // 8byte tag
const int CHECKSUM_SIZE = 2; // 2byte checksum

SoftwareSerial ssrfid = SoftwareSerial(6,8); 

uint8_t buffer[BUFFER_SIZE]; // used to store an incoming data frame 
int buffer_index = 0;

void setup() {
 Serial.begin(9600); 
 
 ssrfid.begin(9600);
 ssrfid.listen(); 
 
 Serial.println(" INIT DONE");
}

void loop() {
  if (ssrfid.available() > 0){
    bool call_extract_tag = false;
    
    int ssvalue = ssrfid.read(); // read 
    if (ssvalue == -1) { // no data was read
      return;
    }

    if (ssvalue == 2) { // RDM630/RDM6300 found a tag => tag incoming 
      buffer_index = 0;
    } else if (ssvalue == 3) { // tag has been fully transmitted       
      call_extract_tag = true; // extract tag at the end of the function call
    }

    if (buffer_index >= BUFFER_SIZE) { // checking for a buffer overflow (It's very unlikely that an buffer overflow comes up!)
      Serial.println("Error: Buffer overflow detected! ");
      return;
    }
    
    buffer[buffer_index++] = ssvalue; // everything is alright => copy current value to buffer

    if (call_extract_tag == true) {
      if (buffer_index == BUFFER_SIZE) {
        unsigned tag = extract_tag();
      } else { // something is wrong... start again looking for preamble (value: 2)
        buffer_index = 0;
        return;
      }
    }    
  }    
}

unsigned extract_tag() {
    uint8_t msg_head = buffer[0];
    uint8_t *msg_data = buffer + 1; // 10 byte => data contains 2byte version + 8byte tag
    uint8_t *msg_data_version = msg_data;
    uint8_t *msg_data_tag = msg_data + 2;
    uint8_t *msg_checksum = buffer + 11; // 2 byte
    uint8_t msg_tail = buffer[13];

    for (int i = 0; i < DATA_TAG_SIZE; ++i) {
      Serial.print(char(msg_data_tag[i]));
    }
    Serial.println("");

    long tag = hexstr_to_value(msg_data_tag, DATA_TAG_SIZE);
    return tag;

}
long hexstr_to_value(char *str, unsigned int length) { // converts a hexadecimal value (encoded as ASCII string) to a numeric value
  char* copy = malloc((sizeof(char) * length) + 1); 
  memcpy(copy, str, sizeof(char) * length);
  copy[length] = '\0'; 
  // the variable "copy" is a copy of the parameter "str". "copy" has an additional '\0' element to make sure that "str" is null-terminated.
  long value = strtol(copy, NULL, 16);  // strtol converts a null-terminated string to a long value
  free(copy); // clean up 
  return value;
}

Reference

Leave a Comment