PDA

Просмотр полной версии : Ошибки библиотеки Modbus



URA6923
25.07.2013, 22:28
Добрый день! Требуется помощь в таком вопросе: хочу использовать библиотеку Modbus вместо конфигуратора .Выкладываю часть программы с записью значения регистров 16 (0x10) Write Multiple registers (MB_WR_REGS).
Данные передаются ,нона выходе Exception постоянная ошибка 0xFF – ошибка таймаута.

1) Не пойму, что не так, что надо делать? Время таймаута ставил разное, но ошибки не исчезают.
2) Почему в эмуляторе при чтении и записи данных в массивах байтов для записи или чтения какой-то мусор?
3) Как правильно организовать проверку данных на ошибки при чтении и записи?

Алексей Дмитриев
26.07.2013, 14:56
Зачем на FBD-то это пишете? В документации есть прекрасный пример на ST. Там все намного читабельней.
Потом, если пробуете в эмуляторе, то ничего работать не будет! Библиотека использует аппаратные особенности контроллера и эмулятором не поддерживается.

URA6923
26.07.2013, 20:13
Зачем на FBD-то это пишете? В документации есть прекрасный пример на ST. Там все намного читабельней.
Потом, если пробуете в эмуляторе, то ничего работать не будет! Библиотека использует аппаратные особенности контроллера и эмулятором не поддерживается.

По первому вопросу могу сказать только одно - потому что я на нем пишу. Можно и на ST, но получается у меня медленно, и для меня пока что не так уж читабельно.
По второму- да, действительно эти библиотеки не работают в эмуляторе и я в курсе этого (в вопросе я неправильно написал про подключение). При проверке я записывал программу в контролер и смотрел как он общается с панелью через программу CoDeSys в онлайне без эмулятора.Так вот, в массивах, которые используются для чтения и записи, если их открыть, меняются данные. Например, я использую первые 4 байта, при чтении они записываются и добавляется еще мусор с 8 по 15 байт. Или CoDeSys не правильно отображает это.
А насчет примера на ST, можно его увидеть? Выложите пожалуйста, если вам не сложно. Заранее благодарен.

ASo
26.07.2013, 20:32
Нормально все работает. Но пример в документации - не правильный.

URA6923
26.07.2013, 20:42
Нормально все работает. Но пример в документации - не правильный.

У кого все нормально работает?И где взять правильный пример?

Алексей Дмитриев
30.07.2013, 10:55
Ну уже обсуждалось неоднократно. Напимер вот пример для связи с МДВВ: http://www.owen.ru/forum/attachment.php?attachmentid=3207&d=1292780156

URA6923
01.08.2013, 21:31
Ну уже обсуждалось неоднократно. Напимер вот пример для связи с МДВВ: http://www.owen.ru/forum/attachment.php?attachmentid=3207&d=1292780156

Спасибо за ссылку.
Но в этом примере нет никакой обработки ошибок, кроме их наличия. При чтении функции 03 ещё можно их отследить, а при записи функции 16 данные передаются правильно, а столько же ошибок.
И интересует такой вопрос - можно ли с помощью библиотеки Modbus менять параметры порта (0 - RS-485 на 1 - RS-232) ну и все остальные параметры? Например, с помощью одного блока обмена опрашивать попеременно два устройства с разными скоростями или разными портами.
Может кто подскажет, как это программно организовать? Или ссылку скиньте на какой нибудь пример.
Всем заранее благодарен.

Алексей Дмитриев
02.08.2013, 10:22
Какую обработку Вы хотите? Собственно при работе периодически вылезает таймаут, как я помню. От него не избавитесь никогда, так как обмен-то асинхронный, имеет право быть. Надо просто проверять, что он есть и не учитывать эти данные. Там в примере эта проверка есть, если ничего не путаю. Другое дело когда постоянно таймаут, то есть слейв отвалился вообще - проверяется с использованием таймера и триггера.
По поводу обслуживания другого порта никаких препятствий не вижу. Пишется точно также, как и для первого, то есть - открываем порт с нужными параметрами и вызываем библиотечные ф-ции для обмена.

URA6923
02.08.2013, 20:56
Какую обработку Вы хотите? Собственно при работе периодически вылезает таймаут, как я помню. От него не избавитесь никогда, так как обмен-то асинхронный, имеет право быть. Надо просто проверять, что он есть и не учитывать эти данные. Там в примере эта проверка есть, если ничего не путаю. Другое дело когда постоянно таймаут, то есть слейв отвалился вообще - проверяется с использованием таймера и триггера.
По поводу обслуживания другого порта никаких препятствий не вижу. Пишется точно также, как и для первого, то есть - открываем порт с нужными параметрами и вызываем библиотечные ф-ции для обмена.

Хочу сказать спасибо за поддержание, так сказать, разговора.
Насчет обработки ошибок, хотелось бы больше иметь информации о ведомом, но функции библиотеки выдают только две ошибки, как я понял это FE и FF, и по этому можно только определить в сети ведомый или нет. По портам, я попробовал менять настройки COMSETTINGS, но что то переключения не получилось, пример прикрепляю.
Возможно, порт нужно полностью выключать, менять установки и заново включать, и все в разных циклах программы.
В прикрепленном примере ещё кое какие места мне непонятны, я там надписи в комментариях сделал (потому что не все там мной написано) хотелось бы получить ответы на возникшие вопросы.
Может будет у специалистов время посмотреть и подсказать, где ошибки. Всем заранее благодарен

lazy
06.08.2013, 13:26
чтобы поменять настройки порт нужно закрыть (дождаться пока закроецо). потом открыть (опять дождацо) и настроить по новому. да нужно разнести по циклам. модбас передает все ошибки. точнее те которые поддерживает ведомый. по поводу передачи. писать в буфер в то время когда идет передача нельзя. отправьте данные в буфер. взведите на один цикл Enable и ждите Complite. как только Complite = true смотрите Exception. Если равен нулю то все ок. С чтением так же. Передаете адреса и кол-во слов взводите Enable на один цикл и ждете Complite. Дождались? если Exception = 0 - разбирайте буфер.

URA6923
07.08.2013, 20:20
чтобы поменять настройки порт нужно закрыть (дождаться пока закроецо). потом открыть (опять дождацо) и настроить по новому. да нужно разнести по циклам. модбас передает все ошибки. точнее те которые поддерживает ведомый. по поводу передачи. писать в буфер в то время когда идет передача нельзя. отправьте данные в буфер. взведите на один цикл Enable и ждите Complite. как только Complite = true смотрите Exception. Если равен нулю то все ок. С чтением так же. Передаете адреса и кол-во слов взводите Enable на один цикл и ждете Complite. Дождались? если Exception = 0 - разбирайте буфер.

Спасибо за ответ. Вообщем как я понял чтобы переключить порт нужно по циклам.
1)Выключаю порт COM_SERVICE Enable =0
2)Ждём окончания передачи - приёма MB_RD_HOLD_REGS Complete =1 (больше ничего не принимаем и не передаем)
3)Ждём COM_SERVICE Ready=0 порт должен закрыться
4)Меняем настройки порта
5)Включаю порт COM_SERVICE Enable =1
Если я в чём то неправ, поправьте пожалуйста.

По передаче данных есть еще вопрос:как правильно должна вестись передача/прием данных, если у мастера есть 3 подчиненных, двое из них опрашиваются постоянно, а третий - только при включении всего оборудования. Вопрос: нужно ли этому третьему постоянно отправлять одни и те же данные? Или сделать несколько обменов(с 1 раза могут данные не дойти), а всё остальное время работать только с первым и вторым?

По ошибкам модбас наверное я их могу посмотреть только в буфере ARRAY модуля MB_RD_HOLD_REGS если подчиненный мне что-то пришлёт, а на выходе модуля Exception только ошибки 0xFE 0xFF.
Сейчас контролера нет под рукой, как появится - всё это буду пробовать.
И еще раз спасибо всем кто помогает обучаться.

lazy
08.08.2013, 14:41
Пункты 1 и 2 нужно поменять местами. А еще лучше вести обмен только когда порт открыт. Дали команду открыть порт - ждем. (может пройти не одна сотня циклов) открылся - настраиваем и начинаем обмен. Сам закрываю порты не дожидаясь окончания обмена.

Если ведомый отключен то запрос завершиться по таймауту. В этом нет ничего страшного. единственное (так как таймаут много больше времени обмена) обмен с первыми двумя приборами будет замедлен. Так что если знаете что прибор сейчас отключен то с ним лучше не общяцо иканеш.

По поводу данных которые не изменились от передачи к передаче... Я не заморачиваюсь и пишу/читаю постоянно.

Все ошибки модбас попадают в Exception. в буфере ничего искать не нужно.

kolyan
10.12.2013, 19:35
Если ведомый отключен то запрос завершиться по таймауту. В этом нет ничего страшного. единственное (так как таймаут много больше времени обмена) обмен с первыми двумя приборами будет замедлен. Так что если знаете что прибор сейчас отключен то с ним лучше не общяцо иканеш.



Здравствуйте!
Вопрос в следующем. Есть мастер (ПЛК-73) и 3 слэйв устройства. Протокол Modbus ASCII.
Как сделать, чтобы при пропадании питания на одном из слэйв устройств не пропадала связь с двумя остальными?
Пытаюсь отключать питание на одном из слэйвов, но тайм-аут не возникает... Не пойму поэтому, по какому параметру отслеживать отсутствие связи со слэйв модулем.
Можно хоть какой-нибудь примерчик попросить работы ПЛК-63 или ПЛК-73 с несколькими слэйв устройствами?

Валенок
10.12.2013, 19:51
по какому параметру отслеживать отсутствие связи со слэйв модулем.


Все ошибки модбас попадают в Exception. в буфере ничего искать не нужно.
(для modbus.lib)

PS
Что касается таймаута - нет смысла его выдерживать более 1.5-2 обычных задержек с конкретного слейва (речь о овенских слейвах). Этого более чем достаточно для определения - ответит или нет.
Если не мудрить с задержками на самих слейвах, а ставить всегда Rs.dL = 0..1 (нафик больше ?), то реальные задержки от модели - 5..10мс. И таймаут более 10..20мс не нужен (+ длина самого запроса/ответа ессно)

kolyan
11.12.2013, 07:52
А конкретный примерчик можно?

__________________________________________________ __________________________________________________ ___
Моя часть программы, отвечающая за опрос 3-х slave устройств (радиомодемы с дискретными входами\выходами) во вложении.
Всё работает, но при пропадании питания любого из slave устройства, не формируется никаких ошибок,
Exception равен нулю.
Не пойму, как при этом исключить из опроса "неисправный" модуль. Но так, чтобы при подаче питания на него, он вновь включался в опрос.

kolyan
11.12.2013, 18:34
Неужели никаких вариантов?:confused:

amn
11.12.2013, 21:29
Здравствуйте kolyan. Я что-то не увидел, где у Вас в программе отслеживаются ошибки. Как вы узнали, что они не формируются?

Где-то попадалось на форуме, что исключить отключенное устройство совсем не получится. Можно опрашивать его намного реже, чтобы не тормозить всю сеть, а когда оно будет снова подключено перейти на обычный опрос. Определить отключенное устройство можно по таймауту. Для этого надо отслеживать ошибки в программе.

kolyan
12.12.2013, 11:47
Спасибо за ответ!
Действительно, в данном варианте программы нет отслеживания ошибок.

Попытки были в других вариантах, но проблема вся в том, что исключения по превышению тайм-аута формируются и при обычной (нормальной) работе, просто их длительность меньше, чем при отключенном слэйв устройстве (или его неисправности).
Была мысль с помощью таймера отслеживать длительные появления исключений по тайм-ауту, но нормального результата не добился, т.к. и при отключенном слэйве исключения имеют хаотичный (разный от раза к разу) характер.

Ещё раз спасибо, что откликнулись.

amn
12.12.2013, 12:12
При отключенном устройстве ошибки будут постоянно. При работающем "иногда" будут проскакивать нормальные посылки.

А что если попробовать использовать счетчик. Если исходить из того, что при нормальной работе проходит какое-то количество битых посылок, считаем их, пока не пройдет нормальная посылка. Экспериментально выясняем максимально возможное количество битых посылок при нормальной работе. Далее в программе контролируем количество битых посылок и если превысит количество, характерное для нормальной работы, то значит устройство отключено.

kolyan
12.12.2013, 12:54
Скорее всего, так и придётся сделать.
Печально, что нет подобного контроля в составе самой библиотеки.
Хотя, если взять тот же ОРС сервер Lectus - там никаких проблем. Пишет "переменная плохого качества" ( как-то же определяет!) - и продолжает опрос других модулей.
________________________________________

Спасибо за совет!

kolyan
12.12.2013, 15:45
Тема закрыта, всем спасибо!