Вход

Просмотр полной версии : Modbus.lib - часто отваливается порт по ошибке EXC_HW в блоке MB_UNI_IO



Millyvolt2
29.08.2024, 23:56
Всем здравствуйте!

Почти год назад у меня была проблема, запостил здесь, ответа тогда не получил:
https://owen.ru/forum/showthread.php?t=37710&page=3&p=421411&viewfull=1#post421411

На тот момент конфигурация была такова - две линии RS-485 ПЛК110, на одной сидят 9 драйверов SMSD Modbus, все двигатели работают параллельно, все команды драйверам в реалтайме поступают по MODBUS RTU на скорости 115200. На второй линии СП307, и частотник, который ограничивает скорость до 19200. При этом ошибка EXC_HW вылетала в среднем 1 раз в 45 минут, что не влияло на рабочий процесс и было в целом малозаметно.
Первая линия работает на библиотеке Modbus.lib, вторая настроена через конфигуратор в Codesys 2.3.

Затем в конфигурации второй линии была увеличена скорость до 115200 (убрали частотник), и добавлена пара сотен регистров, половина на запись, половина на чтение. Читаются регистры СП307 со временем опроса 150 мс, запись по изменению параметра. После данных изменений ошибка EXC_HW стала вылетать раз в 5 минут в среднем, что теперь является существенной проблемой.

Если посмотреть код блока MB_UNI_IO, то видно что ошибка EXC_HW вылетает в случае неудачной записи в порт, то есть в первой части транзакции MODBUS, посылке от мастера к слейву.

Просьба помочь разобраться, может кто-нибудь сталкивался с данной ошибкой?

Samel
24.04.2025, 12:42
Добрый. Тоже столкнулся с ошибка EXC_HW в библиотеке Modbus.lib.


Read := SysComWrite(ComHandle, ADR(DataBuf), DataSize, 0) = DataSize;
IF Read = FALSE THEN (* передача кадра не состоялась*)
Exception := EXC_HW; (* аппаратная ошибка *)
Complete := TRUE; (* установить признак готовности результата *)
Active := FALSE; (* снять признак активности цикла обмена *)
RETURN; (* завершение по ошибке *)
END_IF

Т.е. проблема с записью через SysComWrite.
Может есть решение данной проблемы?

Валенок
24.04.2025, 13:03
Обычно такие решения начинаются с самого проекта.
Ну вот почему не ушло просто в буфер? Порт закрыт, не настроен, буфер забит.. Ещё есть варианты?

Samel
24.04.2025, 13:53
Порт закрыт, не настроен, буфер забит.. Ещё есть варианты?
1. Сообщения в в линию уходят - могу предположить что порт открыт и настроен.
2. При остановке опроса или изменении периода опроса - на линии тишина. Т.е. буфер пустой.

Валенок
24.04.2025, 23:44
..Сообщения в в линию уходят
Вы это чем то видели?


---
тупо проверил

Порт закрыт, не настроен..
Из *Write* возвращается 0 и => EXC_HW

.. буфер забит
Из *Write* возвращается размер того что смогло впихнутся, а если меньше чем хотели (но необязательно 0) и => EXC_HW



2. При остановке опроса или изменении периода опроса - на линии тишина. Т.е. буфер пустой.
Из этого можно еще сделать вывод что толпа на входе* упорядочилась и всем стало хватать времени.
*а это вполне возможно при не связанных между собой вызовах ФБ из modbus.lib. Проект же вы не выложили.

Samel
25.04.2025, 12:30
На линии RS485-2 весит 1 устройство, снимается 1 параметр раз 100мс(время можно менять - не на что не влияет)

Вы это чем то видели?

Только косвенно, по лампочкам на устройстве. Но если после RX идет индикация на TX - устройство получает пакет и на него отвечает.
Период RX/TX соответствует периоду опроса устройства. Если бы буфер был забит - была бы дискотека на индикаторе RX.

Валенок
25.04.2025, 12:58
Если бы буфер был забит - была бы дискотека на индикаторе RX.
так забитый буфер это один из вариантов. а модбас.lib не рулит портом, а пользуется им как дыркой куда не глядя пихает/берет данные. Рулите дыркой - Вы. И как - никто не знает. Проекта - нет.

Что касается забитости буфера, да и вообще, раз уж влезли в модбас.lib, то никто же не мешает поставить программную ловушку ошибки типа:

...
X:= SysComWrite(ComHandle, ADR(DataBuf), DataSize, 0); (*X - DINT*)

if X <> DataSize then
какой-то флажок поднять; (*а в основном коде по этому флажку посмотреть X. Если <= 0 проблемы с портом. Его кто-то закрыл? Если <> 0 - забит буфер*)
end_if

Read := (*SysComWrite(ComHandle, ADR(DataBuf), DataSize, 0)*)
X = DataSize;
...

Samel
30.04.2025, 14:56
Продолжим.
На объекте 3 шкафа с ПЛК110-30/60[М2]; используются оба 485; в основном подключены модули расширения и преобразователи частоты, в среднем от 3 до 10 устройств. Все это замечательно работает уже больше 3 мес. На один из шкафов 2 недели назад подключили нонэйм устройство(период опроса 100мс, $01 $03 $00 $00 $00 $08 $44 $0C) - после 2-6 часов работы вываливается EXC_HW в библиотеке Modbus.lib, на втором интерфейсе 5 ПЧ - полет нормальный.
До объекта пока так и не доехал. Так что пока все со слов наладчиков.
На столе поставил 2 ПЛК: один просто опрашивает "тишину", второй - эмулирует устройство через "modbus slave.exe". За неделю проблему так и не словил.
Помехи или "нонэйм" устройство?
Сегодня на столе решил "пошуметь в линию" (подкинулся в линию 485преобразователем и циклически кидаю байты). Через несколько минут пакеты начинают уходить с задержкой между байтами, потом только 1 байт пакета и ловим EXC_HW(SysComWrite возвращает 1, т.е. забит буфер передачи).
Возникает вопрос, почему SysComWrite(Операционка/ядро плк) не выплевывает содержимое буфера? У ПЛК на это достаточно времени.

Samel
07.05.2025, 15:46
Продолжил экспериментировать.


IF (COM_READY = TRUE )THEN

IF RxUse THEN
WHILE SysComRead(comPort, ADR(rxDataBuf[0]), 200 , 0) <> 0 DO;
END_WHILE
END_IF

TxCheck(IN := TRUE, PT := TxPeriod);
IF TxCheck.Q AND TxUse THEN
FOR i := 1 TO DWORD_TO_INT(TxSizeSend) BY 1 DO
TxDataBuf[i-1] := TxInd;
IF TxIndUse THEN
TxInd := TxInd + 1;
END_IF
END_FOR;
TxDataSize := DWORD_TO_BYTE(SysComWrite(comPort, ADR(TxDataBuf), TxSizeSend, 0));
IF TxDataSize <> TxSizeSend THEN
outDO2 := TRUE;
ELSE
outDO2 := FALSE;
END_IF
TxCheck(IN := FALSE);
END_IF

END_IF

Цикл ПЛК - 5 мс. Настройки порта - 19200,8,N,1.
Работа с "мусором на линии" от 30 - 60 мин.
Результат:83673

Валенок
07.05.2025, 17:42
Буфер забивается. Кто бы мог подумать
Проекта нет (2)

Samel
07.05.2025, 21:11
Буфер забивается. Кто бы мог подумать
Проекта нет (2)
Весь проект постом выше. Почему данные из буфера(переполненного) не уходят в линию?
Скорость - 19200; 8 байт передаются за 5 мс. У нас период отправки 50 мс.

Samel
07.05.2025, 22:08
Какая логика работы буфера SysComWrite? Пока есть данные отправлять? Или другая логика?

Валенок
07.05.2025, 22:09
Весь проект постом выше..
Выше только куски кода. Проекта нет (3)

Samel
07.05.2025, 22:14
Выше только куски кода. Проекта нет (3)

Так в проекте больше ничего :)

Samel
07.05.2025, 22:28
Проект:
TxUse - разрешить отправку данных;
TxPeriod - период отправки данных;
TxSizeSend - размер отправляемых данных;

RxUse - разрешить чтение буфера приема.

Валенок
07.05.2025, 22:34
Проект:.
если это пост#9, даже смотреть не буду т.к

..У ПЛК на это достаточно времени ....8 байт передаются за 5 мс ...
у эльфов. Они думают что если купили 200 упаковок по 12 яиц, то у них 2400 яйца

Исходный проект

Валенок
07.05.2025, 22:46
.8 байт передаются за 5 мс ... от 30 - 60 мин.
достаточно линии работать всего лишь в 0.9998 от эльфийского идеала чтоб за 30 минут буфер переполнился.

Обычная задача про бассейн. Труба втекает. Труба вытекает.

Samel
07.05.2025, 22:49
достаточно линии работать всего лишь в 0.9998 от эльфийского идеала чтоб за 30 минут буфер переполнился.

При таких условия буфер не переполниться! И не надо сюда тянуть всяких эльфов.

Samel
07.05.2025, 22:56
Обычная задача про бассейн. Труба втекает. Труба вытекает.

В бассейн раз в 50 мс поступает 8 л воды и 8 л воды вытекает за 5 мс. Переполниться ли бассейн?

Samel
07.05.2025, 22:58
Тут вопрос в другом. Почему бассейн не опустошается при закрытии входной трубы?

Samel
07.05.2025, 23:10
Переполнения буфера в этом проекте можно сделать за несколько прогонов, поставить TxSizeSend = 200. Но при изменении размера оправляемых данных или увеличении периода отправки флаг переполнения снимается и все продолжает работать. Я же говорю о ситуации когда наступает момент, что буфер принимает только 1 байт( и в линию оправляется только 1 байт) и изменение периода и размера данных ни на что не влияют. При сбросе плк в линию сразу уходит весь буфер около 512 байт

Валенок
07.05.2025, 23:11
При таких условия буфер не переполниться!.
Легко. Вы уверены что кадр в железке прям таки 11 (8n1) бит а не всегда 12 для простоты организации работы со стоп-битами ?

Валенок
07.05.2025, 23:12
Переполнения буфера в этом проекте можно сделать за несколько прогонов, поставить TxSizeSend = 200.
3
........


весь буфер около 512 байт
511 софт + 16 хард
вытекает из простейших замеров

Samel
07.05.2025, 23:14
50 мс — 19200/12/20 = 80 байт

Samel
07.05.2025, 23:21
Должны ли данные из буфера уйти в линию при переполнении, или они там блокируются? В линию уходят все данные из буфера, или только то количество которое последний раз в него записалось?

Валенок
07.05.2025, 23:25
50 мс — 19200/12/20 = 80 байт
//5 мс — 19200/12/200 = 8 байт
ну вот теперь посчитайте теперь не 12 а (12 * 0.9998 ну такое среднее) и

Обычная задача про бассейн. Труба втекает - 12 . Труба вытекает 12 * 0.9998 .
Когда через край?

Samel
07.05.2025, 23:28
//5 мс — 19200/12/200 = 8 байт
ну вот теперь посчитайте теперь не 12 а (12 * 1.0002 ну такое среднее) и

Когда через край?
Почему 5мс если у нас 50.
В бассейн раз в 50 мс поступает 8 л воды и 8 л воды вытекает за 5 мс

Валенок
07.05.2025, 23:34
Почему 5мс если у нас 50
пост #9

а исходного проекта нет (4)

//1.002 или 0.9998 - что куда смысл поняли думаю

Samel
07.05.2025, 23:35
Пост #15. Проект

Валенок
07.05.2025, 23:41
Это исходный или эксперименты из п#9 ?

Samel
07.05.2025, 23:44
Это тестовый проект, на котором вылазит некорректная работа SysComWrite.

Валенок
07.05.2025, 23:49
Это тестовый проект, на котором вылазит некорректная работа SysComWrite.
Если тестовый из #9, то смысл смотреть. По бассейн - выше.
Раз уж экпериментите, то из Rs-1 (8/5мс или 80/50мс или 504/315мс) в Rs-2 переливайте. На одном "счетчик расхода", на другом "прихода"
Ну а динамическую разницу на экран.

Samel
07.05.2025, 23:58
Какая логика работы буфера SysComWrite? Пока есть данные отправлять? Или другая логика? Должны ли данные из буфера уйти в линию при переполнении, или они там блокируются? В линию уходят все данные из буфера, или только то количество которое последний раз в него записалось?
Есть ответы на эти вопросы?

Валенок
08.05.2025, 00:03
Есть ответы на эти вопросы?
Есть данные - отправляются. Тока зачем ждать идеал? В момент прерывания по "железный буфер свободный" может какая-нить задача выпонятся более приоритетная. Rs не обязан прям старт бит за стоповым.


В линию уходят все данные из буфера, или только то количество которое последний раз в него записалось?
Странный вопрос. Фифо.

Samel
08.05.2025, 00:06
Есть данные - отправляются. Тока зачем ждать идеал? В момент прерывания по "железный буфер свободный" может какая-нить задача выпонятся более приоритетная. Rs не обязан прям старт бит за стоповым.


Странный вопрос. Фифо.
Ну значит все это не работает! Пост #21

Валенок
08.05.2025, 00:08
Ну значит все это не работает! Пост #21
На него есть #23
Что запихнулось то и уйдет

Samel
08.05.2025, 00:10
На него есть #23
Что запихнулось то и ушло
А если запихнулось и не ушло? Что делать?

Валенок
08.05.2025, 00:15
Может в церковь сходить?
Или, как я, у Овена специальные ПЛК заказывать. На них всё уходит

Samel
08.05.2025, 00:23
Может в церковь сходить?
Или, как я, у Овена специальные ПЛК заказывать. На них всё уходит

У меня таких ПЛК нет.

Валенок
08.05.2025, 00:26
У вас наверное обычный

--
))