Пример программ на st

ST это язык программирования стандарта IEC61131-3, по структуре и синтаксису ближе всего к языку программирования Паскаль. Удобен для написания больших программ и работы с аналоговыми сигналами и числами с плавающей точкой. ST представляет собой набор инструкций высокого уровня, которые могут использоваться в условных операторах («IF. THEN. ELSE») и в циклах (WHILE. DO).

Далее будем рассматривать реализацию ST в среде CoDeSys.

Выражения. Выражение – это конструкция, возвращающая определенное значение после его вычисления. Выражение состоит из операторов и операндов. Операндом может быть константа, переменная, функциональный блок или другое выражение. Вычисление выражений выполняется согласно правилам приоритета.

Оператор с самым высоким приоритетом выполняется первым, оператор с более низким приоритетом – вторым и т.д., пока не будут выполнены все операторы. Операторы с одинаковым приоритетом выполняются слева направо.

Выражение в скобках

Имя функции (список параметров)

CoDeSys создание первого проекта — счётчик (ST)

Возведение в степень

Логическое исключающее ИЛИ

Перед оператором присваивания находится операнд (переменная или адрес), которому присваивается значение выражения, стоящего после оператора присваивания.

Пример: Var2: = Var3 * 10;

После выполнения этой операции Var2 принимает значение в десять раз большее, чем Var3.

Функциональный блок вызывается с помощью имени экземпляра функционального блока и списка входных параметров с присваиванием данных в круглых скобках. В следующем примере вызывается таймер с параметрами IN и PT. Значение выходной переменной Q присваивается переменной А. К выходной переменной можно обратиться с помощью имени экземпляра функционального блока, точки, следующей за ним и имени выходной переменной:

CMD_TMR (IN: = %IX5, PT: = 300);

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

Часть конструкции фигурных скобках не обязательна. Если возвращает истину, тогда выполняется. В противном случае будут выполняться остальные логические выражения одно за другим, пока одно из них не возвратит истину. Тогда выполняются инструкции, стоящие после этого логического выражения до следующего ELSIF или ELSE. Если все логические выражения ложны, то выполняются инструкции, стоящие после ELSE.

Инструкция CASE . C помощью инструкции CASE можно нескольким различным значениям целочисленной переменной сопоставить различные инструкции.

Инструкция CASE выполняется согласно следующим правилам:

если переменная имеет значение , то выполняется инструкция ;

если не принимает ни одного из указанных значений, то выполняется ;

чтобы одна и та же инструкция выполнялась при различных значениях переменной , необходимо перечислить эти значения через запятую;

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

Вебинар «Основы программирования ПЛК1хх на языке ST»

Цикл FOR. С помощью FOR можно программировать повторяющиеся процессы.

Часть конструкции, заключенная в фигурные скобки, не обязательна. выполняются, пока счетчик не больше . Это условие проверяется перед выполнением , поэтому раздел не выполняется, если больше . Всякий раз, когда выполняются , значение , увеличивается на . может принимать любое целое значение. По умолчанию шаг устанавливается равным 1.

Цикл WHILE . Цикл WHILE может использоваться, как и цикл FOR, с тем лишь различием, что условие выхода определяется логическим выражением. Это означает, цикл выполняется, пока верно заданное условие.

Раздел выполняется циклически до тех пор, пока дает TRUE. Если равно FALSE уже при первой итерации, то раздел не будет выполнен ни разу. Если никогда не примет значение FALSE, то раздел будет выполняться бесконечно. Так же необходимо следить, чтобы цикл не станет бесконечным. Для этого в теле цикла значение входящей в условие переменной обязательно должно изменяться.

Например, путем инкремента или декремента счетчика.

Цикл REPEAT . Цикл REPEAT отличается от цикла WHILE тем, что первая проверка условия выхода из цикла осуществляется, когда цикл уже выполнился 1 раз. Это означает, что независимо от условия выхода цикл выполняется хотя бы один раз.

Раздел выполняется циклически до тех пор, пока дает TRUE. Если равно FALSE уже при первой итерации, то раздел не будет выполнен один раз. Если никогда не примет значение FALSE, то раздел будет выполняться бесконечно, т. е. программист должен быть уверен, что цикл не станет бесконечным. Для этого в теле цикла значение входящей в условие переменной обязательно должно изменяться. Например, путем инкремента или декремента счетчика.

Инструкция EXIT. Если EXIT встречается в циклах FOR, WHILE, REPEAT, то цикл заканчивает свою работу независимо от значения условия выхода.

Источник: www.cobr.ru

Подробности об языке программирования на ST в CoDeSyS

Подробности об языке программирования на ST в CoDeSyS

Прежде чем мы с вами будем рассматривать упрощённую графическую систему программирования для технологов, хотелось бы в двух словах рассказать о базисном языке программирования СИ. Язык ST CoDeSyS отличается от других своей гибкостью и адаптивностью под любые задачи. Он позволяет обрабатывать сложные решения и видеть всю картину в целом. Чаще всего применяется в функциональных блоках для обработки алгоритма той или иной части рабочего органа станка или линии.

Из этой статьи вы узнаете:

Здравствуйте уважаемые Дамы и Господа! Меня зовут Гридин Семён, и я являюсь автором этого блога. В данном посте я хочу обсудить с вами базовые понятия языка программирования CoDeSyS. Называется он ST CoDeSyS, очень сильно напоминает СИ.

Читайте также:
Какая хорошая программа для музыки на Айфон

Язык программирования ST и типы переменных

ST (Structured text) — это одна из составных частей комплекса CoDeSyS и представляет собой текстовый редактор высокого уровня. Он очень похож на Basic или Pascal. Такой способ программирования является идеальным инструментом для людей-программистов. Преимуществом языка является создание сложных математических и разветвленных алгоритмов.

ST позволяет без труда описывать сложные операции компактным и лёгким для восприятия текстом. Structured Text содержит в себе много конструкций, позволяющие присваивать переменные, использовать готовые библиотеки, функции и функциональные блоки.

Программа ST

В чём преимущество данного способа программирования? давайте с вами перечислим:

  1. Наглядность. Вы можете на одном листинге оценить всю последовательность действий и выполнение условий
  2. Программа на ST может быть создана в любом текстовом редакторе
  3. Читабельность. За счёт символьного представления текста и выделения блоков разными цветами

С этим мы разобрались, но, прежде чем переходить к непосредственному изучению азов программирования, необходимо ознакомиться с элементом языка — тип данных. Хочу обратить внимание, этот элемент практически схож во многих си-подобных языках (Питон, Ардуино IDE, СИ# т.д.)

Языки программирования

Тип данных переменной определяет род информации, диапазон представлений и множество допустимых операций. Языки МЭК используют строгую идеологию в этом отношений. Любую переменную можно использовать только после её объявления. Присваивать значения одной переменной другой можно, только если они одного типа. В другом случае используются преобразователи типов.

В таблице ниже я представлю типы данных, которые используются чаще всех:

Тип Название Предел Размер в байтах
BOOL Логическое 1 бит 1 бит
BYTE Целочисленое 8 бит 1 байт
WORD Целочисленое 16 бит 2 байта
INT Целочисленое -32768-32767 2 байта
UINT Целочисленое 0-65535 2 байта
FLOAT Вещественное ±10³³ 4 байта
DATE_AND_TIME Дата и время
STRING Строковое

Перечень основных операторов

Операторы — это символы определённых операций. Но их можно определить и как функции, наделёнными определёнными привилегиями. Они имеют определённые ключевые слова и формы для представления на ST.

Оператор выбора IF позволяет выполнить различные группы выражений в зависимости от условий, выраженных логическими выражениями.

PROGRAM PLC _ PRG
IF in = TRUE THEN out : = 1 ; ELSE out : = 2 ;

Оператор множественного выбора CASE позволяет выполнить различные группы выражений в зависимости от значения одной целочисленной переменной или выражения.

PROGRAM PLC _ PRG
CASE test / 2 OF
in : = FALSE ;

Циклы WHILE и REPEAT обеспечивают повторение группы выражений, пока верно условное логическое выражение. Если условное выражение всегда истинно, то цикл становится бесконечным. Условие в цикле WHILE выполняется до начала цикла, а в REPEAT после тела цикла.

PROGRAM PLC _ PRG
test : INT : = 64 ;
WHILE test > 1 DO
out : = out + 1 ;
test : = test / 2 ;
PROGRAM PLC_PRG
test : INT : = 64 ;
out : = out + 1 ;
test : = test / 2 ;
UNTIL test > 1
END_REPEAT

Цикл FOR обеспечивает заданное количество повторений группы выражений.

PROGRAM PLC _ PRG
FOR test : = 1 TO 10 DO
out : = out + 1 ;

Советы по программированию ПЛК в среде CoDeSyS

Одно из значительных отличий написание алгоритмов для АСУТП от классического программирования — это меньший уровень абстракции. Для описания тех. процесса не требуется глубокое и огромное описание. Достаточно опираться на логику процесса и здравый смысл.

Не стремитесь использовать чужие библиотеки и чужой код в своих проектах.

Смотрите на сайте л карнитин купить.

Обращаю ваше внимание, чужие библиотеки, скачанные с форума на реальных объектах использовать категорически НЕ РЕКОМЕНДУЮ. Для этого есть куча готовых библиотек, такие как Standart, Utill, OSCAT. Фирма ОВЕН для своего оборудования пишет свои ПРОТЕСТИРОВАННЫЕ библиотеки.

Библиотеки

У меня был такой горький опыт. Когда мы занимались автоматизацией ЦТП, а точнее контуром отопления и ГВС, я скачал с форума библиотеки для ПИД-регулирования задвижек. И что же в итоге получилось? Код тупо не сработал, вообще! Пришлось работать сутками, и днём и ночью допиливать программу в режиме цейтнота.

Пишите программы компактно, и оставляйте комментарии.

Когда пишите объёмную и сложную программу, пользуйтесь функциями, функциональными блоками и подпрограммами. Пишите комментарии возле каждого узла автоматизации. Это очень сильно упрощает жизнь. Особенно тогда, когда нужно через некоторое время что-то исправлять.

Пользуйтесь интерактивной справкой в среде разработки.

В данном каталоге вы можете найти ответы на многие ваши вопросы, особенно это актуально для новичков. Открывается справка по нажатию кнопки F1 .

Справка codesys

Плюсы языка ST-массивы и циклы.

Использование циклов и массив облегчают жизнь программисту и увеличивает читабельность кода. Циклы очень удобны при использовании сложных и ресурсоёмких функций, таких как ПИД-регуляторы, опрос аналоговых входов, связь между ПЛК.

На этом я с вами прощаюсь, дорогие друзья, пишите в комментариях, подписывайтесь, рассказывайте друзьям. До встречи в следующих статьях.

С уважением, Гридин Семён.

Источник: kip-world.ru

Полезные возможности ST+Codesys 3, которые многие не замечают

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

Об опыте автора

Опыт работы с ПЛК: 3 года.

Разработка под ПЛК: Beckhoff CX series, SE Modicon M221, WAGO 750 series.

Среды разработки: TwinCAT 3, EcoStruxure Machine Expert-Basic, CODESYS V2.3.

Основная часть опыта приходится на ST+TwinCAT 3, который базируется на CODESYS и IEC 61131.

Читайте также:
Что такое программа триз

Статью решил написать так как покидаю OT и перехожу в мир IT. Хочется поделится опытом, чтобы эти 3 года не прошли даром.

Среда разработки

Если часто приходиться комментировать части кода — то узнайте какое сочетание клавиш позволит вам это сделать, это сэкономит много времени. В TwinCAT XAE Shell для комментирования выделенного кода: Ctrl+K+C и Ctrl+K+U для расскомментирования.

Обезвредьте кнопку Stop, чтобы случайно не остановить ПЛК , иногда такое случайное нажатие может привести к нежелательным последствиям. В TwinCAT XAE Shell можно выбрать какие кнопки выводить на toolbar. После локальной отладки программы рекомендую скрыть кнопку остановки ПЛК .

Structured Text

STRING vs WSTRING

В TwinCAT 3 есть возможность использовать Unicode строки. Они могут пригодиться, если необходимо передовать специфические символы, но без необходимости лучше не использовать WSTRING.

Size of character

Date and time

Почти в любом проекте необходимо знать точное время, вычислять временные интервалы. Часто работа с временем и датами доставляет много проблем и боли. Для себя я нашёл решение, уверен, оно упростит многим жизнь.

F_GetSystemTime() (Функция из модуля Tc2_System)

Эта функция может быть использована для считывания метки времени операционной системы. Временная метка представляет собой 64-разрядное целое значение с точностью до 100 нс. Помимо прочего, его можно использовать для синхронизации задач или измерения времени. Одна единица соответствует 100 нс.

Время представляет собой количество интервалов в 100 нс с 1 января 1601 года.

Хранятся отметки в переменных типа ULINT. Зная всё это мы можем без труда рассчитывать интервалы времени с точностью до 100нс! Нужно просто найти разность между отметками.

К сожалению, стандартных функций для преобразования отметки в тип DATETYPE я не нашёл, поэтому пришлось реализовать такую функцию самостоятельно:

(* :Description: Convert time since 1 January 1601 in 100 ns to DATE_AND_TIME (Преобразует время с 1 Января 1601 года в 100 нс в DATE_AND_TIME) :Usability: Convert timestamp to datetime :Note: check then nSystemType more then 01.01.1970 00:00:00 Version history: Kozhemaykin E. A. | Creating | 16.08.2021; *) FUNCTION F_SystemTimeToDT : DT VAR CONSTANT SECONDS_BETWEEN_1601_AND_1970 : ULINT := 11_644_473_600; END_VAR VAR_INPUT nSystemTime : ULINT; // One unit is 100 ns since 1 January 1601 END_VAR VAR nSeconds : ULINT; END_VAR
nSeconds := (nSystemTime / 10_000_000) — SECONDS_BETWEEN_1601_AND_1970; F_SystemTimeToDT := ULINT_TO_DT(nSeconds);

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

Функция для получения текущей даты/времени в формате DATETIME

(* :Description: Return datetime now in format DATE_AND_TIME (DT) :Usability: For getting datetime now in format DATE_AND_TIME (DT) Version history: Kozhemaykin E. A. | Creating | 16.08.2021; *) FUNCTION F_DateTimeNow : DT
F_DateTimeNow := F_SystemTimeToDT(F_GetSystemTime());
Функция для получения прошедшего времени в формате TIME

(* :Description: Time passed since tStart (Прошло времени c tStart) :Usability: If need check how long time past Version history: Kozhemaykin E. A. | Creating | 16.08.2021; *) FUNCTION F_TimePassed : TIME VAR_INPUT tStart: ULINT; (* Время начала в 100нс от 01.01.1601, текущее время в данном формате предоставляет функция F_GetSystemTime()*) END_VAR
F_TimePassed := ULINT_TO_TIME((F_GetSystemTime() — tStart) / 10000);

Числовые константы

Большинство документаций по обмену по промышленным протоколам содержит шестнадцатиричные адреса регистров, номера функций, обозначения комманд и т.д. Для битовых операций необходимо представлять числа в двоичном виде. Чтобы эффективно решать задачи, где приходиться отходить от десятичной системы счисления необходимо знать о возможности задания константных чисел заданного типа в заданной системе счисления.

В общем виде задание числовой константы выглядит так:

##value

Числовые значения могут быть двоичными числами, восьмеричными числами, десятичными числами или шестнадцатеричными числами. Если целое значение не является десятичным числом, его основание должно быть записано перед целочисленной константой, за которой следует символ хэша (#). Для шестнадцатеричных чисел цифры для чисел от 10 до 15, как обычно, представлены буквами A-F.

Типом этих числовых значений может быть BYTE, WORD, DWORD, SINT, USINT, INT, UINT, DINT, UDINT, REAL или LREAL.

ANY type

В языках программирования со статической типизацией довольно сложно делать универсальные функции/функциональные блоки. Когда мне поставили задачу собирать и анализировать различные данные, я решил, что копировать функциональные блоки и изменять в них только тип входного значения — не лучший вариант. Тогда появилась идея приводить все типы к одному и по объективным причинам это тип LREAL.

При реализации функции или метода вы можете объявлять входные данные (VAR_INPUT) как переменные с типом данных ANY. Далее вы можете получить указатель на значение, тип данных и размер переданной на этот вход переменной.

Структура типа данных ANY

TYPE AnyType : STRUCT // the type of the actual parameter typeclass : __SYSTEM.TYPE_CLASS ; // the pointer to the actual parameter pvalue : POINTER TO BYTE; // the size of the data, to which the pointer points diSize : DINT; END_STRUCT END_TYPE

Кроме типа ANY существуют также дочерние типы:

Дерево наследования типов

Хочу обратить внимание что на вход типа ANY не может быть подана константа, поэтому в некоторых случаях придётся создавать дополнительную переменную.

Зная про этот тип мне удалось реализовать функцию, которая приводила данные разных типов к LREAL.

Функция по преобразованию числовых типов в LREAL

(* :Description: Convert ANY_NUM and ANY_BIT to LREAL :Usability: For development universal functions :Note: Valid types is: ANY_NUM: — ANY_REAL: REAL, LREAL — ANY_INT: USINT, UINT, UDINT, ULINT, SINT, INT, DINT, LINT ANY_BIT: — BYTE, WORD, DWORD, LWORD Version history: Kozhemaykin E. A. | Creating | 01.06.2021; Kozhemaykin E. A. | TO_LREAL | 03.11.2021; *) FUNCTION F_AnyNumToLREAL : LREAL VAR_INPUT AnyNum: ANY; // Variable for converting, need have address END_VAR VAR pReal : POINTER TO REAL; // pointer to a variable of the type REAL pLReal : POINTER TO LREAL; // pointer to a variable of the type LREAL pUSInt : POINTER TO USINT; // pointer to a variable of the type USInt pUInt : POINTER TO UINT; // pointer to a variable of the type UInt pUDInt : POINTER TO UDINT; // pointer to a variable of the type UDInt pULInt : POINTER TO ULINT; // pointer to a variable of the type ULInt pSInt : POINTER TO SINT; // pointer to a variable of the type SInt pInt : POINTER TO INT; // pointer to a variable of the type Int pDInt : POINTER TO DINT; // pointer to a variable of the type DInt pLInt : POINTER TO LINT; // pointer to a variable of the type LInt pByte : POINTER TO BYTE; // pointer to a variable of the type Byte pWord : POINTER TO WORD; // pointer to a variable of the type Word pDWord : POINTER TO DWORD; // pointer to a variable of the type DWord pLWord : POINTER TO LWORD; // pointer to a variable of the type LWord END_VAR VAR_OUTPUT OrginalType: __SYSTEM.TYPE_CLASS; bInvalidType: BOOL := FALSE; END_VAR
// Real numbers IF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_REAL) THEN pReal := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_REAL; F_AnyNumToLREAL := TO_LREAL(pReal^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_LREAL) THEN pLReal := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_LREAL; F_AnyNumToLREAL := pLReal^; // Bit’s numbers ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_BYTE) THEN pByte := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_BYTE; F_AnyNumToLREAL := TO_LREAL(pByte^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_WORD) THEN pWord := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_WORD; F_AnyNumToLREAL := TO_LREAL(pWord^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_DWORD) THEN pDWord := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_DWORD; F_AnyNumToLREAL := TO_LREAL(pDWord^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_LWORD) THEN pLWord := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_LWORD; F_AnyNumToLREAL := TO_LREAL(pLWord^); // Unsigned integers ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_USINT) THEN pUSInt := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_USINT; F_AnyNumToLREAL := TO_LREAL(pUSInt^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_UINT) THEN pUInt := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_UINT; F_AnyNumToLREAL := TO_LREAL(pUInt^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_UDINT) THEN pUDInt := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_UDINT; F_AnyNumToLREAL := TO_LREAL(pUDInt^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_ULINT) THEN pULInt := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_ULINT; F_AnyNumToLREAL := TO_LREAL(pULInt^); // Signed integers ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_SINT) THEN pSInt := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_SINT; F_AnyNumToLREAL := TO_LREAL(pSInt^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_INT) THEN pInt := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_INT; F_AnyNumToLREAL := TO_LREAL(pInt^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_DINT) THEN pDInt := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_DINT; F_AnyNumToLREAL := TO_LREAL(pDInt^); ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_LINT) THEN pLInt := AnyNum.pValue; OrginalType := __SYSTEM.TYPE_CLASS.TYPE_LINT; F_AnyNumToLREAL := TO_LREAL(pLInt^); //Invalid type ELSE F_AnyNumToLREAL := 0; bInvalidType := TRUE; END_IF

Читайте также:
Пример программы на с работа с данными

REFERENCE

Все знают про указатели (POINTER) и связанные с ними проблемы, так вот многие из них можно избежать, если использовать ссылки(REFERENCE):

  • Ссылки проще в использовании: ссылку не нужно разыменовывать (с помощью ^), чтобы получить доступ к содержимому объекта, на который ссылается ссылка.
  • Более чистый синтаксис для передачи значений: Если вход является ссылкой, то нет необходимости писать ADDR(value).
  • В отличие от указателей, для ссылок компилятор проверяет типы данных при передаче значений.

Стоит отметить, что не всегда ссылкой можно заменить указатель, но когда это возможно, то сделайте это.

Pragmas

Инструкции pragma влияют на свойства переменных, относящихся к процессу компиляции или предкомпиляции. Не поленитесь просмотреть возможности каждого типа pragmas — обязательно найдёте что-то полезное для своего проекта.

  • Message pragmas
  • Attribute pragmas
  • Conditional pragmas
  • Region pragma
  • Pragmas for warning suppression

Union

Union — тип структуры, который позволяет представлять значение в разных типах данных. Данная структура полезна при отладке кода а также при обработке входных значений.

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

SEL, MIN, MAX, LIMIT

Многим программистам ПЛК часто не хватает синтаксического сахара, которого много в других языках программирования. На примере функции SEL хочется показать, что возможно этот «сахар» в виде тернарного оператора не особо нужен.

Если вам нужно выбрать значение в зависимости от условия, выможете сделать это в одну строку:

value := SEL(condition, if false, if true);

Если вам нужно ограничить значение сверху и/или снизу, это также можно сделать в одну строку:

value := MIN(value, max_limit); value := MAX(value, min_limit); or value := LIMIT(min_limit, value, max_limit);

Многие функции и операторы, которых нам не хватает уже написаны — нужно только поискать.

Заключение

В статье описано,то на что лично мне захотелось обратить внимание (ООП решил не трогать). Буду рад если мой опыт принесёт кому-то пользу. Попрошу при использовании предоставленных функций оставлять продолжать version history.

Делитесь своим опытом в комментариях. Чтобы быть в курсе событий и общаться с коллегами предлагаю перейти по ссылкам: тг-канал proPLC, тг-чат proPLC.

  • Программирование
  • Промышленное программирование
  • SCADA
  • Программирование микроконтроллеров

Источник: habr.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru