RFID система VI-88F
RFID системы являются популярным решением для отслеживания продукциии и других объектов в складской логистике и др. RFID системы как правило имеют последовательный порт, который работает в 2-х режимах:
- терминала, когда при появлении метки в поле видимости в последовательный порт отправляется строка с данными о метки.
- режим опроса , или командный режим, когда RFID отдает код метки по запросу от хоста
В WebHMI поддержка RFID системы VI-88/86/89F реализована через пользовательский протокол, когда RFID настроена в "командном режиме" на выдачу только одной метки за 1 раз для упрощения обработки ответов (в случае наличия нескольких меток в поле действия - они становятся в очередь LIFO). Алгоритм пользовательского протокола в этом случае такой:
- отправить команду - "получить ID меток в поле действия"
- проверить ответ - прочитать 5 байт и сравнить с ответом "нет меток"
- если ответ другой, дочитать оставшиеся байты, проверить контрольную сумму и при правильной сумме взять подстроку из ID метки, преобразовать в число и вернуть как значениие регистра
Дальнейшую обработку полученного кода метки: применение "словаря", повторные чтения для уверенного приема конкретной метки и др. - можно реализовать в пользовательских скриптах. Пример пользовательского протокола обмена с RFID системой VI-88/86/89F (без обработки CRC) :
function createDevices () -- функция создания регистров
addDevice({name = "H", base = 16}); -- в документации регистры в шестнадацтиричной системе
end
local errorCount = 0; -- error counter
local req_array = {0x40, 0x06, 0xEE, 0x01, 0x00, 0x00, 0x00, 0xCB}; -- шаблон строки запроса Get tag list
local no_tag_mask = {0xf4, 0x03, 0xEE, 0x02, 0x19}; -- маска нет меток
-- СРАВНЕНИЕ 2-х таблиц на совпадение
function cmpTables (t1,t2)
local cmp_expression = false;
for i,v in ipairs (t1)
do
cmp_expression = (v == t2[i]);
if not cmp_expression then return false; end
end
return true;
end
-- ПРЕОБРАЗОВАНИЕ ТАБЛИЦЫ В СТРОКУ --
function Table2string(t)
local result = "";
for i,v in ipairs(t) do
result = result..string.format("%x",v)
end
return result
end
-------------------------------------
function readRegister (reg, device, unitId) --ФУНКЦИЯ ЧТЕНИЯ
local res = sendBytes(req_array); -- отправка запроса
INFO("Request was sent!");
if (res == false) then
DEBUG("Can't send bytes");
return false;
end
local response = readBytes(5); -- прием ответа
local response2 = {};
if (response == false) then
ERROR("Can't read response") ;
return false;
end
if cmpTables(no_tag_mask, response)
then
INFO("NO tag");
return 0;-- метка не присутствует
else
-- дочитываем остаток
response2 = readBytes(13); -- прием ответа
if (response == false)
then
ERROR("Can't read response") ;
return false;
end
-- склеить обе части
for i,v in ipairs(response2)
do
table.insert(response, v)
end
end
-- посчитать контрольную сумму, если нужно
local CRC = table.remove(response); -- убрать символ контрольной суммы
local string_out = Table2string(response);
local last_four = string_out:sub(#string_out - 3)
-- убрать контрольую сумму
INFO("Tag was "..last_four);
return tonumber(last_four,16);
-- КОНЕЦ Ф. ЧТЕНИЯ--
end
function writeRegister ()
-- Add your code here
return false;
end