|
Seeedstudio的RDM630和RDM6300是两种不同类型的RFID读卡器,即使它们经常被混淆在一起。除了相似的名称外,造成混淆的另一个原因可能是它们使用相同的引脚布局和传输协议。据我所知,除了相同的技术功能外,它们之间没有其他共同之处。通常,需要以约10-15美元的价格购买Seeedstudio的RDM630和以1-3美元的价格购买RDM6300。我认为,RDM630更坚固耐用并允许更长的读取距离。
两种读卡器均工作主125 kHz的频率,并能够读取EM4100兼容的标签。其他标签(例如EM4305标签)在这些读卡器上不起作用。
在本篇文章中,我们主要介绍了如何将RDM6300和RDM630与Arduino Uno一起使用。幸运的是,两个RFID读卡器都通过串行连接使用相同的协议。结果,可以使用相同的源代码来使两个读卡器正常工作。因此,无论您是拥有RDM630还是RDM6300,如果想使其与Arduino一起使用,本文都可以使用。
所需的材料清单: – Arduino Uno开发板 – 跳线 – Seeedstudio RDM630读卡器 – RDM6300读卡器 – 125 kHz标签
RDM630 / RDM6300的引脚分布: RDM630 / RDM6300总共有9个引脚,其中有两组Vcc和GND。 Vcc引脚连接到5V DC。 ANT1和ANT2用于将天线连接到板上。通常,RDM630和RDM6300已经带有天线。尽管如此,仍可以将天线切换到例如定制天线。 TX用于发送数据,RX用于接收数据。 LED引脚可用于快速查找是否成功读取了RFID标签。如果不存在RFID标签,则LED引脚处于5V(HIGH)。如果读取到RFID,LED引脚会在一段时间内变为0V(LOW)。
RDM630的引脚布局。
与Arduino Uno的连接方式: 在本文中,RDM630 / RDM6300的四个引脚连接到Arduino Uno。 Vcc连接到Arduino的5V引脚(红线),而GND则连接到Arduino的GND(黑线)。 TX引脚连接到数字引脚6(绿线)。本文不需要RX引脚,因为我们不会将数据发送到RFID模块。为了完整起见,RX连接到数字引脚8(黄线)。最后,将天线连接到ANT1和ANT2。
Arduino Uno和RDM6300之间的接线。
示例源代码: 如前所述,两个模块都可以使用相同的源代码。当检测到RFID标签时,RDM630 / RDM6300发送一个14字节的帧:头[1字节]、数据[10字节]、校验和[2字节]和尾[1字节]。头(或前导符)始终为0x02。同样,尾部始终为0x03。数据字段包含ASCII编码的HEX值。有时,制造商倾向于将RFID标签数据字段分为两部分:版本和标签。因此,根据您的RFID标签类型,数据的前两个字节可能是版本,而其他8个字节可能是实际的RFID标签。我在源代码中考虑了这一点。为了从数据字段计算校验和,必须对所有数据条目执行XOR操作。 - #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];
- // print message that was sent from RDM630/RDM6300
- Serial.println("--------");
- Serial.print("Message-Head: ");
- Serial.println(msg_head);
- Serial.println("Message-Data (HEX): ");
- for (int i = 0; i < DATA_VERSION_SIZE; ++i) {
- Serial.print(char(msg_data_version[i]));
- }
- Serial.println(" (version)");
- for (int i = 0; i < DATA_TAG_SIZE; ++i) {
- Serial.print(char(msg_data_tag[i]));
- }
- Serial.println(" (tag)");
- Serial.print("Message-Checksum (HEX): ");
- for (int i = 0; i < CHECKSUM_SIZE; ++i) {
- Serial.print(char(msg_checksum[i]));
- }
- Serial.println("");
- Serial.print("Message-Tail: ");
- Serial.println(msg_tail);
- Serial.println("--");
- long tag = hexstr_to_value(msg_data_tag, DATA_TAG_SIZE);
- Serial.print("Extracted Tag: ");
- Serial.println(tag);
- long checksum = 0;
- for (int i = 0; i < DATA_SIZE; i+= CHECKSUM_SIZE) {
- long val = hexstr_to_value(msg_data + i, CHECKSUM_SIZE);
- checksum ^= val;
- }
- Serial.print("Extracted Checksum (HEX): ");
- Serial.print(checksum, HEX);
- if (checksum == hexstr_to_value(msg_checksum, CHECKSUM_SIZE)) { // compare calculated checksum to retrieved checksum
- Serial.print(" (OK)"); // calculated checksum corresponds to transmitted checksum!
- } else {
- Serial.print(" (NOT OK)"); // checksums do not match
- }
- Serial.println("");
- Serial.println("--------");
- 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;
- }
复制代码
执行源代码并在靠近天线的地方放置RFID标签,则Arduino IDE的串口监视器应输出以下内容:
|