PDA

Просмотр полной версии : Обработка отсутствия одного из приборов Modbus_Slave



EgorL
22.07.2025, 12:17
Коллеги, подскажите пожалуйста, как решить вот такую задачу:
СПК207 мастер над несколькими СИ30. Время от времени некоторые из них не в сети по разным причинам.
При этом происходят недопустимые задержки в обработке данных. Задержка между счётом СИ30 и отображением на контроллере до 5 секунд. (если удалить из проекта отсутствующий прибор, то мгновенно).
Как правильно обрабатывать счётчики не в сети, чтобы программа не ждала, но, чтобы, в то же время, при включении станка, данные начинали обрабатываться без перезагрузки?

Cs-Cs
22.07.2025, 12:23
1. Правильно настроить таймауты в Modbus.
Потому что ПЛК делает запрос, потом ждёт таймаут, и потом идёт дальше опрашивать. Если таймаут стоит на 1 секунду (так по умолчанию) - то ВЕСЬ опрос будет вставать на эту секунду.
2. Сделать программное отключение устройств из опроса через xEnable (по имени слейва; если надо подробно - я распишу). Это позволит ВООБЩЕ выключить их из опроса. Но тогда надо и не забыть включить.

В остальном вроде всё. Modbus - это протокол с последовательным опросом. И там всегда будет так, что проблемное устройство будет тормозить обмен.

EgorL
22.07.2025, 12:52
1. Сколько лучше поставить таймаут для линии из 32 СИ30? или где прочитать про расчёт этого?

2. Буду очень признателен.

как-то так:

IF NOT Modbus_Master_COM_Port.xAllSlavesOk THEN
Modbus_Slave_SI30_1.Enable := NOT Modbus_Slave_SI30_1.xError;
Modbus_Slave_SI30_2.Enable := NOT Modbus_Slave_SI30_2.xError;
END_IF

но тогда можно ли обращаться по типу (или вообще как то перечислить всё количество):

var1 := CONCAT('Modbus_Slave_SI30_', INT_TO_STR(i));
ModbusSlaveComPort_Diag(var1).Enable...

Валенок
22.07.2025, 17:48
1.Таймаут - время реального(самостоятельно засечь) опроса + 5..15мс
2.Зачем выключать опросы непонятно. Для "мертвых" увеличить период опроса до 3...6 сек и исключить от них запросы друг за другом. Ответил - ставьте нужный период. Умирание - несколько битых запросов подряд, но в порядке общей очереди.
И никаких торможений.

EgorL
23.07.2025, 07:41
2.Зачем выключать опросы непонятно. Для "мертвых" увеличить период опроса до 3...6 сек и исключить от них запросы друг за другом. Ответил - ставьте нужный период. Умирание - несколько битых запросов подряд, но в порядке общей очереди.
Как период изменить? У "Modbus_Slave" только "SetCommunicationState" со START STOP RESET.
Как очерёдность опросов можно изменить?
Как в цикле обращаться ко всем СЛЕЙВам?
Мне бы принципы понять. Первый раз контроллер в руки взял.

Cs-Cs
23.07.2025, 09:12
Валенок Он через конфигурацию ПЛК рабоатет. Там период опроса не увеличишь.
Если только делать опрос по триггеру из кода - но я не знаю, нужно ли такое советовать.

EgorL Да я как раз и хотел сказать, что по именам слйевов можно через xEnable их выключать.
Но как потом включать - хз.

Валенок
23.07.2025, 09:16
Он через конфигурацию ПЛК рабоатет. Там период опроса не увеличишь.
Если только делать опрос по триггеру из кода - но я не знаю, нужно ли такое советовать.

(Ну на безрыбье)
Момент окончания запроса и его результат известен? Или тоже нет ничего?

Cs-Cs
23.07.2025, 09:22
(Ну на безрыбье) Момент окончания запроса и его результат известен? Или тоже нет ничего?
Конкретно в 3.5 (как у него) всё от 2.3 отличается. В ТЕОРИИ известен, если программа успеет отловить xDone и xError
Если запросы очень короткие - то не успеет отловить.

Ну, в общем, если он напишет по твоему совету опрос по триггеру и будет дёргать его через условный BLINK вс разными периодами - то прокатит.
ИМХО, если я верно понял, тут сама задача в корне не верна:
* Если нужен быстрый опрос - то нефиг отключать устройства и создавать таймауты
* Если устройства могут отключаться - то тогда это надо делать через какое-то меню станка, чтобы НЕ опрашивать их.
А остальное - костыли.

EgorL
23.07.2025, 09:38
Сделал вот так. Формально оно работает, но... Наверное действительно это решение для периода аварийного отсутствия станка в сети, после чего оператору надо будет в меню СЛК отключать и включать станок.

MyTimer(IN:=TRUE, PT:=T#15S, Q=>xTimerFlag);

IF xTimerFlag = TRUE THEN
// Попробовать включить выключенные СЛЕЙВы
IF NOT Modbus_Slave_SI30_1.Enable THEN
Modbus_Slave_SI30_1.Enable := TRUE;
END_IF
MyTimer(IN := FALSE);
MyTimer(IN := TRUE, PT:=T#15S, Q=>xTimerFlag);
xTimerFlag := FALSE;
END_IF
.....

IF NOT Modbus_Master_COM_Port.xAllSlavesOk THEN
Modbus_Slave_SI30_1.Enable := NOT Modbus_Slave_SI30_1.xError;
Modbus_Slave_SI30_2.Enable := NOT Modbus_Slave_SI30_2.xError;
END_IF

Подскажите, как всё таки можно в цикле перебирать все слейвы?

Валенок
23.07.2025, 10:22
В ТЕОРИИ известен, если программа успеет отловить xDone и xError
Если запросы очень короткие - то не успеет отловить..
Что значит если успеет? Оно может подняться и опуститься между пользовательскими циклами?

EgorL
23.07.2025, 12:15
в цикле перебирать все слейвы?
Похоже нельзя.
Даже попробовал при инициализации присвоить все слейвы в массив, чтобы потом в коде просто перебирать его, но не получилось: ModbusSlaveComPort_Diag не поддерживет присвоение.
Грусть-печаль.:confused:

Cs-Cs
23.07.2025, 14:47
Что значит если успеет? Оно может подняться и опуститься между пользовательскими циклами?Ага. Я на это нагорал.
Не знаю, как было в 2.3 (подскажи, если точнее мен помнишь), в 3.5 ошибка скидывается, когда он опрашивает следующий канал устройства.
Ну то есть, если набить в Slave три запроса - то на каждый запрос будет так:
* Скинули ошибку
* Сделали запрос
* Если был таймаут - выставили ошибку
* Скинули
* Сделали второй запрос
...и поэтому, если запросы короткие (1 регистр) - то можно и не поймать

Емельянов Кирилл
24.07.2025, 01:12
Похоже нельзя.
Даже попробовал при инициализации присвоить все слейвы в массив, чтобы потом в коде просто перебирать его, но не получилось: ModbusSlaveComPort_Diag не поддерживет присвоение.
Грусть-печаль.:confused:

Канал приложение в помощь. Или библиотеки

EgorL
24.07.2025, 13:39
Канал приложение в помощь. Или библиотеки
О чём речь идёт? Можете более развёрнуто пояснить?

Валенок
24.07.2025, 18:45
Не знаю, как было в 2.3.
Там надо постаратся чтоб получить время цикла большее чем самый быстрый запрос. Это про конфигурацию. Про бибки и говорить смысла нет.
Но даже через конфигурацию можно отловить момент чтения а-ля "OnRecv“

Емельянов Кирилл
25.07.2025, 02:17
О чём речь идёт? Можете более развёрнуто пояснить?

https://m.youtube.com/watch?v=elizZ9l_-sw

VladimirVRN
31.08.2025, 23:25
Доброго времени суток!

А может для решения проблемы использовать библиотеку OwenCommunication?