Тензод200
Работа WebHMI с тензометрическим контроллером Тензод200 легко реализуется благодаря возможности использования пользовательских протоколов на встроенном языке скриптов .
Прибор ТЕНЗОД200 имеет открытый символьный протокол с адресацией устройств в сети, имеет несколько режимов работы со встроенными портами RS-232/485/ИРПС, такими как выдача результатов измерения в порт (режим терминала), режим печати и др. Для опроса устройства по RS-485 необходимо отключить в приборе функции выдачи в порт данных (параметр 8026). Основные настройки прибора приведены ниже : <l> 8028 = 83 , разрешить чтение и запись, не отвечать на запрос ошибки 8029 = 96..11 скорость обмена [9600 - 115200] по первым 2-м цифрам скорости 802А = адрес прибора в сети 8001 = положение 10-й точки в результате 8036 = 21, подсвечивать прием / отправку пакетов светодиодами (для наладки связи ) 8026 = 00 не выводить в порт данные в режиме терминала количество бит 8, 2 стоповых бита, без четности в некоторых версиях прибора могут меняться местами линии А (Data-) и В (Data+) </l> Пример функций поддержки протокола в ТЕНЗОД200 на языке скриптов :
function createDevices () -- функция создания регистров
addDevice({name = "H", base = 16}); -- в документации регистры в шестнадацт. системе
end
local errorCount = 0; -- error counter
-- дшаблон строки, длина всегда 8, меняем только адрес и к. сумму
local request_str = "#{ADDR}0 RM 8198 8 $0{CRC}\r\n"
--ФУНКЦИЯ ЧТЕНИЯ
function readRegister (reg, device, unitId)
-- адрес в сети подставить из переданного параметра unitId
adr_char = string.char( tonumber(unitId .. "",16) ) ;
request_str = string.gsub(request_str, "#{ADDR}", "#"..adr_char, 1);
-- вычислить контрольную сумму, c 2 по 14 символы
local crc_2 =0;
for j=2, 14 do
crc_2 = crc_2 + request_str:byte(j); -- посчитать к. сумму, она зависит от адреса
j = j + 1;
end
-- преобразовать в число 16-ое в виде строки
crc_str_to = string.format("%X",crc_2);
-- вставить к. сумму в строку
request_str = string.gsub(request_str, "{CRC}", crc_str_to);
-- отправка строки запроса
local res = sendString(request_str);
if (res == false) then
DEBUG("Can't send bytes");
return false;
end
-- прием ответа
local response = readString(48);
if (response == false) then
ERROR("Can't read response") ;
return false;
end
if (#response < 48) then
ERROR("packet shorter "..tostring(#response)) ;
return false;
end
-- посчитать контрольную сумму 4..40
local crc_3= 0;
for j=4, 40 do
crc_3 = crc_3 + response:byte(j);
j = j + 1;
end
-- получить ее в виде строки
crc_str_reply = string.format("%X",crc_3);
-- взять к. сумму из ответа
__,__, res_crc = string.find(response,"($0%w%w%w)");
-- последние 3 цифры
res_crc = string.sub (res_crc,3);
-- обработка ошибки к. суммы
if (res_crc ~= crc_str_reply) then
errorCount = errorCount + 1;
if (errorCount > 3) then
closeConnection();
errorCount = 0;
end
DEBUG("CRC not Ok "..res_crc.." vs."..crc_str_reply);
return false;
end
-- найти позицию "8" чтобы взять ближайшие к ней цифры с значением
local result_start_i, res_end_i = string.find(response," 8 ");
local result_sub = string.sub(response, res_end_i, res_end_i+11); -- взять значения
local result_sign = string.sub(response, res_end_i+22, res_end_i+23); -- взять знак числа
-- найти пары чисел с пробелами используя свойство ф. sring.find "захвата" нескольких значений с помощью ()
local p1,p2,p3,p4 = "","","","";
__,__, p1,p2,p3,p4 = string.find(result_sub,"( %d%d)( %d%d)( %d%d)( %d%d)");
-- перевернуть строку
result_sub = p4..p3..p2..p1;
-- убрать пробелы
result_sub = string.gsub(result_sub, " ","");
-- преобр. в число
value_out = tonumber(result_sub);
-- вернуть из функции полученное число со знаком
if (result_sign == "80") then
value_out = (0 - value_out) ;
end
-- возвращение результата
return value_out;
end
function writeRegister ()
-- Add your code here
end