Зачем?
UHF Reader позволяет обеспечить контроль за метками на расстоянии до 10 метров, что дает интересные перспективы различного использования. Самый очевидный – это контроль пропуска автотранспорта. Но можно придумать и более экзотичные варианты: контроль за оборудованием в гараже/сарае. Едва ли воришка додумается, что к велосипеду (чемодану с инструментом) приклеен RFID tag и он способен сообщить о своем отбытии за пределы наблюдаемого периметра.
NodeJS + RaspberryPI – гибкий и дешевый сервер обработки данных и управления периферией.
Оборудование
Я взял на тесты CF-RU5109 (CHAFON), поддерживающий соединение по RS232, RS485, Wiegand, TCP. (TCP мне нужен только для удобства тестирования оборудования)
Страница модели — CF-RU5109
Метки — rfid gen2 uhf paper tag with Alien H3 chip
Дальность считывания. Эксперименты показали, что считывание зависит от активности метки (ее перемещении в пространстве). Пассивно лежащая метка считывается уверенно на расстоянии 3 метра, слабо двигающаяся — 5-5.5 метров, на расстоянии 8 метров приходилось активно размахивать рукой. У моего ридера встроенная антенна на 9dbi.
Софт
К Ридеру прилагается SDK, подробное описание команд, несколько тестовых программ под Windows. Я использую этот софт только, чтобы попробовать поработать с Ридером, — в работе с NodeJS нам от него ничего не нужно.
Подключаем к Node
tcpclient.prototype.Start = function () {
client = new net.Socket();
client.setEncoding('ascii');
client.connect(6000, '192.168.0.190', function() {
});
client.on('connect', function(data) {
console.log('UHF reader connected');
var bytes = Buffer.from([0x04, 0xff, 0x21, 0x19, 0x95], "ascii");
client.write(bytes);
client.on('data', function(data) {
console.log('UHF reader respond:');
var buffer = Buffer.from(data, "ascii");
console.log(buffer);
});
});
client.on('close', function() {
console.log('UHF reader - connection closed');
});
client.on('error', function(err) {
console.log(err)
});
};
tcpclient.prototype.Write = function (req) {
var bytes = new Buffer(req, "ascii");
console.log(bytes);
client.write(bytes);
};
Из мануала. Командный блок структурирован так:
Len, Adr, Cmd, Data[], LSB-CRC16, MSB-CRC16
Последние два байта – это контрольная сумма CRC16, с полиномом 0x8408, стартовым числом 0xFFFF. Байты выводятся в обратном порядке. Производитель любезно предоставил код на Си для расчета, а я его переписал на JS (см. ниже).
Соответственно, [0x04, 0xff, 0x21, 0x19, 0x95] – это команда с запросом статуса ридера по дефолтному адресу FF. 04-длина, 21-команда, 19 и 95 – CRC16 checksum.
var PRESET_VALUE = 0xFFFF;
var POLYNOMIAL = 0x8408;
var CRC16 = function (pucY) {
var uiCrcValue = PRESET_VALUE;
for(var i = 0; i < pucY.length; i++){
uiCrcValue = uiCrcValue ^ (pucY[i]);
for(var j = 0; j < 8; j++){
if(uiCrcValue & 0x0001){
uiCrcValue = (uiCrcValue >> 1) ^ POLYNOMIAL;
} else {
uiCrcValue = (uiCrcValue >> 1);
}
}
}
var buf = Buffer.from(uiCrcValue.toString(16), 'hex');
buf = Buffer.from([buf[1], buf[0]], 'hex');
return buf;
};
//CRC16([0x04, 0xff, 0x21]); //returns <Buffer 19 95>
Примеры команд
Inventory – запрос на однократное считывание карты. Действует в режиме Answer-mode
req =[0x04, 0x00, 0x01, 0xdb, 0x4b];
tcpClient.Write(req);
Если метка в зоне видимости, то мы получим ответ
UHF reader respond:62 00 51 79 17 19 00 04 05 60 5b 28 – это тег метки.
<Buffer 13 00 01 01 01 0c 62 00 51 79 17 19 00 04 05 60 5b 28 2f 24>
Переключение режимов работы ридера
Answer-mode: [0x0a, 0x00, 0x35, 0x00, 0x02, 0x01, 0x00, 0x01, 0x00, 0x2a, 0x9f]
Scan/ Active mode: [0x0a, 0x00, 0x35, 0x01, 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, 0x9b]. В этом режиме ридер постоянно опрашивает метки и отдает их теги.
Что дальше?
А дальше, если требуется простое решение, то либо пишем код, который с периодичностью отправляет команду 0х01 (Inventory). Метки в зоне видимости отдают свои теги, мы сверяем их с БД и инициируем соответствующие действия. Или пишем код, который в режиме постоянного сканирования ждет попадания метки в зону видимости и реагирует событием.
Комментарии (8)
RingoAl
15.09.2018 18:16А где про то, что у метки есть два поля? TID и EPC? И что EPC вполне можно не только читать, но и писать?
Еще на дальность считывания метки сильно влияет наличие металла. Если вы ее наклеите на тот же велосипед, уверенного считывания даже на метре не будет.Alhiimik Автор
15.09.2018 18:19В статью эта тема не входила. Есть метки для металлических поверхностей, надо все тестировать. Есть ридер с более мощной антенной.
Anshi85
15.09.2018 21:24Спасибо за статью, возник такой вопрос, могу ли я относительно недорого реализовать в офисе что то наподобие СКУД, чтобы была информация когда пришел человек и когда ушел.
d-stream
15.09.2018 23:30Как показала практика — карточные СКУД для этого мало подходят. По крайней мере пока RFID метки не вшиты в людей...)
В остальных случаях либо параноидальное «отмечание» на считывателях отпечатка пальца/сетчатки, либо «да ну это нафиг».
Alhiimik Автор
15.09.2018 23:32Самое дешевое решение для DIY:
Для СКУД проще и дешевле взять обычный RFID, например, Matrix-II MF-I на быстрой частоте — 13,56 МГц. В отличие от UHF, надо прикладывать на расстояние не дальше 5 см.
Контроллером может стать Raspberry c NodeJS.
Электрическую часть я делал на 1-wire Matix-Arduino-Raspberry. Просто и удобно, но ограничение на 15 метров (шина на витой паре). При больших расстояниях надо искать способ подключиться по Wiegand или экспериментировать с другими протоклами
Alhiimik Автор
15.09.2018 23:34Если про скрытое наблюдение, то можно только на UHF. Только надо сначала заставить людей вшить метки куда-то :) Ну или в подошвы всех ботинок встроить метки. Тогда точно сработает, до смены ботинок
irbis_al
Скажите,- тэг метки ведь должен быть в конечном итоге «строка»…
А это 62 00 51 79 17 19 00 04 05 60 5b 28 не совсем можно перевести в читабельную строку(например символы 00 04 05)?
Alhiimik Автор
Это то, что отдает ридер, это HEX метки. Я пока не разбирал ее значения, и, в принципе, не собирался, т.к. в мои планы входило только чтение уникального тега, ничего более