JRD-100 - UHF-RFID Arduino Модуль

Reading time: 5 minutes.

17 August 2021

Table of Content

О модуле

JRD-100 - это модуль беспроводного считывания меток сверхвысокой частоты (UHF).

Данное решение позволяет считывать сразу до 50 радиометок в секунду. Внутренний буфер рассчитан на 200 единиц. Конструкция модуля позволяет применять передатчик мощностью 100 мВт, что обеспечивает производительную, энергоэффективную работу в радиусе более 1.5 метра.

Спецификации JRD-100

  • Расстояние считывания тегов: 1-2,5 м
  • Расстояние записи: 10 см
  • Рабочее напряжение: 3,3 - 5 В
  • Диапазон рабочих частот: 840-960 МГц
  • Выходная мощность: 18-26 dBm
  • Интерфейс: TTL UART
  • Стабильное и чувствительное считывание меток
  • Поддержка протоколов беспроводного интерфейса
    • EPCglobal UHF Class 1 Gen 2
    • ISO 18000-6C.

Сферы применения

Применяются системы дальней идентификации во множестве областей. Модуль подходит для управления складской логистикой, автоматизированной розничной торговли и любых систем учета и безопасности.

Распиновка JRD-100

Подключение UHF-RFID по UART

Подключается JRD-100 “Plug & Play” через UART-интерфейс. Управление передачей данных происходит при помощи набора AT-команд.

Подключите пин к 5V, а также установите пару конденсаторов на питание.

Код

В публичном доступе нет мануалов и примеров интеграции модуля, поэтому мы сами разработали интеграцию UHF-RFID JRD-100 и Arduino.

Код работает почти на любом микроконтроллере.

В начале задан массив команд, для управления модулем. В теле программы по индексу вызываются команды:

#include <Arduino.h>
#include <HardwareSerial.h>

HardwareSerial Serial2(PA3, PA2);
bool DEBUG = true;

const uint8_t RFID_cmdnub[39][26] =
{
{0xBB, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x7E,}, //0. Hardware version
{0xBB, 0x00, 0x03, 0x00, 0x01, 0x01, 0x05, 0x7E,}, //1. Software version
{0xBB, 0x00, 0x03, 0x00, 0x01, 0x02, 0x06, 0x7E,}, //2. manufacturers
{0xBB, 0x00, 0x22, 0x00, 0x00, 0x22, 0x7E,}, //3. Single polling instruction
{0xBB, 0x00, 0x27, 0x00, 0x03, 0x22, 0x27, 0x10, 0x83, 0x7E,}, //4. Multiple polling instructions
{0xBB, 0x00, 0x28, 0x00, 0x00, 0x28, 0x7E,}, //5. Stop multiple polling instructions
{ 0xBB, 0x00, 0x0C, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x20,
0x60, 0x00, 0x30, 0x75, 0x1F, 0xEB, 0x70, 0x5C, 0x59, 0x04,
0xE3, 0xD5, 0x0D, 0x70, 0xAD, 0x7E,
}, //6. Set the SELECT parameter instruction
{0xBB, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x7E,}, //7. Get the SELECT parameter
{0xBB, 0x00, 0x12, 0x00, 0x01, 0x01, 0x14, 0x7E,}, //8. Set the SELECT mode
{ 0xBB, 0x00, 0x39, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x08, 0x4D, 0x7E,
}, //9. Read label data storage area
{ 0xBB, 0x00, 0x49, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x04, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x71, 0x7E
}, //10. Write the label data store
{ 0xBB, 0x00, 0x82, 0x00, 0x07, 0x00, 0x00, 0xFF,
0xFF, 0x02, 0x00, 0x80, 0x09, 0x7E,
}, //11. Lock the LOCK label data store
{ 0xBB, 0x00, 0x65, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x67,
0x7E,
}, //12. Inactivate the kill tag
{0xBB, 0x00, 0x11, 0x00, 0x02, 0x00, 0xC0, 0xD3, 0x7E,}, //13. Set communication baud rate
{0xBB, 0x00, 0x0D, 0x00, 0x00, 0x0D, 0x7E,}, //14. Get parameters related to the Query command
{0xBB, 0x00, 0x0E, 0x00, 0x02, 0x10, 0x20, 0x40, 0x7E,}, //15. Set the Query parameter
{0xBB, 0x00, 0x07, 0x00, 0x01, 0x01, 0x09, 0x7E,}, //16. Set up work area
{0xBB, 0x00, 0x08, 0x00, 0x00, 0x08, 0x7E,}, //17. Acquire work locations
{0xBB, 0x00, 0xAB, 0x00, 0x01, 0x01, 0xAC, 0x7E,}, //18. Set up working channel
{0xBB, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0x7E,}, //19. Get the working channel
{0xBB, 0x00, 0xAD, 0x00, 0x01, 0xFF, 0xAD, 0x7E,}, //20. Set to automatic frequency hopping mode
{ 0xBB, 0x00, 0xA9, 0x00, 0x06, 0x05, 0x01, 0x02,
0x03, 0x04, 0x05, 0xC3, 0x7E,
}, //21. Insert the working channel
{0xBB, 0x00, 0xB7, 0x00, 0x00, 0xB7, 0x7E,}, //22. Acquire transmitting power
{0xBB, 0x00, 0xB6, 0x00, 0x02, 0x07, 0xD0, 0x8F, 0x7E,}, //23. Set the transmitting power
{0xBB, 0x00, 0xB0, 0x00, 0x01, 0xFF, 0xB0, 0x7E,}, //24. Set up transmitting continuous carrier
{0xBB, 0x00, 0xF1, 0x00, 0x00, 0xF1, 0x7E,}, //25. Gets the receiving demodulator parameters
{0xBB, 0x00, 0xF0, 0x00, 0x04, 0x03, 0x06, 0x01, 0xB0, 0xAE, 0x7E,}, //26. Set the receiving demodulator parameters
{0xBB, 0x00, 0xF2, 0x00, 0x00, 0xF2, 0x7E,}, //27. Test the RF input block signal
{0xBB, 0x00, 0xF3, 0x00, 0x00, 0xF3, 0x7E,}, //28. Test the RSSI signal at the RF input
{0x00},
{0xBB, 0x00, 0x17, 0x00, 0x00, 0x17, 0x7E,}, //30. Module hibernation
{0xBB, 0x00, 0x1D, 0x00, 0x01, 0x02, 0x20, 0x7E,}, //31. Idle hibernation time of module
{0xBB, 0x00, 0x04, 0x00, 0x03, 0x01, 0x01, 0x03, 0x0C, 0x7E,}, //32. The IDLE mode
{0xBB, 0x00, 0xE1, 0x00, 0x05, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xE4, 0x7E,}, //33.NXP G2X label supports ReadProtect/Reset ReadProtect command
{0xBB, 0x00, 0xE3, 0x00, 0x05, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0xE7, 0x7E,}, //34. The NXP G2X label supports the CHANGE EAS directive
{0xBB, 0x00, 0xE4, 0x00, 0x00, 0xE4, 0x7E,}, //35. The NXP G2X tag supports the EAS_ALARM directive
{0xBB, 0x00, 0xE0, 0x00, 0x06, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xE4, 0x7E,}, //36.NXP G2X label 16bits config-word
{ 0xBB, 0x00, 0xE5, 0x00, 0x08, 0x00, 0x00, 0xFF,
0xFF, 0x01, 0x01, 0x40, 0x00, 0x2D, 0x7E,
}, //37.Impinj Monza 4 Qt tags support Qt instructions
{ 0xBB, 0x00, 0xD3, 0x00, 0x0B, 0x00, 0x00, 0xFF,
0xFF, 0x01, 0x03, 0x00, 0x00, 0x01, 0x07, 0x00, 0xE8, 0x7E,
}, //38.The BlockPermalock directive permanently locks blocks of a user’s Block

};

void Sendcommand(uint8_t com_nub)
{
uint8_t b = 0;
while (RFID_cmdnub[com_nub][b] != 0x7E)
{
Serial2.write(RFID_cmdnub[com_nub][b]);
if(DEBUG) {
Serial.print(" 0x");
Serial.print(RFID_cmdnub[com_nub][b], HEX);
}
b++;
}
Serial2.write(0x7E);
Serial2.write("\n\r");
Serial.println();
}
uint8_t DATA_I[256];

void Readcallback()
{
uint8_t DATA_I_NUB = 0;
while(!Serial2.available());
while (Serial2.available())
{
delay(2);
DATA_I[DATA_I_NUB] = Serial2.read();
if (DEBUG == 1)
{
if(DATA_I[DATA_I_NUB] < 16) {
Serial.print(" 0x0");
} else {
Serial.print(" 0x");
}
Serial.print(DATA_I[DATA_I_NUB], HEX);
}
DATA_I_NUB++;
}
Serial.println();
}
/* code */
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("begin of UHF-Reader");
Serial2.begin(115200);

}

void loop() {
// put your main code here, to run repeatedly:
for (size_t i = 0; i < 10; i++) {
Serial.println("Single polling:");
Sendcommand(3);
Serial.println("Recieving:");
Readcallback();
// Serial.println();
Serial.println("Requesting data:");
Sendcommand(9);
Serial.println("Recieving data:");
Readcallback();
delay(3000);
Serial.println();
}
// Serial.println("End of programm");
// delay(5000);
}