Вложений: 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