PDA

Просмотр полной версии : MODBUS COM отслеживание записи в канал



RomeoVar
22.06.2021, 11:56
Добрый день
Пытаюсь разобраться с таймингами записи по каналу MODBUS. Прошу помощи и консультации
Суть задачи: в рамках проекта нужно гарантировать запись параметров в устройства подключенные по MODBUS COM.
Решил работать через стандартный функционал (о других не знал), настроил все каналы (смотрите во вложении).
Стал разбираться с опциями цикла шины и не совсем понятно как происходит чтение - запись в/из канала. В документации все туманно, четких временных границ по записи/чтению нет. В частности изложено так

"...По умолчанию данный параметр имеет значение <не задано>. Это означает, что в качестве
задачи цикла шины используется задача проекта с наименьшим временем цикла (обычно такой
задачей является задача MainTask).
20
4. Задачи и коммуникационные драйверы
Таким образом, если в проекте есть задача с адекватными временем цикла (например,
для протокола Modbus – 10…20 мс) – то описанные выше настройки задач всех Modbusкомпонентов можно оставить в значениях по умолчанию, и при этом никаких проблем с обменом
не возникнет.
С другой стороны, если пользователь, например, увеличит время задачи MainTask до 100
мс (и при этом в проекте не будет задач с меньшим временем цикла) – то обмен будет работать
некорректно (с точки зрения пользователя опрос будет медленным, часть ответов slave-устройств
будет пропущена)."

А так как мне нужно определить время последней записи/чтения по каналу я решил создать отдельную задачу MODBUS_HANDLER, установить для него "адекватный" циклический вызов (18 мс). И приоритет где-то больше 15. При таких настройках я вообще ничего не отлавливаю. Время не фиксируется даже по тем каналам которые опрашиваются каждые 100мс, а по фронту не записываются с первого раза вообще. Нужно выполнить 2-3 попытки чтобы выполнить запись. Я уменьшил цикл вызова до 6мс с самым низким приоритетом, и "о чудо" все заработало. Пишется с первого раза и отлавливаются все события.
Теперь вопрос - насколько корректна такая реализация чтения/записи в/из шины?

Евгений Кислов
22.06.2021, 12:16
Добрый день.


Теперь вопрос - насколько корректна такая реализация чтения/записи в/из шины?

Что вы вкладываете в понятие "корректность" и каковы ее критерии?

RomeoVar
25.06.2021, 10:09
Корректность использования ресурсов ПЛК согласно его технической спецификации. У меня возникли сомнения. Почему?
В документации указано что время цикла задачи к которой привязан обмен по MODBUS считается адекватным если его значение лежит в пределах 18-20 мс. А у меня так не получается.
Более того, чтобы получить информацию о том как прошел обмен по определенному каналу нужен программный обработчик, т.к. информация из переменных iChannelIndex xDone xError нигде не сохраняется. И если произошла ошибка при чтении/записи по одному из каналов, я этого никак не увижу.
Соответственно в моем понимании это нужно сделать так,:
1. Отдельная задача с циклом 4-6 мс и приоритетом 30 в которой будет обрабатываться результат обмена по каналу и результат записываться в массив
Что-то типа

RTRIG_RolDone(CLK := ROL_DORNA.xDone);
RTRIG_JawsDone(CLK := JAWS_DORNA.xDone);
RTRIG_PushDone(CLK := FR_D720.xDone);
IF RTRIG_RolDone.Q THEN
GVL.ltD_ChLastRW[roller_drive][ROL_DORNA.iChannelIndex] := TargetVars.stRtc.ltSystemTick;
END_IF
IF RTRIG_JawsDone.Q THEN
GVL.ltD_ChLastRW[jaw_drive][ROL_DORNA.iChannelIndex] := TargetVars.stRtc.ltSystemTick;
END_IF
IF RTRIG_PushDone.Q THEN
GVL.ltFR_ChLastRW[FR_D720.iChannelIndex] := TargetVars.stRtc.ltSystemTick;
END_IF

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

Также подобную реализацию можно повесить на событие (переменная xDone), но про такое в документации вообще написано "ни-ни, это плохо"

Вот:

3. Не назначайте задачам тип Свободное выполнение или Статус.
4. Не изменяйте интервалы вызова и приоритеты задач, которые CODESYS добавляет
автоматически.
5. В проекте должна присутствовать хотя бы одна задача с адекватным в рамках вашей системы
управления интервалом вызова (обычно такой задачей является MainTask, которая вызывается с
интервалом не менее 20 мс).
6. Не редактируйте в компонентах Modbus задачу цикла шины

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

Отсюда вопрос и сомнения

Евгений Кислов
25.06.2021, 10:25
Корректность использования ресурсов ПЛК согласно его технической спецификации. У меня возникли сомнения. Почему?
В документации указано что время цикла задачи к которой привязан обмен по MODBUS считается адекватным если его значение лежит в пределах 18-20 мс. А у меня так не получается.

В этой статье еще, например, указано следующее:



1. Не добавляйте в проект задачи (используйте только задачи, автоматически создаваемые
CODESYS).
2. Если вы добавляете в проект задачу – то должны четко понимать, как именно реализована
обработка многозадачности в CODESYS для используемого вами ПЛК и уметь ясно ответить на
вопрос, зачем именно вы создаете эту задачу.

...



На вашем скриншоте видно, что в проекте есть 5 задач, созданных вручную.

Кроме того, на скриншоте видно, что как минимум для одного slave-устройства настроено ~20 запросов циклического чтения c периодом опроса 100 мс.
Учитывая другие устройства - вероятно, в проекте их еще больше.
Если прочитать спецификацию Modbus - то станет понятно, что уложиться в такие интервалы времени невозможно (*для драйвера Modbus, реализованного согласно спецификации).


Суть задачи: в рамках проекта нужно гарантировать запись параметров

Гарантия записи параметров - после записи сделать чтение и сравнить значения. Всё остальное - это надежда на что-то.

RomeoVar
25.06.2021, 11:47
В этой статье еще, например, указано следующее:

Гарантия записи параметров - после записи сделать чтение и сравнить значения. Всё остальное - это надежда на что-то.

Именно так я и делаю - после записи читаю и сравниваю. НО! Это мне непонятно:

Кроме того, на скриншоте видно, что как минимум для одного slave-устройства настроено 20 запросов циклического чтения c периодом опроса 100 мс.
Вы говорите о периоде опроса 100мс. А в настройках канала указано что это таймаут ответа. Нужно ли понимать что ответило - ли устройство, нет-ли пока не истекут 100мс. следующий запрос отправлен не будет? Если да, то зачем такое? И в документации опять-же об этом ни слова. Я для себя, ввиду отсутствия информации, опытным путем предположил следующий алгоритм. По выбранному каналу идет обмен, если в течении 100мс ответ не получен, переходим к следующему каналу, а если ответ получен, переходим к опросу следующего канала не дожидаясь окончания таймаута.
Кстати измерения показывают нечто подобное. В моей задаче, неважно какой, происходит запись в каналы устройства по триггерной переменной. в задаче цикла шины, с периодом 6 мс. я отслеживаю время последней записи в канал и в массив. Результаты на скрине, в каналы с 6 по 23, а это как минимум 17 каналов, происходит в промежутке с 32.641 мс до 33.865 мс, это равно 1,224 секунды, т.е. в среднем 72 милисекунды. На самом деле была запись в большее количество каналов, (часть запросов идет циклически через 100 мс.) поэтому эта цифра еще меньше. А интервалы между записью в каналы фактические лежат в пределах 10 - 20 мс. Значит таймаут все-таки применяется только при отсутствии ответа от устройства.
Но если опираться на Ваше утверждение получается цикл должен занимать 2,6 секунды. Вот как-то так.

RomeoVar
25.06.2021, 11:56
На вашем скриншоте видно, что в проекте есть 5 задач, созданных вручную.
Я об этом тоже упомянул, я сознательно не последовал рекомендациям. Т.к. мне непонятно почему нельзя (если конечно я понимаю зачем я это делаю), если такая возможность есть?
Но это к сути вопроса по обмену не относится.

Евгений Кислов
25.06.2021, 12:01
Вы говорите о периоде опроса 100мс. А в настройках канала указано что это таймаут ответа.

У вас на скриншоте видно "цикл., t#100ms". Это период опроса и он не имеет никакого отношения к таймауту.
Но я ошибся в числе запросов - на скриншоте их видно 10, а не 20. Сколько у вас их всего в проекте - я, конечно, не знаю, но предполагаю, что больше.


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

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


И в документации опять-же об этом ни слова.

Не соглашусь.

55737


Но если опираться на Ваше утверждение получается цикл должен занимать 2,6 секунды.

Процитируйте мое "утверждение", пожалуйста, из которого вы сделали такой вывод.


Т.к. мне непонятно почему нельзя (если конечно я понимаю зачем я это делаю), если такая возможность есть?

См. п. 2 в процитированном (https://owen.ru/forum/showthread.php?t=34988&p=358770&viewfull=1#post358770) тексте.


Я об этом тоже упомянул, я сознательно не последовал рекомендациям. ... Но это к сути вопроса по обмену не относится.

Т.е. вы не следуете рекомендациям из документа и ваш вопрос в том, почему наблюдаемое вами поведение не соответствует некоторым оценкам, приводимым в документе.
Понятно.

RomeoVar
25.06.2021, 13:01
Ну вобщем Вы перевернули с ног на голову. Я изложил суть задачи, и спросил мнения эксперта о ее корректности.
По поводу этого:

Кроме того, на скриншоте видно, что как минимум для одного slave-устройства настроено ~20 запросов циклического чтения c периодом опроса 100 мс.
Если Вы обратите внимание это циклический опрос ТОЛЬКО НА ЧТЕНИЕ, и меня ЭТИ таймауты не интересуют. Меня интересует проверка записи, а запись осуществляется по триггерной переменной. И меня интересовала обработка, т.е. проверка записи. Я ее реализовал так, как описал, через отдельную задачу и поинтересовался, насколько такой подход корректен? А Вы ответили вопросом на вопрос.

RomeoVar
25.06.2021, 13:06
Т.е. вы не следуете рекомендациям из документа и ваш вопрос в том, почему наблюдаемое вами поведение не соответствует некоторым оценкам, приводимым в документе.
Понятно.
О каком поведении Вы говорите?
Если о том что не происходит запись в канал? Тут я думаю уже разобрался - я слишком рано сбрасываю триггерную переменную записи в FALSE. Это я в принципе устранил

RomeoVar
25.06.2021, 13:07
Просто Вы как-то раздраженно отвечаете. Я ведь пока не экперт, я только изучаю контроллер.

Евгений Кислов
25.06.2021, 13:34
Просто Вы как-то раздраженно отвечаете.

Это не так. Мне искренне жаль, если вам так показалось.


Если Вы обратите внимание это циклический опрос ТОЛЬКО НА ЧТЕНИЕ, и меня ЭТИ таймауты не интересуют.

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


А Вы ответили вопросом на вопрос.

К сожалению, не на все вопросы (особенно сложные) удается ответить сразу - иногда требуется сначала что-то уточнить.


Тут я думаю уже разобрался - я слишком рано сбрасываю триггерную переменную записи в FALSE. Это я в принципе устранил

Тогда давайте определимся - какой вопрос у вас сейчас остался?
Почему "вообще ничего не отлавливается" в задаче с периодом вызова 18 мс и отлавливается всё - в задаче с периодом вызова 6 мс?
Если я правильно интерпретировал вопрос - то выложите ваш проект, пожалуйста, и инструкцию, как с его помощью определить, отлавливаются ли события или нет.

RomeoVar
25.06.2021, 13:56
Вобщем с Вашей помощью в проблеме я разобрался.
Еще раз, кратко, у меня идет обмен по MODBUS с устройствами. Часть каналов опрашиваются циклически с периодом 100мс. из них осуществляется только чтение, запись туда не осуществляется. Это информативные значения.
В остальные каналы осуществляется запись только по триггерной переменной. Чтение из этих каналов также по триггерной переменной, но чтение, в принципе, нужно только чтобы убедиться что параметр в канал записан.
Я предполагал что 200мс (цикл вызова задачи визуализации) будет достаточно чтобы записать данные во все каналы. Я почему-то так решил. Поэтому в одном из циклов я триггер поднимал, а уже в следующем сбрасывал.
Но если прикинуть в среднем на обмен по одному каналу требуется около 20 мс. А я пишу сразу по 10-15 параметров в 2 устройства. Соответственно это 30*20 = 600 мс. минимум. Т.е. все параметры не успели записаться, а я уже флаг сбросил.
Таким образом я установил задержку на сброс триггерной переменной, чтобы все параметры успели гарантировано записаться.

Жаль только что нельзя получить инфу выполнилась ли запись в канал или нет через системную переменную. Т.е. вроде как переменные есть, но они динамически меняются и если пакетов много, что записалось - не отловить.

А вопрос теперь остался один - переменная xError если происходит ошибка при обмене, как долго держит свое значение TRUE?

Евгений Кислов
25.06.2021, 14:09
А вопрос теперь остался один - переменная xError если происходит ошибка при обмене, как долго держит свое значение TRUE?

Формально - она держит свое значение в течение того времени, пока на входе xExecute экземпляра ФБ запроса (ФБ ModbusChannel) остается значение TRUE.
На практике обычно (но не гарантированно) этим временем является один цикл задачи, в которой происходит обмен.


Жаль только что нельзя получить инфу выполнилась ли запись в канал или нет через системную переменную. Т.е. вроде как переменные есть, но они динамически меняются и если пакетов много, что записалось - не отловить.

С помощью стандартных средств это действительно сделать затруднительно - поэтому обычно в таких случаях используют каналы с типом Приложение или библиотеку OwenCommunication.

RomeoVar
25.06.2021, 18:23
С помощью стандартных средств это действительно сделать затруднительно - поэтому обычно в таких случаях используют каналы с типом Приложение...
В настройках канала Есть параметр "Триггер" с вариантами, цикл., передний фронт и приложение. Вы это имели в виду?
В онлайн справке CODESYS об этом ничего не пишут. И здесь "CDSv3.5_Modbus_v2.0.pdf" ничего нет.
Где можно почитать или может есть видео с информацией по этому поводу?
Спасибо
Насчет OwenCommunication перейти пока не могу. Слишком много переписывать

Евгений Кислов
25.06.2021, 19:01
Вы это имели в виду?

Да.


Где можно почитать или может есть видео с информацией по этому поводу?

Простой пример здесь, и дальше смотрите на входы-выходы, которые есть у ModbusChannel (они вам уже знакомы):
https://faq.codesys.com/pages/viewpage.action?pageId=24510480


И здесь "CDSv3.5_Modbus_v2.0.pdf" ничего нет.

Не соглашусь - там та же ссылка, что я привел выше.

55743

RomeoVar
25.06.2021, 19:27
Да, я на эту библиотеку смотрел IoDrvModbus только я почему-то решил что ее к каналам не "прикрутить", только программно, а у меня уже было все настроено через каналы. А так-то да, она должна мне помочь
Спасибо

RomeoVar
04.07.2021, 22:04
Попробовал я ModbusChannel. При скорости обмена 38400 статус xDone FB не отлавливается. Но дело в том, что у меня настроены каналы на 3 типа: циклический опрос, по переднему фронту и в приложении. Так вот, по переднему фронту, при программной обработке я статус записи отлавливаю, а при записи через приложение - никак не могу. Может это как-то связано с тем что у меня есть каналы, которые опрашиваются по переднему фронту?
Могу сбросить пример проекта, чтобы было понятно о чем я.

Евгений Кислов
05.07.2021, 04:49
Попробовал я ModbusChannel. При скорости обмена 38400 статус xDone FB не отлавливается. Но дело в том, что у меня настроены каналы на 3 типа: циклический опрос, по переднему фронту и в приложении. Так вот, по переднему фронту, при программной обработке я статус записи отлавливаю, а при записи через приложение - никак не могу. Может это как-то связано с тем что у меня есть каналы, которые опрашиваются по переднему фронту?
Могу сбросить пример проекта, чтобы было понятно о чем я.

Выложите пример проекта, удалив из него всё, что не касается рассматриваемого вопроса.

RomeoVar
05.07.2021, 08:13
Вот пример. Каналы с 69 по 74.
Я пытался по всякому ловить xDone. И по триггеру и по состоянию. Никак не получилось. Но через 30 мс. переменнная обновляется

Евгений Кислов
05.07.2021, 09:11
Вот пример. Каналы с 69 по 74.
Я пытался по всякому ловить xDone. И по триггеру и по состоянию. Никак не получилось. Но через 30 мс. переменнная обновляется




IF xRdPosReg THEN
xSuccess := FALSE;
wIntPosPOld := GVL.stServo[1].stRdServo.wP700_IntPosP;
GVL.stServo[1].stWrServo.wP700_IntPosP := 4610;
GVL.stServo[1].stWrServo.wP765_IntPosDZT := 1000;
fbModbusRol(slave := ROL_DORNA, xExecute := xRdPosReg (*!*), iChannelIndex := iCurrentCh);
ltTimeOfStart := TargetVars.stRtc.ltSystemTick;
xRdPosReg := FALSE;
xCount := TRUE;
iCntr := iCntr + 1;
END_IF


См. выделенную строку.
Вы, видимо, считаете, что fbModbusRol выполняется синхронно за один цикл контроллера - поэтому сразу после вызова прерываете его работу.
Но это не так - блок работает асинхронно.
Поэтому нужно дождаться сигнала на выходе xDone и только потом прекращать его работу.
См. демонстрацию:
https://dropmefiles.com/G7YW7

RomeoVar
05.07.2021, 12:54
я делал и так, и асинхронно. Это остался последний вариант, в котором я считал кол-во циклов, через которое данные запишутся в переменную из канала.
Происходит так - подымаешь флаг execute , xbusy поднимается в true. Данные записываются в переменную (примерно 30мс), a xbusy висит, xdone не поднимается. Пока опять не запишешь в xexecute TRUE. Могу видео записать


Вот как-то так выходит

Я грешу на конфликт каналов с разными параметрами обмена. Или слишком высокая скорость обмена. У Вас в видео 9600, для моих задач этого мало

Пол дня вчера на исследование этой темы ухлопал, и остался на месте.
Сначала я сделал по рекомендации, Ваше видео посмотрел. Неа, ниче не работает

Евгений Кислов
05.07.2021, 13:10
я делал и так, и асинхронно. Это остался последний вариант, в котором я считал кол-во циклов, через которое данные запишутся в переменную из канала.
Происходит так - подымаешь флаг execute , xbusy поднимается в true. Данные записываются в переменную (примерно 30мс), a xbusy висит, xdone не поднимается. Пока опять не запишешь в xexecute TRUE. Могу видео записать


Вот как-то так выходит

Я грешу на конфликт каналов с разными параметрами обмена. Или слишком высокая скорость обмена. У Вас в видео 9600, для моих задач этого мало

Пол дня вчера на исследование этой темы ухлопал, и остался на месте.
Сначала я сделал по рекомендации, Ваше видео посмотрел. Неа, ниче не работает

Вы точно посмотрели видео из моего предыдущего поста?
В нём ваш проект со скоростью 38400 и исправленным кодом - и ловится каждый импульс xDone.

RomeoVar
07.07.2021, 08:36
Проблема, похоже была в этом куске кода (с 8 по 11 строки).
Было так:


IF fbModbusRol.xExecute THEN
fbModbusRol(slave := ROL_DORNA, xExecute := FALSE, iChannelIndex := iCurrentCh);
END_IF


Сейчас я изменил на такой


IF fbModbusRol.xExecute THEN
fbModbusRol.xExecute := FALSE;
END_IF


Спасибо.
Буду проверять на рабочем проекте

RomeoVar
07.07.2021, 08:49
Да, я увидел свой прокол
Но очень странно. В документации четко написано (по переднему фронту xExecute). Передний фронт был. Т.е. нужно было дождаться сигнала xDone и только потом прекращать вызов функционального блока. Т.е. операции чтения/записи и формирования сигналов выполняются ...
Все, понял. Спасибо.

RomeoVar
07.07.2021, 08:53
Нужно было делать так:


RTRIG_fbMbRolDone(CLK := fbModbusRol.xDone);

IF RTRIG_fbMbRolDone.Q THEN
xSuccess := TRUE;
fbModbusRol.xExecute := FALSE;
xRdPosReg := FALSE;
END_IF

IF xRdPosReg THEN
//xSuccess := FALSE;
wIntPosPOld := GVL.stServo[1].stRdServo.wP700_IntPosP;
GVL.stServo[1].stWrServo.wP700_IntPosP := 4610;
GVL.stServo[1].stWrServo.wP765_IntPosDZT := 1000;
fbModbusRol(slave := ROL_DORNA, xExecute := xExecModbus, iChannelIndex := iCurrentCh);
ltTimeOfStart := TargetVars.stRtc.ltSystemTick;
//xRdPosReg := FALSE;
xCount := TRUE;
iCntr := iCntr + 1;
END_IF

DenisV
07.07.2021, 12:39
55910
Вырезка из той же статьи. А что значит потеря части ответов? Значения будут переданы не верно или просто не переданы?

Как я заметил, интервал выполнения задач очень сильно влияет на производительность и загрузку процессора.
А если происходит управление не критичной системой, то есть, где допустИм большой интервал ответа устройства. Можно ли как-то изменив интервал задач создаваемых Codesys как-то оптимизировать процесс и отдать предпочтение например более быстрой работе визуализации или в целом меньшей загрузке процессора?

Евгений Кислов
07.07.2021, 12:44
55910
Вырезка из той же статьи. А что значит потеря части ответов? Значения будут переданы не верно или просто не переданы?

Как я заметил, интервал выполнения задач очень сильно влияет на производительность и загрузку процессора.
А если происходит управление не критичной системой, то есть, где допустИм большой интервал ответа устройства. Можно ли как-то изменив интервал задач создаваемых Codesys как-то оптимизировать процесс и отдать предпочтение например более быстрой работе визуализации или в целом меньшей загрузке процессора?

Если у вас период опроса = 100 мс, таймаут = 1000 мс и период вызова задачи = 1000 мс - то, вероятно, ни одного ответа от slave-устройства вы в программе не увидите.
Это как пример.


Можно ли как-то изменив интервал задач создаваемых Codesys как-то оптимизировать процесс и отдать предпочтение например более быстрой работе визуализации или в целом меньшей загрузке процессора?

Скажем так, повлиять на этот процесс вы сможете (приоритеты и интервалы вызова задач доступны пользователю для изменения).

DenisV
07.07.2021, 14:08
Скажем так, повлиять на этот процесс вы сможете (приоритеты и интервалы вызова задач доступны пользователю для изменения).
В то же время согласно статье этого не рекомендуется делать, без четкого понимания своих действий. Пока к сожалению не могу сказать этого о себе, также сложно понять допустимые пределы настроек для нормальной работы. Может вы можете дать несколько советов по настройкам и оптимизации конкретного проекта? Может тогда мне удастся осознать всю концепцию.
Master-TCP Master Таймаут ответа 1000мс
AO_D1(МУ210-501) - мин.период опроса 200 мс
AI_D2 (МВ210-101) - мин.период опроса 600 мс
AI_D3 (МВ210-101) - мин.период опроса 600 мс
AI_D4 (МВ210-101) - мин.период опроса 600 мс

Интервалы MainTask=20мс, AlarmManagerTask=50мс, OwenCloudTask=100, Visu_task=100
Приоритеты по умолчанию.
5591155912

Как можно в данном случае снизить нагрузку на процессор и немного увеличить скорость работы визуализации, пожертвовав скоростью опроса.

P.S И должна ли частота обновления экрана соответствовать интервалу выполнения задачи VISU_TASK для лучшего быстродействия ?

Евгений Кислов
07.07.2021, 14:17
также сложно понять допустимые пределы настроек для нормальной работы.

Это и правда сложно - потому что для этого нужно сформулировать критерии "нормальной работы".


Как можно в данном случае снизить нагрузку на процессор и немного увеличить скорость работы визуализации, пожертвовав скоростью опроса.

Можете попробовать для AlarmManagerTask поставить 200 мс, для MainTask = 50 мс, для VISU_TASK приоритет = 30.


P.S И должна ли скорость выполнения задачи VISU_TASK соответствовать частоте обновления экрана ?

Желательно, чтобы сооответствовала или хотя бы была кратна.

RomeoVar
07.07.2021, 14:26
Пока я отлаживал моменты взаимодействия с Modbus у меня возник такой вопрос.
Специфика моей работы такова, что я с реальным контроллером взаимодействую 2*2 (2 дня работаю, 2 выходной). Мне в голову пришла мысль Взять SoftPLC ( Например CODESYS Control Win V3 ) , MasterOPC Universal Modbus, 2 USB адаптера RS485 (CH340g).
У меня получилось так:
CODESYS Control Win V3 - Добавил Com-порт, привязал к первому адаптеру 485 (порт № 5). Настроил модбас, добавил устройство.
MasterOPC Universal Modbus - настроил ка Slave, привязал ко второму адаптеру (порт №8)
Запускаю - все вроде работает, пакетами обмениваются, только при попытке записать или считать записанные значения в/из тэга MasterOPC Universal Modbus приходят нули.
Я опять где-то косячу? Или это все-таки ограничение CODESYS. Т.к. если такая фича прокатит можно к любому компу "прикрутить" модуль ввода вывода, работающего по modbus и фактически получить SoftPLC?
Заранее признателен
Если нужно позже могу записать видео, как чего я делал

DenisV
07.07.2021, 14:44
Это и правда сложно - потому что для этого нужно сформулировать критерии "нормальной работы".
Можете попробовать для AlarmManagerTask поставить 200 мс, для MainTask = 50 мс, для VISU_TASK приоритет = 30.


Да согласен, у каждого своя "нормальная работа" )

Огонь, спасибо! При этих настройках именно тот эффект, которого я хотел добиться.

RomeoVar
07.07.2021, 21:25
Еще раз большое спасибо. После того как подправил код работы через приложение:


RTRIG_fbMbRolDone(CLK := fbModbusRol.xDone);

IF RTRIG_fbMbRolDone.Q THEN
xSuccess := TRUE;
fbModbusRol.xExecute := FALSE;
xRdPosReg := FALSE;
END_IF

IF xRdPosReg THEN
//xSuccess := FALSE;
wIntPosPOld := GVL.stServo[1].stRdServo.wP700_IntPosP;
GVL.stServo[1].stWrServo.wP700_IntPosP := 4610;
GVL.stServo[1].stWrServo.wP765_IntPosDZT := 1000;
fbModbusRol(slave := ROL_DORNA, xExecute := xExecModbus, iChannelIndex := iCurrentCh);
ltTimeOfStart := TargetVars.stRtc.ltSystemTick;
//xRdPosReg := FALSE;
xCount := TRUE;
iCntr := iCntr + 1;
END_IF

В режиме эмуляции Modbus тоже начал очень даже хорошо работать.
Тему закрыть можно, но вдруг возникнут еще вопросы. Пусть еще пару дней повисит

RomeoVar
08.07.2021, 08:27
А есть ли в CODESYS механизм (функциональный блок, свойство, метод) позволяющий получить индекс канала, привязанного к переменной? Очень было-бы полезно

Евгений Кислов
08.07.2021, 08:49
А есть ли в CODESYS механизм (функциональный блок, свойство, метод) позволяющий получить индекс канала, привязанного к переменной? Очень было-бы полезно

Это не канал привязывается к переменной, а переменная к каналу.
Такого механизма нет.

RomeoVar
08.07.2021, 10:43
В итоге пришел я к OwenCommunication. Прийдется переписать немного (ну не так уж и немного) код. По другому все криво получается.
Зато опыт (сын ошибок трудных)

RomeoVar
08.07.2021, 13:44
Спрошу еще в своей теме:
Есть массив структур, делаю инициализацию структур значенями по умолчанию. Хочу чтобы эти значения были защищены от изменения. Возможно ли такое?
Код (один из элементов массива):


TYPE MB_SWORD :
STRUCT
iChannelIndex : INT;
uiDataAddr : UINT;
uiDataCount : UINT := 1;
wData : WORD;
END_STRUCT
END_TYPE

Присвоенное значение хочу защитить от изменения
uiDataCount : UINT := 1;
Можно ли это сделать?

Евгений Кислов
08.07.2021, 13:59
Спрошу еще в своей теме:
Есть массив структур, делаю инициализацию структур значенями по умолчанию. Хочу чтобы эти значения были защищены от изменения. Возможно ли такое?
Код (один из элементов массива):


TYPE MB_SWORD :
STRUCT
iChannelIndex : INT;
uiDataAddr : UINT;
uiDataCount : UINT := 1;
wData : WORD;
END_STRUCT
END_TYPE

Присвоенное значение хочу защитить от изменения
uiDataCount : UINT := 1;
Можно ли это сделать?

Не дублируйте свои посты, пожалуйста.
https://owen.ru/forum/showthread.php?t=30595&p=359527&viewfull=1#post359527