Страница 1 из 3 123 ПоследняяПоследняя
Показано с 1 по 10 из 22

Тема: Запрос по маске в MasterOPC Server

  1. #1

    По умолчанию Запрос по маске в MasterOPC Server

    Добрый день! Попытался реализовать протокол для устройства в MasterOPC Server согласно инструкции для функции Modbus Function Code 23 (0x17) Read/Write Multiple Registers https://insat.ru/products/Universal_...ver_API_UG.pdf, но что то пошло не так.
    Запрос по маске сделал на основе скрипта первого примера для датчика температуры и влажности МАВ-ТС100 фирмы «Микрофор». Решил начать с самого простого старт/остановка устройства, старт запись в 0x000C значения 0x0001, стоп запись 0x0000 соответственно. Скрипт из примера для теста обрезал по максимуму для своих тестов.

    Код скрипта:
    function Start_Chill(num_reg)
    local send={}; --массив отправляемых чисел
    local Addr=server.GetCurrentDeviceAddress( );--получения адреса устройства
    table.insert(send,Addr); --добавляем в таблицу первый элемент - адрес
    table.insert(send,0x17); --добавляем в таблицу второй элемент - идентификатор команды
    table.insert(send,0x0000); --добавляем в таблицу третий Read Address Hi Lo
    table.insert(send,0x0000); --добавляем в таблицу четвертый Quantity to Read Hi Lo
    table.insert(send,0x000C); --добавляем в таблицу пятый Write Address Hi Lo
    table.insert(send,0x01); --добавляем в таблицу шестой Quantity to Write
    table.insert(send,0x02); --добавляем в таблицу седьмой Byte Count
    table.insert(send,num_reg); --добавляем в таблицу восьмой Значение на запись
    local sendmask={"byte","byte","int16:10","int16:10","int 16:10","int16:10","byte","int16:10"}; --маска отправляемого запроса
    local dest={}; --массив полученных чисел
    local destmask={"byte","byte","byte","int16:10"}; --маска принимаемого запроса
    local err,len;
    local n=0;
    repeat
    --посылка и получение запроса в устройство
    err,dest,len=server.SendAndReceiveDataByMask(3,8,s endmask,send,destmask,20);
    n=n+1;
    --условие выхода - корректный ответ или превышение запросов
    until err>=0 or n>=server.GetCurrentDeviceRetry()
    --обрабатываем полученные данные
    if err>=0 then
    --запрос выполнен корректно
    if dest[2]==0x17 then
    return true,dest[3]; --возвращаем флаг что запрос корректен и значение
    else
    server.Message("Неизвестная функция"); --пишем сообщение в лог
    return false,0; --запрос некорректен
    end;
    else
    return false,0; --запрос некорректен, возвращаем соответсвующий флаг
    end;
    end;
    -- Initialization
    function OnInit()
    end
    -- Uninitialization
    function OnClose()
    end
    -- Processing
    function OnWrite()
    if server.ReadCurrentTag()==true
    then noerr,RegH=Start_Chill(0x0001)
    else noerr,RegH=Start_Chill(0x0000)
    end;
    end

    Формируемая маска запроса в MasterOPC Server 21-07-2021 17:36:51.224 SMS HRZ::ChillerCOM5) Tx: [0014] 01 17 00 00 00 00 00 0C 00 01 02 D9 0D 0A , причем я сделал логическое переключение для старта и остановки устройства, но при задании true либо false маска запроса никак не изменяется. Я ожидал получить такую маску : 01 17 00 00 00 00 00 0C 00 01 02 00 01 LRC 0D 0A
    Вложения Вложения

  2. #2

    По умолчанию

    Я еще тут поэкспериментировал немного с устройством, даже такая сформированная маска не подходит, нужно маску :01 17 00 00 00 00 00 0C 00 01 02 00 01 LRC сформировать без пробелов и передать в ASCII кодировке. Как это можно сделать в MasterOPC Server? Вернее эта маска должна быть без пробелов :011700000000000C0001020001LRC[CR][LF]
    Последний раз редактировалось fizhimik; 23.07.2021 в 12:14.

  3. #3

    По умолчанию

    Я немного разобрался, мне подошел второй пример из https://insat.ru/products/Universal_...ver_API_UG.pdf, но затем при попытке повторить запрос в устройство как в примере из мануала к устройству, я понял что расчет LRC в функции server.SendAndReceiveDataByMask мне не подходит. Можете подсказать как это можно реализовать?

  4. #4

    По умолчанию

    Добрый день! Забросил пока этот прибор, решил попробовать подключить другой, без контрольной суммы, но не могу конвертировать получаемые ASCII символы.
    Запрос на измерение выглядит так Tx: [0017] 3A 30 36 30 33 30 34 32 31 34 30 32 31 34 30 0D 0A, ответ от прибора Rx: [0021] 3A 30 38 30 33 30 32 32 31 34 30 30 30 30 30 30 30 30 30 0D 0A. В выделенных символах находится измеряемое число (оно на данный момент 0). В маске получаемых данных я прописал destmask={"string:32","string:23","string:6"}; --маска принимаемого запроса. Так правильно, стоит ли считать пробелы? В Справке к Master OPC описан пример пересчета значения в FLOAT, но я не понимаю как перейти от получаемых ASCII к значению, которое можно подставить в пример для пересчета. Можете подсказать?

  5. #5

    По умолчанию

    Вы можете получить как строку, а потом с помощью стандартной функции tonumber (описание в справке) привезти к числу
    Либо вы можете сразу получать как sdouble - посмотрите пример DCON в инструкции
    Спасибо.

  6. #6

    По умолчанию

    Цитата Сообщение от SCADAMaster Посмотреть сообщение
    Вы можете получить как строку, а потом с помощью стандартной функции tonumber (описание в справке) привезти к числу
    Либо вы можете сразу получать как sdouble - посмотрите пример DCON в инструкции
    Спасибо.
    Но к сожалению, я что то делаю не так. Ни одним из способов преобразовать данные не получилось. Вот конец кода, функция ToFloat из справки.
    Код:
    local dest={}; --массив полученных чисел
    local destmask={"string:32","sdouble:1:8","string:6"}; --маска принимаемого запроса
    local err,len;
    local n=0;
    local list={};
    local val;
    err,dest,len=server.SendAndReceiveDataByMask(0,tab le.maxn(send),sendmask,send,destmask,200);

    server.WriteCurrentTag(ToFloat(dest[2]));

    Ошибка тега:
    04-08-2021 14:48:30.885 Measure:Node1.Device1.Measure >> [string "--[[(R)Node1.Device1.Measure]]-- Initializati..."]:3: bad argument #1 to 'BitAnd' (number expected, got string)
    stack traceback:
    [C]: at 0x00873ad0
    [C]: in function 'BitAnd'
    [string "--[[(R)Node1.Device1.Measure]]-- Initializati..."]:3: in function 'ToFloat'
    [string "--[[(R)Node1.Device1.Measure]]-- Initializati..."]:44: in function <[string "--[[(R)Node1.Device1.Measure]]-- Initializati..."]:23>

  7. #7

    По умолчанию

    Что за tofloat? Нет такой функции - есть функция tonumber. Посмотрите ее описание в справке
    Спасибо.

  8. #8

    По умолчанию

    Цитата Сообщение от SCADAMaster Посмотреть сообщение
    Что за tofloat? Нет такой функции - есть функция tonumber. Посмотрите ее описание в справке
    пример из справки:
    Пример функции

    function ToFloat(register)

    local fraction=bit.BitAnd(register,0x7FFFFF); --маскируем 23 бита - получем мантиссу

    local exp=bit.BitRshift(register,23); --смещаемся вправо на 23 бита - получаем экспоненту

    local exp=bit.BitAnd(exp,0xFF); --маскируем биты экспоненты

    local sign=bit.BitFromData(register,31); --выделяем бит знака

    local float=2^(exp-127)*(1+fraction/2^23); --вычисляем число

    if sign==true then float=float*(-1); end; --проверяем знак

    return float;

    end

    Пример вызова функции.

    val=1042284544;

    FloatNumber=ToFloat(val);

    Может я совсем не правильно делаю, ведь пробел это то же символ и это надо учитывать?
    Либо извлекаемую строку с данными обработать string.split, получив таблицу с отдельными ASCII символами, преобразовать таблицу получив значения HEX(тут я могу ошибаться в терминологии) и затем как то совместить значения из таблицы получив одно число, которое потом сконвертировать во Float?
    Последний раз редактировалось fizhimik; 04.08.2021 в 15:47.

  9. #9

    По умолчанию

    Ну так там ToFloat это пользовательская функция и делает она не это.
    Посмотрите описание tonumber
    И где вы пробел увидели? У пробела ASCII код - 0x20
    Спасибо.

  10. #10

    По умолчанию

    Цитата Сообщение от SCADAMaster Посмотреть сообщение
    Ну так там ToFloat это пользовательская функция и делает она не это.
    Посмотрите описание tonumber
    И где вы пробел увидели? У пробела ASCII код - 0x20
    Пробел между символами 30 30...
    Я решил перепроверить работу tonumber в Lua, вот результат
    tonumber в Lua:

    Если пробелы убрать то функция работает. Что я делаю не так?

Страница 1 из 3 123 ПоследняяПоследняя

Похожие темы

  1. MULTI-PROTOCOL MASTEROPC SERVER
    от oleg1821 в разделе Master SCADA 3
    Ответов: 19
    Последнее сообщение: 13.11.2018, 07:38
  2. MasterOPC Server теряет связь
    от Михаил85 в разделе Master SCADA 3
    Ответов: 1
    Последнее сообщение: 05.10.2018, 08:26
  3. Universal MasterOPC Server и TeamViewer
    от a_gricaj в разделе OPC Серверы
    Ответов: 0
    Последнее сообщение: 06.05.2018, 15:43
  4. Modbus Universal MasterOPC Server и ВКТ-7
    от Alex Tulaev в разделе Master SCADA 3
    Ответов: 5
    Последнее сообщение: 03.03.2017, 09:55

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •