-
Вложений: 3
DEBUG#07. В чем причина ошибки "Processor load watchdog of all IEC-tasks detected"?
Вопрос: в процессе работы контроллера иногда возникает ошибка "Processor load watchdog of all IEC-tasks detected". В чем причина ее появления?
Вложение 50794 Вложение 50795
Ответ: данная ошибка означает, что сработал сторожевой таймер, который контролирует загрузку CPU и генерирует исключение, если она в течение нескольких секунд превышает 99%.
Этот механизм, в частности, используется для детектирования возникновения бесконечного цикла в программе пользователя.
В редких случаях превышение загрузки ЦПУ может быть вызвано внешними факторами - например, сетевым штормом.
В подобных ситуациях остановка работы контроллера может быть нежелательной (если допускается остановка выполнения программы на ограниченный интервал времени).
Для отключения генерации исключения в подобных ситуациях - нужно подключиться к контроллеру через утилиту WinSCP и отредактировать файл CODESYSControl.cfg, который расположен в рабочей директории контроллера (пути к рабочей директории для разных контроллеров см. в документе CODESYS V3.5. FAQ). В файле в секции [CmpSchedule] следует присвоить параметру ProcessorLoad.Maximum значение 0 и перезапустить CODESYS (в web-конфигураторе: ПЛК - Настройки - Перезапустить CODESYS).
Вложение 50796
-
Вложений: 3
COM12. Проблемы с опросом Modbus Serial Slave устройств через МКОН
Вопрос: контроллер настроен в режиме Modbus TCP Master. Необходимо реализовать опрос устройств на шине RS-485, подключенных к контроллеру через конвертер протоколов МКОН. Для каждого slave-устройства в проект добавлен компонент Modbus TCP Slave. Во всех компонентах указан и один и тот же IP-адрес и порт, и разные Unit ID, соответствующие адресам слэйвов на шине RS-485. Проблема в том, что в CODESYS каждый компонент Modbus TCP Slave создает отдельное подключение, а МКОН поддерживает только два одновременных подключения, то есть опросить больше двух слэйвов таким образом невозможно. Как можно решить эту проблему?
Вложение 50820
Ответ: при работе с преобразователями протоколов Modbus TCP/Modbus RTU необходимо добавлять в проект только один компонент Modbus TCP Slave, а уже в него - нужное количество компонентов Modbus Slave COM Port. В этом случае контроллер установит с конвертером протоколов только одно соединение.
Вложение 50821
См. видеопример.
Обратите внимание: в текущих версиях CODESYS присутствует баг, из-за которого при возникновении любой ошибки обмена с устройством Modbus Slave COM Port, добавленным в компонент Modbus TCP Slave, его опрос больше не производится.
Для решения проблемы необходимо реализовать сброс ошибок в коде:
Код:
PROGRAM PLC_PRG
VAR
fbConfirmError: R_TRIG;
fbConfirmError1: R_TRIG;
fbConfirmError2: R_TRIG;
END_VAR
// Modbus_Slave_COM_Port, Modbus_Slave_COM_Port_1, Modbus_Slave_COM_Port_2 - имена компонентов из дерева проекта (см. скриншот выше)
fbConfirmError(CLK := Modbus_Slave_COM_Port.xError, Q => Modbus_Slave_COM_Port.xConfirmError);
fbConfirmError1(CLK := Modbus_Slave_COM_Port_1.xError, Q => Modbus_Slave_COM_Port_1.xConfirmError);
fbConfirmError2(CLK := Modbus_Slave_COM_Port_2.xError, Q => Modbus_Slave_COM_Port_2.xConfirmError);
Ошибка исправлена в CODESYS V3.5 SP17.
Вложение 56833
-
COM13. Как интегрировать контроллер с Telegram-ботом?
Вопрос: как интегрировать контроллер с Telegram-ботом?
Ответ: см. пример.
В нем демонстрируется:
- отправка сообщений от контроллера боту;
- отправка файлов от контроллера боту;
- чтение последнего сообщения, отправленного пользователем в чат с ботом.
Требуемая версия прошивки контроллера: 1.2.07xx.xxxx или выше
В примере демонстрируется использование утилит curl и jq, вызываемых через ФБ библиотеки CmpSysExec.
В примере используются библиотеки OwenStringUtils и VisuKeyboard_En-ru (библиотека русскоязычной клавиатуры).
https://owen.ru/product/codesys_v3/libraries
Пользователь может доработать пример под конкретную задачу, используя документацию о Telegram API.
-
Вложений: 1
PRG#22. Как считать серийный номер USB-накопителя, подключенного к контроллеру?
Вопрос: как считать серийный номер USB-накопителя, подключенного к контроллеру?
Ответ: см. пример.
Вложение 51143
Если накопитель не подключен, то будет выведена информация о flash-памяти контроллера.
-
Вложений: 1
VISU#22. Как сделать так, чтобы диалог открывался рядом с кнопкой его вызова?
Вопрос: при выборе диалога можно настроить его открытие либо по центру экрана, либо по заданным координатам.
Требуется настроить диалоги в проекте так, чтобы они открывались рядом с кнопками, нажатием на которые они вызываются.
Это можно сделать через вариант с заданными координатами, но потребуется вручную вычислять координаты для каждой кнопки.
Можно ли как-то избежать этого?
Ответ: в данном случае в качестве координат открытия диалога можно указать системные переменные ptMouse.iX и ptMouse.iY - они соответствуют координатам последнего нажатия в визуализации.
При этом в настройках визуализации должен быть установлен режим масштабирования Фиксировано.
Вложение 51532
-
Вложений: 3
COM#14. Почему при работе с шаблонами настройки Mx210 сбрасываются на заводские?
Вопрос: в проекте используются шаблоны модулей Mx210. Настройки модулей задаются через ОВЕН Конфигуратор.
Но при подключении модулей к контроллеру настройки их входов/выходов сбрасываются на заводские. В чем может быть проблема?
Ответ: при использовании шаблонов Mx210 не надо настраивать входы/выходы модулей через ОВЕН Конфигуратор - нужно делать это прямо в CODESYS в настройках шаблона на вкладке Конфигурация.
Вложение 51937
Настройки будут записываться:
- при загрузке проекта из CODESYS;
- при запуске контроллера;
- в случае потери и восстановления связи.
Для шаблона МВ210-101 запись настроек можно отключить - это требуется, чтобы изменять настройки входов в процессе работы контроллера с помощью каналов вкладки Соотнесение входов-выходов.
Вложение 51938 Вложение 51939
-
Вложений: 2
COM#15. Почему значения в каналах Modbus отображаются серым?
Вопрос: при настройке обмена по Modbus в дереве проекта не отображается ошибок (горят зеленые кружочки), но сами значения в каналах являются нулевыми и отображаются серым.
В чем может быть проблема?
Вложение 52146
Ответ: так происходит, если к каналам не привязаны переменные или привязанные переменные не использюутся в программе.
Самый простой способ избежать таких ситуаций - для параметра Всегда обновлять переменные установить значение Вкл. 2 (Всегда в задаче цикла шины).
В этом случае значения в каналах всегда будут "активными".
Вложение 52147
-
OTHER#09. Можно ли использовать для ПЛК ОВЕН платные компоненты из CODESYS Store?
Вопрос: можно ли при работе с контроллерами ОВЕН использовать дополнительные платные компоненты и библиотеки из CODESYS Store, которые требуют программного (Soft Container) или аппаратного (WIBU key) лицензирования?
Ответ: в настоящий момент такая возможность отсутствует.
Поддержка Soft Container запланирована в одной из следующих прошивок.
-
COM#16. Как работать с OwenCloud через API?
Вопрос: есть ПЛК, который подключен к сети с доступом в интернет, и другое устройство, которое находится на удаленном объекте.
У ПЛК нет доступа к сети этого объекта (или сеть там вообще отсутствует), но устройство подключено к облачному сервису OwenCloud.
Возможно ли как-то с ПЛК считывать/записывать параметры этого устройства?
Ответ: да, это возможно с помощью API OwenCloud. См. пример и видео.
При переносе примера на ПЛК2xx в ФБ WRITE_PARAMATER потребуется изменить значение константы c_sPathToFile на:
Код:
c_sPathToFile: STRING := '/root/CODESYS/send_data.json';
Документация на API:
https://api.owencloud.ru/
-
OTHER#10. Как организовать удаленный доступ к ПЛК из CODESYS для загрузки проектов?
Вопрос: можно ли организовать удаленный доступ к ПЛК из CODESYS для загрузки проектов?
Ответ: да, это возможно. См. более подробную информацию и данные для доступа к демонстрационному ПЛК в этом посте.
-
Вложений: 3
PRG#23. Как использовать функции для работы со временем из библиотеки Util?
Вопрос: в библиотеке Util есть ряд функций для работы со временем (JoinDateTime, SplitDateTime и т.д.), в которых значение системного времени представляется переменной типа ULINT.
Как конвертировать это значение в переменную типа DT?
Вложение 53881
Ответ: функции библиотеки представляют системное время в виде числа миллисекунд, прошедших с полуночи (00:00:00 UTC) 1 января 1970 года - то есть это вариация UnixTime с тем отличием, что UnixTime представляет время в виде числа секунд. Тип DT хранит время в формате UnixTime.
Поэтому при работе с функциями библиотеки надо делить (для выхода функции JoinDateTime) или умножать (для входа функции SplitDateTime) значение на 1000:
Вложение 53882 Вложение 53883
-
COM#17. Как настроить контроллер в режиме Slave по нестандартному протоколу обмена?
Вопрос: требуется заменить специфический контроллер, который раньше работал в режиме Slave и управлялся утилитой на ПК, которая отправляла команды по нестандартному символьному протоколу.
Как настроить контроллер с CODESYS V3.5 для работы в таком режиме?
Ответ: см. пример и видео.
-
Вложений: 2
DEBUG#08. Что делать, если системное время периодически отображается без учета UTC?
Вопрос: в алгоритме программы используется значение системного времени контроллера.
Периодически (с бессистемной периодичностью, но не менее одного раза за 10 минут работы) происходит кратковременный (продолжительностью не более нескольких сотен миллисекунд) "выброс" системного времени.
Во время "выброса" значение системного времени отображается (и обрабатывается в коде программы) без учета часового пояса (в узле OwenRTC в канале UTC Offset в этот момент отображается 0 - несмотря на то, что фактически в настройках контроллера часовой пояс задан отличным от нуля).
Как можно устранить эти "выбросы"?
Вложение 54157
Комментарий: эта ситуация обычно наблюдается в проектах с использованием OwenArchiver и в сложных проектах с большим количеством ФБ.
В данный момент у нас нет точной информации о причинах возникновении этой проблемы. Во время исследования нескольких пользовательских проектов, в которых проблема проявлялась - она исчезала при удалении из проекта части функционала (в одном из случаев таким функционалом была библиотека, разработанная пользователем).
Ответ: в качестве варианта решения этой проблемы мы разработали ФБ RTC_FILTER, который позволяет отфильтровывать "выбросы" cистемного времени.
Ниже приведена ссылка на пример использования этого ФБ.
Общий принцип работы блока: пока вход xEnableFilter имеет значение TRUE, то блок находится в работе и на выходе dtFilteredDateAndTime отображается значение входа dtDateAndTime с отфильтрованными "выбросами".
Т.е. даже во время "выброса" на выходе ФБ будет корректное значение системного времени с учетом часового пояса.
Скачать пример: https://ftp.owen.ru/CoDeSys3/99_Foru...projectarchive
На скриншоте - синим выделено значение канала Hour узла OwenRTC с "выбросами" системного времени, зеленым - выход блока RTC_FILTER с отфильтрованнным значением системного времени.
Вложение 54158
-
Вложений: 1
VISU#23. Как изменить язык по умолчанию в клавиатурах библиотеки OwenVisuDialogs?
Вопрос: диалоги KeypadOwen и KeypadOwenBig из библиотеки OwenVisuDialogs по умолчанию открываются с англоязычной раскладкой и нижним регистром.
Как сделать так, чтобы диалог открывался с русскоязычной раскладкой и верхним регистром?
Ответ: откройте Менеджер библитек и задайте значения переменных в списке параметров KeypadDefaultLanguage:
Вложение 54389
- LANG.ENG_LC - англоязычная раскладка, нижний регистр
- LANG.ENG_UC - англоязычная раскладка, верхний регистр
- LANG.RUS_LC - русскоязычная раскладка, нижний регистр
- LANG.RUS_UC - русскоязычная раскладка, верхний регистр
-
Вложений: 1
VISU#24. Как сделать скриншот web-страницы и отобразить его в визуализации?
Вопрос: как сделать скриншот web-страницы и отобразить его в визуализации?
Ответ: контроллер не имеет встроенных средств для снятия скриншотов web-страниц.
Но если он подключен к сети с доступом в Интернет - то можно воспользоваться одним из интернет-сервисов для снятия скриншотов.
См. пример, основанный на использовании сервиса ScreenshotMachine.
Для использования API сервиса требуется пройти регистрацию: https://www.screenshotmachine.com/re...php?button=api
Вложение 54731
Примечание: сервис не может использоваться для снятия скриншотов web-визуализации самого контроллера.
-
Вложений: 1
COM#18. Как получить информацию о погоде?
Вопрос: как получить в ПЛК информацию о текущей погоде?
Ответ: см. пример. В примере демонстрируется получение информации о погоде с помощью сервиса https://openweathermap.org/
(соответственно, контроллер должен быть подключен к интернету).
Вложение 55186
-
Вложений: 1
VISU#25. Как программно обработать результат закрытия диалога ввода? (Numpad, Keypad)
Вопрос: необходимо в коде программы определить, по нажатию на какую кнопку (OK или CANCEL) был закрыт диалог Numpad или Keypad.
Это требуется, например, чтобы при вводе нового значения (с помощью нажатия на кнопку OK) однократно произвести его валидацию.
Каким образом это можно сделать?
Ответ: для диалогов библиотеки OwenVisuDialogs (NumpadOwen, NumpadOwenBig, KeypadOwen, KeypadOwenBig) начиная с версии 3.5.14.3 добавлена возможность получения информации о результате закрытия диалогов.
Для этого используется переменная g_stClosedDialogInfo из списка глобальных переменных DialogsSettings.
Переменная является структурой типа OwenDialogClosingInfo и включает следующие поля, содержащие информацию о последнем закрытом диалоге:
Вложение 55395
- xIsDialogClosed (BOOL) - флаг закрытия диалога. Принимает значение TRUE при закрытии любого из упомянутых выше диалогов.
Сбрасывается в FALSE автоматически при открытии любого из упомянутых диалогов или вручную из программы пользователя. - wsDialogTitle (WSTRING) - заголовок закрытого диалога
- eDialogType (перечисление OwenDialog_TYPE) - тип закрытого диалога (NUMPAD или KEYPAD)
- eDialogClosingResult (перечисление OwenDialogClosed_RESULT) - результат закрытия диалога (т.е. кнопка диалога, по нажатию на которую он был закрыт - OK или CANCEL)
Библиотека и пример использования доступны по ссылке:
https://owen.ru/forum/showthread.php...l=1#post348262
См. также другой пример, в котором демонстрируется более сложный, но универсальный вариант получения результата закрытия любого диалога.
-
Вложений: 1
VISU#26. Как считать информацию о пользователях визуализации в переменные программы?
Вопрос: в проекте используется управление пользователями визуализации (Менеджер визуализации - Управление пользователями).
Необходимо считать информацию о созданных пользователях в переменные программы (например, чтобы потом управлять ими из кода).
Как это можно сделать?
Ответ: см. пример.
Вложение 55502
Если вы используете CODESYS V3.5 SP17 Patch 3 с плагином визуализации 4.3.0.0 или выше - то см. этот пример и информацию из п. 2.7 данного документа.
-
Вложений: 2
VISU#27. Проблемы с отображением длинных строковых переменных в визуализации
Вопрос: есть ли какие-нибудь ограничения по длине строковых переменных, отображаемых в визуализации?
В нашем проекте переменная типа WSTRING обрезается на 1249 символах. Можно ли как-то обойти это ограничение?
Ответ: для отображения строк в визуализации используется буфер для форматирования текста.
По умолчанию размер буфера составляет 2500 байт - этого хватает для вывода переменных типа STRING длиной до 2499 символов и переменных типа WSTRING длиной до 1249 символов.
Для увеличения размера буфера нужно создать программу со следующим кодом:
Код:
PROGRAM VisuSetStringBuffer
VAR
END_VAR
// Выделяем буфер для форматирования строк визуализации на 10000 байт (можно указать своё значение)
// его хватит для STRING(9999) или WSTRING(4998)
VisuElems.VisuFctConfigureTextBufferSize(10000);
Вложение 55518
В Менеджере визуализации привяжите эту программу во вкладке Вызов после запуска визуализации (привязывать ее к какой-либо задаче не надо):
Вложение 55519
-
Вложений: 3
PRG#24. CAA Memory и работа с памятью
При обработке данных, реализации протоколов и в других задачах часто требуются манипуляции с памятью.
Базовые функции для работы с памятью доступны в библиотеке CAA Memory.
Вложение 55522
В частности, в ней расположены две крайне часто используемые функции - MemMove (копирование данных, аналог memmove из С) и MemFill (заполнение области памяти, аналог memset из С).
Ниже приведены примеры вызова функций для работы с экземпляром структуры SOME_DATA.
Код:
TYPE SOME_DATA :
STRUCT
iVar: INT;
rVar: REAL;
byVar: BYTE;
lwVar: LWORD;
END_STRUCT
END_TYPE
Код:
PROGRAM PLC_PRG
VAR
stSomeData: SOME_DATA := (iVar := 11, rVar := 22.33, byVar := 42, lwVar := 16#DEADCAFEDEADCAFE);
abyBuffer: ARRAY [0..255] OF BYTE;
xCopy: BOOL;
xClear: BOOL;
END_VAR
Функция MemMove копирует uiNumberOfBytes байт из области памяти, размещенной по указателю pSource, в область памяти, размещенную по указателю pDestination.
Области памяти могут перекрываться.
Код:
IF xCopy THEN
MEM.MemMove(pSource := ADR(stSomeData), pDestination := ADR(abyBuffer), uiNumberOfBytes := SIZEOF(stSomeData) );
xCopy := FALSE;
END_IF
Вложение 55520
Обратите внимание на "разрывы" в массиве. Они связаны с тем, что переменные в структурах располагаются с учетом выравнивания памяти.
Для контроля выравнивания можно использовать атрибут pack_mode:
https://help.codesys.com/webapp/_cds...rsion=3.5.17.0
Функция MemFill "заполняет" область памяти размером uiLength байт по указателю pMemoryBlock значением byFillValue.
Код:
IF xClear THEN
MEM.MemFill(pMemoryBlock := ADR(stSomeData), uiLength := SIZEOF(stSomeData), byFillValue := 0);
xClear := FALSE;
END_IF
Вложение 55521
-
Вложений: 4
PRG#25. Привязка переменных к каналам компонентов дерева проекта
Формально привязка переменных к каналам компонентов в дереве проекта может быть произведена двумя способами:
1. Привязкой к каналу уже существующей переменной (маппированием) - с помощью ввода имени этой переменной или ее выбором через ассистент ввода (для этого надо нажать на кнопку "...").
Вложение 55721
2. Вводом имени еще несуществующей переменной - тогда в проекте будет автоматически объявлена неявная глобальная переменная с этим именем.
В зависимости от выбранного способа в столбце Соотнесение будет отображаться соответствующая иконка: для способа 1 - "стрелка", для способа 2 - "лампочка".
В подавляющем большинстве случаев рекомендуется использовать только способ 1.
Из-за автообъявления переменных в каналах компонентов при загрузке проекта могут периодически (без систематики) возникать ошибки - из-за того, что карта адресов таких переменных может быть сформирована некорректно.
Особенно часто это наблюдается при автообъявлении переменных типа BIT и ARRAY.
Примеры ошибок:
Вложение 55719 Вложение 55720
Поэтому настоятельно рекомендуется использовать только способ 1 - то есть привязывать к каналам уже заранее объявленные переменные.
Вложение 55722
-
COM#19. Как настроить проброс портов для ПЛК2хх?
Вопрос: как настроить проброс портов для ПЛК2хх, чтобы использовать контроллер в качестве шлюза между сетями?
Ответ: см. статью.
-
PRG#26. Ограничение библиотеки CmpSysExec на длину команды и способ его обхода
ФБ библиотеки CmpSysExec используются для вызова утилит Linux (например, curl).
Длина команды, подаваемой на вход блока, ограничена 255 символами.
Примечание: в версии библиотеки 3.5.17.31 добавлен блок SysExecute5, который позволяет работать с командами длиной до 2047 символов.
В некоторых случаях этого может оказаться недостаточно - например, когда в теле команды передается текст длинного сообщения или значения множества параметров REST API запроса.
В такой ситуации можно записать текст во временный файл (см. пример) и использовать этот файл как аргумент при вызове curl.
Код:
// текст сообщения передается как аргумент команды
curl -s -X POST https://api.telegram.org/bot1395641168:AAFMoUpthm5W_wnQEPR6-dNsP4Hah0S2-8c/sendMessage -d "chat_id=721952499" -d "text=123"
// текст сообщения сохраняется в файл, который передается как аргумент команды
curl -s -X POST https://api.telegram.org/bot1395641168:AAFMoUpthm5W_wnQEPR6-dNsP4Hah0S2-8c/sendMessage -d "chat_id=721952499" -d "text=$(cat /home/root/CODESYS_WRK/message.txt)"
-
PRG#27. Файловые плейсхолдеры
При работе с файлами с помощью библиотек CAA File и SysFile часто требуется указывать путь к конкретной директории - например, директории сервера web-визуализации, USB-накопителю и т.д.
Эти пути могут отличаться для разных моделей ПЛК и разных прошивок - поэтому запомнить все их вариации довольно сложно.
Вместо этого проще использовать плейсхолдеры (заместители).
В этом случае CODESYS сам заменит плейсхолдер на путь к нужной директории.
Следует учитывать, что плейсхолдеры обрабатываются только упомянутыми библиотеками (например, их нельзя использовать при работе с библиотекой CmpSysExec).
Плейсхолдеры CODESYS:
- $$PlcLogic$$ - директория проекта CODESYS;
- $$visu$$ - директория файлов визуализации (одновременно с этим - директория сервера web-визуализации);
- $$trend$$ - директория файлов трендов;
- $$alarms$$ - директория файлов тревог.
Специфичные плейсхолдеры для контроллеров ОВЕН:
- $$USB$$ - корневая директория USB-накопителя;
- $$SD$$ - корневая директория SD-накопителя;
- $$FTP$$ - директория FTP-сервера.
Пример использования плейсхолдеров:
Код:
hFile := SysFile.SysFileOpen('$$visu$$/test.txt', SysFile.ACCESS_MODE.AM_APPEND_PLUS, ADR(dwRes) );
SysFile.SysFileWrite(hFile, ADR(sData), TO_UINT(LEN(sData)), ADR(dwRes) );
SysFile.SysFileClose(hFile);
-
VISU#28. Как переключить экран в фрейме из кода программы?
Вопрос: как переключить экран, отображаемый в элементе Фрейм, из кода программы?
Ответ: см. пример.
Если вы используете CODESYS V3.5 SP17 Patch 3 с плагином визуализации 4.3.0.0 или выше - то см. этот пример и информацию из п. 5 данного документа.
-
VISU#29. Работа с тревогами из кода программы (AlarmManager)
-
Вложений: 4
COM#20. Как отмасштабировать значение, считываемое по Modbus?
Вопрос: в проекте настроен опрос других устройств по протоколу Modbus через стандартные компоненты. Считываются целочисленные значение, и согласно документации их нужно домножить на 0.01, чтобы получить "настоящее" значение в формате REAL. Можно ли это выполнить это масшабирование на уровне настройки компонентов Modbus?
Ответ:
1. Необходимо создать ФБ для конвертации данных. В рамках примера он будет называться CONVERT.
Перед объявлением ФБ необходимо указать атрибут io_function_block, а перед объявлением его переменной, которая будет привязываться к компоненту Modbus - io_function_block_mapping.
Код:
{attribute 'io_function_block'}
FUNCTION_BLOCK CONVERT
VAR_INPUT
{attribute 'io_function_block_mapping'}
wInput: WORD;
END_VAR
VAR_OUTPUT
rOutput: REAL;
END_VAR
VAR
END_VAR
rOutput := wInput * 0.01;
2. В компоненте Modbus на вкладке Соотнесение входов/выходов выберите нужный канал (нужно выделить конкретный регистр - тип WORD)
и нажмите кнопку Добавить ФБ для IO-канала.
Вложение 56796
В выпадающем окне нужно выбрать ФБ CONVERT.
Вложение 56797
В результате в столбце Соотнесение отобразится соответствующая пиктограмма, а в столбце Переменная будет автоматически сформирован путь к неявно объявленному экземпляру ФБ.
Вложение 56798
3. С помощью этого пути можно обратиться к выходной переменной ФБ в коде программы (убрав из пути узел Application):
Код:
PROGRAM PLC_PRG
VAR
rValue1: REAL;
rValue2: REAL;
END_VAR
rValue1 := Modbus_Slave_COM_Port_CONVERT.rOutput;
rValue2 := Modbus_Slave_COM_Port_CONVERT_1.rOutput;
Вложение 56799
-
COM#21. Как подключиться к SQL-серверу?
Вопрос: требуется записываться и считывать данные из СУБД с использованием SQL. Как это можно сделать?
Ответ:
Работа с MySQL поддерживается начиная с прошивки 1.3.0620.xxxx.
Работа с MsSQL поддерживается начиная с прошивки 1.3.0812.xxxx.
Работа с SQLite (встраиваемая СУБД, хостится на самом ПЛК) поддерживается во всех прошивках.
См. пример и видео: MySQL / MsSQL / SQLite
-
COM#22. Как подключить контроллер к VPN?
Вопрос: как подключить контроллер к VPN?
Ответ: контроллеры Овен поддерживают протоколы OpenVPN и WireGuard.
Настройка подключения производится через web-конфигуратор.
Документация (см. приложение Г) / Видеопример по OpenVPN
-
COM#23. Как работать с GSM/GPRS-модемами?
Вопрос: как работать с GSM/GPRS-модемами (отправлять/получать cмc, устанавливать GPRS-подключение)?
Ответ: см. информацию по ссылке.
-
Вложений: 5
COM#24. Как настроить обмен между ПЛК, программируемыми в CODESYS V3.5?
Вопрос: как настроить обмен данными между несколькими ПЛК, программируемыми в CODESYS V3.5?
Очевидно, что это можно сделать с помощью протокола Modbus TCP, но этот вариант является довольно трудоемким (настройка мастера и слэйвов, размещение данных в регистрах и т.д.)
Нет ли более простых способов?
Ответ: такие способы есть.
1. Если один ПЛК должен передавать одни и те же данные на несколько других ПЛК, то можно использовать сетевые переменные (Network Variables).
См. документацию (п. 3) и видеопример.
2. Если один ПЛК должен считывать/записывать разные данные с одного или нескольких ПЛК, то можно использовать Менеджер источников данных (Data Source Manager).
См. видеопример, доп. информацию для ПЛК2хх и информацию в онлайн-справке CODESYS:
https://help.codesys.com/webapp/_cds...rsion=3.5.17.0
https://help.codesys.com/webapp/_cds...rsion=3.5.17.0
https://help.codesys.com/webapp/_cds...rsion=3.5.17.0
Вопрос: Как в коде контролировать наличие связи через Data Source Manager?
Ответ: это можно сделать с помощью глобальных переменных диагностики:
- g_Datasources.<имя_источника_данных>Error (тип - Datasources.DataSourceError)
- g_Datasources.<имя_источника_данных>State (тип - Datasources.DataSourceMonitoringState)
Имя источника данных можно увидеть в дереве проекта (по умолчанию для первого источника данных это имя - Datasource).
Вложение 57244
Перечисления для этих переменных объявлены в библиотеке Datasources, которая автоматически добавляется в проект вместе с менеджером источников данных:
Вложение 57245
Вопрос: Как в коде контролировать наличие связи при использовании сетевых переменных?
Ответ: это можно сделать с помощью глобальных переменных диагностики, которые автоматически генерируются в списке сетевых переменных.
Для диагностики на стороне отправителя:
необходимо в свойствах списка сетевых переменных на вкладке Свойства сети установить галочку Подтверждение для ожидания подтверждений от получателя.
Вложение 57246
В случае обрыва связи в структуре NetVarTxDiag_UDP поле sLastError примет значение NetVarUDPError_NOACKNOWLEDGEMENT, а поле nErrorCount будет постоянно увеличиваться.
Вложение 57247
Для диагностики на стороне получателя:
В случае обрыва связи в структуре NetVarRxDiag_UDP значение полей nReceiveCount и tLastReceive "застынут" и перестанут изменяться.
Вложение 57248
-
Вложений: 1
PRG#28. Как инициализировать структуру в коде программы?
Вопрос: как иницилизировать структуру в коде программы?
Предположим, что объявлена такая структура:
Код:
TYPE TEST_DATA :
STRUCT
iVar: INT;
rVar: REAL;
END_STRUCT
END_TYPE
Понятно, что в коде программы можно инициализировать ее таким образом:
Код:
PROGRAM PLC_PRG
VAR
stData: TEST_DATA;
xInit: BOOL;
END_VAR
IF xInit THEN
stData.iVar := 11;
stData.rVar := 22.33;
...
xInit := FALSE;
END_IF
Но нет ли более простого способа?
Ответ: можно инициализировать структуру с помощью специального оператора STRUCT (не описанного в данный момент в справке CODESYS).
Код:
PROGRAM PLC_PRG
VAR
stData: TEST_DATA;
xInit: BOOL;
END_VAR
IF xInit THEN
stData := STRUCT(iVar := 11, rVar := 22.33);
xInit := FALSE;
END_IF
Этот способ также позволяет инициализировать структуры, объявленные в области VAR_INPUT CONSTANT в редакторе языка CFC:
Вложение 57586
-
OTHER#11. Как исполнить на ПЛК "имперский марш"?
Вопрос: как исполнить на зуммере ПЛК "имперский марш"?
Комментарий: данный функционал поддерживается в прошивках с CODESYS V3.5 SP16 Patch 3 и выше - в них в узле Buzzer добавлена возможность управления частотой зуммера.
Ответ: см. пример и видео.
-
Вложений: 1
PRG#29. Локальные перечисления
Вопрос: в наших проектах мы регулярно используем перечисления для повышения читабельности кода.
Некоторые перечисления используются только в конкретном функциональном блоке, и при переносе этого блока в другие проекты приходится не забывать о копировании таких перечислений, что составляет определенное неудобство.
Очевидным вариантом является выделение этого функционального блока и его перечислений в библиотеку, но это тоже является неудобным, так как в разных проектах часто приходится редактировать исходники этого ФБ, адаптируя его под конкретное применение.
Если ли какие-либо варианты для упрощения нашей ситуации?
Можно ли как-то "встроить" перечисление в ФБ?
Ответ: в CODESYS V3.5 (начиная с версии SP7) поддерживаются так называемые "локальные" перечисления. Эти перечисления создаются не при добавлении объекта типа DUT, а прямо в области объявления переменных.
Пример:
Код:
VAR
eState: (OPEN := 0, READ := 10, WRITE := 20, CLOSE := 30) INT;
END_VAR
Объявление локальных перечислений поддерживается в POU (функциях, ФБ и программах) и списках локальных переменных.
Объявление локальных перечислений не поддерживается в методах.
Источник информации:
1. https://alltwincat.com/2021/11/16/local-enumerations/
2. Баг-трекер CODESYS:
Вложение 58125
Примечание: локальные перечисления также поддерживаются в CoDeSys V2.3
-
Вложений: 1
PRG#30. Как выполнить действие при активации тревоги?
Вопрос: в проекте настроена Конфигурация тревог. Требуется при активации (или деактивации, подтверждении и т.д.) тревог выполнять какие-то действия - например, отправлять cмс, e-mail, сообщение через telegram-бота и т.п. Как это сделать?
Ответ: см. пример.
В примере демонстрируется, как при изменении состояния тревоги отправить e-mail. По аналогии можно реализовать выполнение других операций.
Вложение 58783
-
Вложений: 1
COM#25. Как записать данные из ПЛК в таблицу Google Spreadsheet?
Вопрос: как записать данные из ПЛК в таблицу Google Spreadsheet?
Ответ: см. пример.
Вложение 58906
-
Вложений: 3
DEBUG#10. В проекте для СПК возникает 40 ошибок типа Screen.VisuElems...
Вопрос: при создании проекта для СПК в среде CODESYS V3.5 SP16 Patch 3 и выше возникают такие ошибки:
Вложение 58974
Как их исправить?
Ответ: нажмите ПКМ на узел Screen, выберите команду Обновить устройство и обновите компонент до последней доступной версии.
Вложение 58975
Ошибки связаны с изменениями во внутренних библиотеках CODESYS, которые произошли в свежих версиях.
Рекомендуем создавать проект для СПК на основе шаблона - в этом случае ошибок не будет:
Вложение 58976
-
Вложений: 2
COM#26. В версии SP16 Patch 3 не удается опросить Modbus TCP Slave Device - ошибка 10
Вопрос: ПЛК настроен как Modbus TCP Slave Device через дерево проекта.
При его опросе возвращается ошибка 10 (0x0A): GATEWAY PATH UNAVAILABLE.
Вложение 58977
Ошибка проявилась в версии CODESYS V3.5 SP16 Patch 3, в прошлых версиях CODESYS с тем же проектом все работало нормально.
В чем может быть проблема?
Ответ: начиная с версии CODESYS V3.5 SP16 контроллер, настроенный как Modbus TCP Slave Device, отвечает только на запросы с Unit ID = 0 и Unit ID = 255.
Вложение 58978
Остальные адреса обрабатываются только в режиме SerialGateway.
В версии V3.5 SP17 будет восстановлено старое поведение - ПЛК будет отвечать на запросы с любым Unit ID.
-
Вложений: 2
PRG#31. Как инициализировать массивы и структуры?
Вопрос: как задать начальные значения для переменных типа массив (ARRAY) и структура (STRUCT)?
Ответ: см. видеопример или текстовое описание ниже.
Начальные значения элементов массива задаются в квадратных скобках:
Код:
aiData: ARRAY [1..6] OF INT := [1, 2, 3, 4, 5, 6];
Если некоторым последовательно размещенным элементам надо задать одно и то же значение - то можно сделать так:
Код:
// aiData[3] и aiData[4] получат значение 0
aiData: ARRAY [1..6] OF INT := [1, 2, 2(0), 5, 6];
Для многомерных массивов синтаксис аналогичен:
Код:
aiData: ARRAY [1..2, 1..3] OF INT := [1, 2, 3, 11, 22, 33];
Вложение 59180
Начальные значения элементов структуры можно задать прямо при ее создании.
Все экземпляры данной структуры по умолчанию будут инициализированы этими значениями.
Код:
TYPE TEST_DATA :
STRUCT
iVar: INT := 11;
rVar: REAL := 22.33;
END_STRUCT
END_TYPE
Если требуется при объявлении конкретного экземпляра структуры задать индивидуальные значения элементов - то это можно сделать в круглых скобках c указанием их имен:
Код:
stData: TEST_DATA := (iVar := 123, rVar := 11.22);
Пример инициализации массива структур:
Код:
astData: ARRAY [1..3] OF TEST_DATA := [ (iVar := 111, rVar := 11.22), (iVar := 222, rVar := 22.33), (iVar := 333, rVar := 33.44) ];
Кроме того, задать начальные значения можно в редакторе автообъявления:
Вложение 59181
-
PRG#32. Как сбросить счетчики ПЛК2хх из кода программы?
Вопрос: используем ПЛК210. Требуется сбрасывать счетчики дискретных входов и энкодеров из кода программы.
В узле Leftside на вкладке Конфигурация есть параметр Сброс счетчиков входов и энкодеров, но он применяется только при загрузке программы.
Как можно сбросить счетчики прямо в процессе работы ПЛК при выполнии нужного условия?
Ответ: явного механизма сброса счетчиков и энкодеров нет.
Вместо этого следует копировать их значения в промежуточные переменные, которыми уже можно будет манипулировать в коде программы.
См. пример.