EnglishРусскийУкраїнська
В теме много сообщений

Вопрос о ModBus


Автор Сообщение
Сообщение создано: 18. 01. 2012 [19:02]
andrey-sw
Андрей Сычев
Создатель темы
Зарегистрирован(а) с: 10.12.2008
Сообщения: 21
Фокус не удался, собирал из svn
3|/WorkStation/sub_ModSched/ | SO '/usr/lib/openscada/daq_ModBus.so' ошибка: /usr/lib/openscada/daq_ModBus.so: undefined symbol: _ZN6OSCADA6TValue7chldAddEaPNS_9TCntrNodeEib !
так что проверю чуть позже, результаты сообщю
Хотя можно попробовать в исходнике 0.7.2 сделать соответствующие изменения...

[Сообщение редактировалось 1 раз(а), в последний раз 18.01.2012 в 19:10.]
Сообщение создано: 23. 01. 2012 [11:11]
andrey-sw
Андрей Сычев
Создатель темы
Зарегистрирован(а) с: 10.12.2008
Сообщения: 21
Случайный ID транзакции не помог. Сделал задержку в 10мс перед запросом и все заработало. видимо это ограничение либо ТРМ либо ADAM-4572.
Вот часть кода
JAVASCRIPT
if(prt == "TCP")    // Modbus/TCP protocol process                                                                       
{                                                                                                                                    
    usleep(10000);                                                                                                                   
    //> Encode MBAP (Modbus Application Protocol)                                                                                    
    int tid = rand();                                                                                                                
    mbap.reserve(pdu.size()+7);                                                                                                      
    mbap.append((char *)&tid,2);//Transaction ID                                                                             
    mbap.append(2,(char)0);//Protocol ID                                                                                
    mbap += (char)((pdu.size()+1)>>8);<>//PDU size MSB                                                                               
    mbap += (char)(pdu.size()+1);//PDU size LSB                                                                               
    mbap += (char)node;//Unit identifier                                                                            
    mbap += pdu;                                                                                                                     
 
    //> Send request                                                                                                                 
    int resp_len = tro.messIO(mbap.data(), mbap.size(), buf, sizeof(buf), reqTm, true);                                              
    rez.assign(buf,resp_len);

Может и не очень красиво но меня устраивает
Кстати не совсем понял строку
mbap.append(2,(char)0);//Protocol ID
разве должно быть не так
mbap.append((char)0,2);//Protocol ID
Но раз работает значит я что то не допонял...



[Сообщение редактировалось 1 раз(а), в последний раз 23.01.2012 в 11:12.]
Сообщение создано: 23. 01. 2012 [13:19]
roman
Roman Savochenko
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 1460
"andrey-sw" wrote:

Случайный ID транзакции не помог.

Чего и требовалось ожидать.

"andrey-sw" wrote:

Сделал задержку в 10мс перед запросом и все заработало. видимо это ограничение либо ТРМ либо ADAM-4572.

Используйте OpenSCADA в роли TCP->RTU шлюза. :)

"andrey-sw" wrote:

Может и не очень красиво но меня устраивает

Совсем некрасиво! Добавил параметр таймаута повтора запроса в транспорт Transport.Sockets.

"andrey-sw" wrote:

Кстати не совсем понял строку
mbap.append(2,(char)0);//Protocol ID
разве должно быть не так
mbap.append((char)0,2);//Protocol ID
Но раз работает значит я что то не допонял...

Почитайте STL.

Учиться, учиться и учиться лучше чем работать, работать и работать.
Сообщение создано: 27. 01. 2012 [11:31]
yozhik
Алексей Николаев
Зарегистрирован(а) с: 29.11.2010
Сообщения: 127
Создал функцию:
JAVASCRIPT
req = SYS.XMLNode("TCP");
req.setAttr("id","terminal").setAttr("reqTm",100).setAttr("node",node).setText( Special.FLibSYS.strEnc2Bin( "03 09 0C 00 01" ) );
SYS.Transport.Sockets.out_terminal_test.messIO(req,"ModBus");
...
.
Установил максимальное время вычисления 1 сек. Когда устройство по протоколу модбас "на свзяи", то все нормально. Если же его отключить, то вызов функции завершается сообщением "Исчерпано предельное время вычисления функции". Тайм-аут же по связи, как видно из текста функции, установлен в 100 мс. По идее после ожидания 100 мс и должно завершиться выполнение функции, а не по истечению 1 сек. Или не так? Иначе данная функция вызываясь 1 раз в сек забивает весь лог этим сообщением об ошибке.
Сообщение создано: 27. 01. 2012 [11:48]
roman
Roman Savochenko
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 1460
"yozhik" wrote:

Установил максимальное время вычисления 1 сек. Когда устройство по протоколу модбас "на свзяи", то все нормально. Если же его отключить, то вызов функции завершается сообщением "Исчерпано предельное время вычисления функции". Тайм-аут же по связи, как видно из текста функции, установлен в 100 мс. По идее после ожидания 100 мс и должно завершиться выполнение функции, а не по истечению 1 сек. Или не так? Иначе данная функция вызываясь 1 раз в сек забивает весь лог этим сообщением об ошибке.

Не так. Я не вижу всего содержимого функции и так подозреваю, что messIO() в ней вызывается многократно, а значит суммарно их время превысило секунду. А вообще, для верности, поставьте лимит в 2 секунды, поскольку разрешение времени используемое для вычисления лимита 1 секунда, что может приводить к срабатыванию от 0 до 1 секунды, в вашем случае.

Учиться, учиться и учиться лучше чем работать, работать и работать.
Сообщение создано: 27. 01. 2012 [12:13]
yozhik
Алексей Николаев
Зарегистрирован(а) с: 29.11.2010
Сообщения: 127
"roman" wrote:

Я не вижу всего содержимого функции и так подозреваю, что messIO() в ней вызывается многократно, а значит суммарно их время превысило секунду.

Приведенный кусок кода и есть вся функция (как раз для чистоты эксперимента и выделил этот кусок кода в отдельную функцию), где только вместо многоточия стоит SYS.messDebug() для тестирования. Так вот до messDebug выполнение не доходит. Сделал количество запусков функции 10 при этом общее время выполнения оказалось 57,2 сек. Т.о. получаем 5,72 сек.

"roman" wrote:

А вообще, для верности, поставьте лимит в 2 секунды, поскольку разрешение времени используемое для вычисления лимита 1 секунда, что может приводить к срабатыванию от 0 до 1 секунды, в вашем случае.

Поставил 2 сек. Помогло, но не на 100%. Увеличил до 3 сек - стало нормально. Странно, но вроде работает.
Сообщение создано: 27. 01. 2012 [13:05]
roman
Roman Savochenko
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 1460
"yozhik" wrote:

Приведенный кусок кода и есть вся функция (как раз для чистоты эксперимента и выделил этот кусок кода в отдельную функцию), где только вместо многоточия стоит SYS.messDebug() для тестирования. Так вот до messDebug выполнение не доходит. Сделал количество запусков функции 10 при этом общее время выполнения оказалось 57,2 сек. Т.о. получаем 5,72 сек.

У меня нет такой проблемы. Взял Ваш код и получил время выполнения "Затрачено времени: 101.5мс."

Учиться, учиться и учиться лучше чем работать, работать и работать.
Сообщение создано: 27. 01. 2012 [13:37]
yozhik
Алексей Николаев
Зарегистрирован(а) с: 29.11.2010
Сообщения: 127
"roman" wrote:

У меня нет такой проблемы. Взял Ваш код и получил время выполнения "Затрачено времени: 101.5мс."

Попробовал сейчас на демо станции на транспорте testModBus - действительно время выполнения 101,5 мс. Но этот транспорт настроен на localhost и включен. В моем же случае, транспорт настроен на устройство, которое (по какой-либо причине) в данный момент не в сети и соответственно транспорт отключен.

Если я правильно понимаю, то при обращении по выключенному в данный момент транспорту производится попытка его включения. Вот это время на включение и добавляется к 100 мс тайм-аута и поэтому общее время выполнения функции превышает заданное. Если это на самом деле так, то все понятно и остается единственный вопрос - а каково время включения транспорта?
Сообщение создано: 27. 01. 2012 [14:13]
roman
Roman Savochenko
Contributor
Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 1460
"yozhik" wrote:

Попробовал сейчас на демо станции на транспорте testModBus - действительно время выполнения 101,5 мс. Но этот транспорт настроен на localhost и включен. В моем же случае, транспорт настроен на устройство, которое (по какой-либо причине) в данный момент не в сети и соответственно транспорт отключен.

У меня на localhost вообще 4 мс, поскольку стек сети может сразу определить, что там ничего не слушает. А на внешнем адресе, по которому ничего нет, то что я показал!

"yozhik" wrote:

Если я правильно понимаю, то при обращении по выключенному в данный момент транспорту производится попытка его включения. Вот это время на включение и добавляется к 100 мс тайм-аута и поэтому общее время выполнения функции превышает заданное. Если это на самом деле так, то все понятно и остается единственный вопрос - а каково время включения транспорта?

Ничего подобного, для подключения используется тот же таймаут и это я Вам показал своим примером, поскольку в случае с ошибкой подключения транспорт всегда останавливается и пытается запуститься при следующем запросе, с тем-же таймаутом.

Не верите - берите исходник и разбирайтесь!

Учиться, учиться и учиться лучше чем работать, работать и работать.



1619