风筝
发表于: 2020-2-4 15:14:55 | 显示全部楼层

Seeedstudio的RDM630和RDM6300是两种不同类型的RFID读卡器,即使它们经常被混淆在一起。除了相似的名称外,造成混淆的另一个原因可能是它们使用相同的引脚布局和传输协议。据我所知,除了相同的技术功能外,它们之间没有其他共同之处。通常,需要以约10-15美元的价格购买Seeedstudio的RDM630和以1-3美元的价格购买RDM6300。我认为,RDM630更坚固耐用并允许更长的读取距离。


两种读卡器均工作主125 kHz的频率,并能够读取EM4100兼容的标签。其他标签(例如EM4305标签)在这些读卡器上不起作用。


在本篇文章中,我们主要介绍了如何将RDM6300和RDM630与Arduino Uno一起使用。幸运的是,两个RFID读卡器都通过串行连接使用相同的协议。结果,可以使用相同的源代码来使两个读卡器正常工作。因此,无论您是拥有RDM630还是RDM6300,如果想使其与Arduino一起使用,本文都可以使用。

rdm6300_and_rdm630.jpg


所需的材料清单:

–  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)。

pin_layout_rdm_630_6300.jpg

RDM630的引脚布局。


与Arduino Uno的连接方式:

在本文中,RDM630 / RDM6300的四个引脚连接到Arduino Uno。 Vcc连接到Arduino的5V引脚(红线),而GND则连接到Arduino的GND(黑线)。 TX引脚连接到数字引脚6(绿线)。本文不需要RX引脚,因为我们不会将数据发送到RFID模块。为了完整起见,RX连接到数字引脚8(黄线)。最后,将天线连接到ANT1和ANT2。

wiring_arduino_rdm630_rdm6300.jpg

Arduino Uno和RDM6300之间的接线。


示例源代码:

如前所述,两个模块都可以使用相同的源代码。当检测到RFID标签时,RDM630 / RDM6300发送一个14字节的帧:头[1字节]、数据[10字节]、校验和[2字节]和尾[1字节]。头(或前导符)始终为0x02。同样,尾部始终为0x03。数据字段包含ASCII编码的HEX值。有时,制造商倾向于将RFID标签数据字段分为两部分:版本和标签。因此,根据您的RFID标签类型,数据的前两个字节可能是版本,而其他8个字节可能是实际的RFID标签。我在源代码中考虑了这一点。为了从数据字段计算校验和,必须对所有数据条目执行XOR操作。

  1. #include <SoftwareSerial.h>
  2. 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)
  3. const int DATA_SIZE = 10; // 10byte data (2byte version + 8byte tag)
  4. const int DATA_VERSION_SIZE = 2; // 2byte version (actual meaning of these two bytes may vary)
  5. const int DATA_TAG_SIZE = 8; // 8byte tag
  6. const int CHECKSUM_SIZE = 2; // 2byte checksum
  7. SoftwareSerial ssrfid = SoftwareSerial(6,8);
  8. uint8_t buffer[BUFFER_SIZE]; // used to store an incoming data frame
  9. int buffer_index = 0;
  10. void setup() {
  11. Serial.begin(9600);

  12. ssrfid.begin(9600);
  13. ssrfid.listen();

  14. Serial.println("INIT DONE");
  15. }
  16. void loop() {
  17.   if (ssrfid.available() > 0){
  18.     bool call_extract_tag = false;
  19.    
  20.     int ssvalue = ssrfid.read(); // read
  21.     if (ssvalue == -1) { // no data was read
  22.       return;
  23.     }
  24.     if (ssvalue == 2) { // RDM630/RDM6300 found a tag => tag incoming
  25.       buffer_index = 0;
  26.     } else if (ssvalue == 3) { // tag has been fully transmitted      
  27.       call_extract_tag = true; // extract tag at the end of the function call
  28.     }
  29.     if (buffer_index >= BUFFER_SIZE) { // checking for a buffer overflow (It's very unlikely that an buffer overflow comes up!)
  30.       Serial.println("Error: Buffer overflow detected!");
  31.       return;
  32.     }
  33.    
  34.     buffer[buffer_index++] = ssvalue; // everything is alright => copy current value to buffer
  35.     if (call_extract_tag == true) {
  36.       if (buffer_index == BUFFER_SIZE) {
  37.         unsigned tag = extract_tag();
  38.       } else { // something is wrong... start again looking for preamble (value: 2)
  39.         buffer_index = 0;
  40.         return;
  41.       }
  42.     }   
  43.   }   
  44. }
  45. unsigned extract_tag() {
  46.     uint8_t msg_head = buffer[0];
  47.     uint8_t *msg_data = buffer + 1; // 10 byte => data contains 2byte version + 8byte tag
  48.     uint8_t *msg_data_version = msg_data;
  49.     uint8_t *msg_data_tag = msg_data + 2;
  50.     uint8_t *msg_checksum = buffer + 11; // 2 byte
  51.     uint8_t msg_tail = buffer[13];
  52.     // print message that was sent from RDM630/RDM6300
  53.     Serial.println("--------");
  54.     Serial.print("Message-Head: ");
  55.     Serial.println(msg_head);
  56.     Serial.println("Message-Data (HEX): ");
  57.     for (int i = 0; i < DATA_VERSION_SIZE; ++i) {
  58.       Serial.print(char(msg_data_version[i]));
  59.     }
  60.     Serial.println(" (version)");
  61.     for (int i = 0; i < DATA_TAG_SIZE; ++i) {
  62.       Serial.print(char(msg_data_tag[i]));
  63.     }
  64.     Serial.println(" (tag)");
  65.     Serial.print("Message-Checksum (HEX): ");
  66.     for (int i = 0; i < CHECKSUM_SIZE; ++i) {
  67.       Serial.print(char(msg_checksum[i]));
  68.     }
  69.     Serial.println("");
  70.     Serial.print("Message-Tail: ");
  71.     Serial.println(msg_tail);
  72.     Serial.println("--");
  73.     long tag = hexstr_to_value(msg_data_tag, DATA_TAG_SIZE);
  74.     Serial.print("Extracted Tag: ");
  75.     Serial.println(tag);
  76.     long checksum = 0;
  77.     for (int i = 0; i < DATA_SIZE; i+= CHECKSUM_SIZE) {
  78.       long val = hexstr_to_value(msg_data + i, CHECKSUM_SIZE);
  79.       checksum ^= val;
  80.     }
  81.     Serial.print("Extracted Checksum (HEX): ");
  82.     Serial.print(checksum, HEX);
  83.     if (checksum == hexstr_to_value(msg_checksum, CHECKSUM_SIZE)) { // compare calculated checksum to retrieved checksum
  84.       Serial.print(" (OK)"); // calculated checksum corresponds to transmitted checksum!
  85.     } else {
  86.       Serial.print(" (NOT OK)"); // checksums do not match
  87.     }
  88.     Serial.println("");
  89.     Serial.println("--------");
  90.     return tag;
  91. }
  92. long hexstr_to_value(char *str, unsigned int length) { // converts a hexadecimal value (encoded as ASCII string) to a numeric value
  93.   char* copy = malloc((sizeof(char) * length) + 1);
  94.   memcpy(copy, str, sizeof(char) * length);
  95.   copy[length] = '\0';
  96.   // the variable "copy" is a copy of the parameter "str". "copy" has an additional '\0' element to make sure that "str" is null-terminated.
  97.   long value = strtol(copy, NULL, 16);  // strtol converts a null-terminated string to a long value
  98.   free(copy); // clean up
  99.   return value;
  100. }
复制代码

执行源代码并在靠近天线的地方放置RFID标签,则Arduino IDE的串口监视器应输出以下内容:

serial_monitor_read_rdm6300_rdm630.jpg

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1483



手机版|

GMT+8, 2024-5-11 16:28 , Processed in 0.262568 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表