EnglishУкраїнськаmRussian
Login/New
Topic with many replies

Опрос устройств по событию


Author Message
Written on: 24. 02. 2010 [18:22]
Vladimir
Vladimir Ivanov
Topic creator
registered since: 24.02.2010
Posts: 4
Есть задача опроса определенной группы регистров через Modbus по событию.
Т. е. по нажатию на виджет необходимо ОДИН раз вычитать группу регистров по Modbus из устройства и отобразить на страницу.
Если регистры описать в подсистеме "Сбор данных", то они читаются постоянно с установленной периодичностью.
Читал тут, что можно использовать messIO, но у меня так и не получилось.
Как это правильно реализовать?
Как использовать messIO?
Written on: 25. 02. 2010 [08:07]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
Vladimir wrote:

Есть задача опроса определенной группы регистров через Modbus по событию.
Т. е. по нажатию на виджет необходимо ОДИН раз вычитать группу регистров по Modbus из устройства и отобразить на страницу.

С помощью messIO() и делается.
Vladimir wrote:

Как использовать messIO?

По логике:
- формирования PDU запроса
- обработка PDU ответа

Learn, learn and learn better than work, work and work.
Written on: 25. 02. 2010 [08:55]
Vladimir
Vladimir Ivanov
Topic creator
registered since: 24.02.2010
Posts: 4
А можно простейший пример, а то я что то туплю. Читал, но до конца не понял.
Как не делал, так и не заработало.
Делал так:

pdu="тру-ла-ла";
SYS.Transport.Serial.out_rtu.messIO(pdu, 200);


[This article was edited 1 times, at last 25.02.2010 at 09:00.]
Written on: 25. 02. 2010 [17:15]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
req = SYS.XMLNode("TCP");
req.setAttr("id","test").setAttr("reqTm",1).setAttr("node",1).setAttr("reqTry",2).setText(Special.FLibSYS.strEnc2Bin("03 00 00 00 05"));
SYS.Transport.Sockets.out_testModBus.messIO(req,"ModBus");
test = Special.FLibSYS.strDec4Bin(req.text());

Learn, learn and learn better than work, work and work.
Written on: 25. 02. 2010 [17:55]
Vladimir
Vladimir Ivanov
Topic creator
registered since: 24.02.2010
Posts: 4
Спасибо большое. Буду пробовать.
Written on: 03. 03. 2010 [09:00]
Aleksey
Aleksey Popkov
Contributor
registered since: 31.07.2008
Posts: 326
Vladimir wrote:

Спасибо большое. Буду пробовать.

У Вас получилось или нет ? Отписались-бы.
Written on: 03. 03. 2010 [14:52]
Vladimir
Vladimir Ivanov
Topic creator
registered since: 24.02.2010
Posts: 4
Все получилось. Теперь осмысливаю все это. Подскажите, как из полученного ответного пакета взять, например, 3 и 4 байт, преобразовать в значение int для использования. В каком формате данные в ответном пакете?
Written on: 03. 03. 2010 [15:23]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
Vladimir wrote:

Подскажите, как из полученного ответного пакета взять, например, 3 и 4 байт, преобразовать в значение int для использования.

С помощью
int charCodeAt( int symb ); - Извлекает из строки код символа <symb>.

intVl = ( pdu.charCodeAt(3) << 8 )|pdu.charCodeAt(4);

Vladimir wrote:

В каком формате данные в ответном пакете?

Соответствующий pdu ответа для отосланого pdu запроса. http://wiki.oscada.org/Doc/ModBus?v=jzl#h592-7

Learn, learn and learn better than work, work and work.
Written on: 13. 03. 2010 [19:40]
almaz
Almaz Karimov
Contributor
registered since: 25.09.2008
Posts: 516
Вставка из документации:
Функции объекта исходящего транспорта (SYS.Transport["Modul"]["OutTransp"]):
* string messIO( string mess, real timeOut = 1000 ); - отправка сообщения <mess> через транспорт с таймаутом ожидания <timeOut>.
* int messIO( XMLNodeObj req, string prt ); - отправка запроса <req> к протоколу <prt> для осуществления сеанса связи через транспорт посредством протокола.

С помощью протокола ModBus, видимо, работает. Есть ли возможность просто отправить несколько байт через последовательный транспорт и получить в ответ несколько байт? Если можно - рабочий пример.

Есть прибор с нестандартным протоколом - вот и возникла проблема. Через вкладку "Запрос" транспорта очень просто получается в бинарном коде отправить и получить результат, а функция messIO (первый формат) ну никак не хочет ничего выдать.banghead.gif

Код использовал следующий:
str=SYS.Transport.Serial.out_ttyUSB0.messIO("4b 00 37 40",3);
В итоге исходящий трафик есть, входящего нет. Таймаут 3 секунды. Видимо отправляет каждый символ одним байтом...icon_rolleyes.gif А как же переключить функцию с текстового режима в бинарный?

Ура! Следующий код что-то выдал в ответ:
str=SYS.Transport.Serial.out_ttyUSB0.messIO(SYS.strFromCharCode(0x4b, 0x00, 0x37, 0x40),1);
С таймаутом 1 секунда. Остаётся разбор ответного пакета!!!

Работают без таймаута (с минимальным временем опроса) следующие два примера кода:
str=SYS.Transport.Serial.out_ttyUSB0.messIO(SYS.strFromCharCode(0x4b, 0x00, 0x37, 0x40),0);
str=SYS.Transport.Serial.out_ttyUSB0.messIO(SYS.strFromCharCode(0x4b, 0x00, 0x37, 0x40));

Окончательный вариант с применением других функций и уже с декодированием и таймаутом ожидания ответа:
str=Special.FLibSYS.strDec4Bin(SYS.Transport.Serial.out_ttyUSB0.messIO(Special.FLibSYS.strEnc2Bin("4B 00 37 40"),0.2));
В строковой переменной str получаем строку ответа формата "4B 00 37 40" уже удобного для разбора строковыми функциями.

Почему-то очень часто обрезает ответ (последние байт, два,три). Таймауты последовательного порта регулировал по-разному. Не помогает.
То же самое происходит на вкладке "Запрос" транспорта, если убрать галочку "Ожидать таймаут". В чём проблема ясно. А как исправить? Почему функция messIO (формат первый) не производит ожидания таймаута?

21 век - век повсеместной автоматизации. Главное - во благо всем людям.
Written on: 13. 03. 2010 [20:13]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
almaz wrote:

В строковой переменной str получаем строку ответа формата "4B 00 37 40" уже удобного для разбора строковыми функциями.

Проще разбирать бинарный ответ функцией charCodeAt().

almaz wrote:

Почему-то очень часто обрезает ответ (последние байт, два,три). Таймауты последовательного порта

Потому что природа любого интерфейса такова. Они могут возвращать не сразу весь поток. У одних это связано с входным буфером и особенностью передачи данных удалённой станцией. Например Web-браузера часто шлют запрос кусками. У других, последовательных, с заранее неизвестным размером сообщения, например ModBusRTU.

Поэтому транспорт возвращает то, что получил в буфер. А остальное задача протокола. В случае с последовательным интерфейсом если известна длина ответа или есть другой критерий например, это символьный протокол и он заканчивается символом '\r' то протокол ожидает всего сообщения до критерия. Иначе, в случае с ModBusRTU ожидается всё сообщение до таймаута. Детальнее посмотрите в свой же модуль DCON на предмет использования функции messIO(), она фактически такая-же.

В случае с данным вариантом функции messIO() нужно слать пустые запросы для ожидания остатка сообщения. Признаком таймаута является пустой ответ. Только обновитесь, корректный возврат по таймауту я только что добавил!

Learn, learn and learn better than work, work and work.



7464