Школа для Электрика. Все Секреты Мастерства. Образовательный сайт по электротехнике  
ElectricalSchool.info - большой образовательный проект на тему электричества и его использования. С помощью нашего сайта вы не только поймете, но и полюбите электротехнику, электронику и автоматику!
Электрические и магнитные явления в природе, науке и технике. Современная электроэнергетика, устройство электрических приборов, аппаратов и установок, промышленное электрооборудование и системы электроснабжения, электрический привод, альтернативные источники энергии и многое другое.
 
Школа для электрика | Правила электробезопасности | Электротехника | Электроника | Провода и кабели | Электрические схемы
Автоматизация | Тренды, актуальные вопросы | Обучение электриков | Вебинары и курсы | Калькулятор по электротехнике | Контакты



 

База знаний | Избранные статьи | Эксплуатация электрооборудования | Электроснабжение
Электрические аппараты | Электрические машины | Электропривод | Электрическое освещение

 Школа для электрика / Автоматизация производственных процессов / Арифметические операции в ST: сложение, вычитание, умножение и деление


 Школа для электрика в Telegram

Арифметические операции в ST: сложение, вычитание, умножение и деление



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

Арифметические операции в Structured Text (ST) — это базовый инструмент, которым должен владеть каждый программист, работающий с ПЛК. На первый взгляд сложение и вычитание кажутся тривиальными действиями, однако подводные камни, связанные с типами данных, порядком операций и точностью вычислений, часто приводят к серьезным ошибкам. Давайте разберемся во всех аспектах арифметических вычислений в ST.

Арифметические операции в ST

Основные математические операторы в ST

В Structured Text используются четыре основных оператора для арифметических операций:

+ (плюс) — сложение
- (минус) — вычитание
* (звездочка) — умножение
/ (косая черта) — деление

Кроме того, существуют ещё два оператора, которые часто используются при работе с целыми числами:

MOD (модуль) — остаток от деления
** или ^ — возведение в степень

Давайте рассмотрим каждый из них:

Сложение (+)

Сложение — это, пожалуй, самая простая операция:

VAR
value1: INT := 100;
value2: INT := 50;
sum: INT;
END_VAR

sum := value1 + value2; (* sum = 150 *)

Сложение работает со всеми численными типами данных: INT, DINT, REAL, LREAL. Результат имеет тип, соответствующий одному из операндов (обычно более широкому типу):

VAR
intValue: INT := 100;
realValue: REAL := 25.5;
result: REAL;
END_VAR

result := intValue + realValue; (* результат: 125.5 (REAL) *)

Вычитание (-)

Вычитание работает аналогично сложению:

VAR
temperature: REAL := 25.5;
offset: REAL := 2.0;
correctedTemp: REAL;
END_VAR

correctedTemp := temperature - offset; (* correctedTemp = 23.5 *)

Одна из особенностей вычитания — это унарный минус, который позволяет поменять знак числа:

VAR
value: INT := 100;
inverted: INT;
END_VAR

inverted := -value; (* inverted = -100 *)

Умножение (*)

Умножение часто используется при масштабировании значений. Например, преобразование напряжения (0-10V) в физическую величину (0-100°C):

VAR
voltage: REAL := 5.0; (* 5 вольт *)
temp: REAL;
END_VAR

temp := voltage * 10.0; (* результат: 50°C *)

Множество промышленных задач требует умножения. Например, расчет потребленной энергии:

VAR
power: REAL := 2.5; (* киловатты *)
hours: REAL := 8.0; (* часов работы *)
energyConsumed: REAL;
END_VAR

energyConsumed := power * hours; (* результат: 20.0 кВт?ч *)

Деление (/)

Деление — это операция, требующая особого внимания, особенно при работе с целыми числами:

VAR
totalDistance: REAL := 150.0; (* километры *)
travelTime: REAL := 3.0; (* часы *)
averageSpeed: REAL;
END_VAR

averageSpeed := totalDistance / travelTime; (* результат: 50.0 км/ч *)

Однако при делении целых чисел результат также будет целым числом, и дробная часть будет отброшена:

VAR
total: INT := 10;
divisor: INT := 3;
result: INT;
END_VAR

result := total / divisor; (* результат: 3 (а не 3.333...) *)

Это важно помнить, так как потеря точности может привести к ошибкам в расчетах.

Остаток от деления (MOD)

Оператор MOD возвращает остаток от деления одного целого числа на другое:

VAR
number: INT := 17;
divisor: INT := 5;
remainder: INT;
END_VAR

remainder := number MOD divisor; (* результат: 2, так как 17 = 5*3 + 2 *)

MOD часто используется для определения четности/нечетности числа или для циклических расчетов:
itemCount: INT := 100;
itemsPerBox: INT := 12;
remainingItems: INT;
END_VAR

remainingItems := itemCount MOD itemsPerBox; (* сколько товара останется *)

Возведение в степень ( или ^)**

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

VAR
base: REAL := 2.0;
exponent: REAL := 3.0;
result: REAL;
END_VAR

result := base ** exponent; (* результат: 8.0 *)
(* или *)
result := base ^ exponent; (* то же самое *)

Порядок вычисления операций: в каком порядке считать?

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

Приоритет операций в ST (от высшего к низшему):

  • Возведение в степень: ** или ^
  • Унарный минус: -value
  • Умножение и деление: *, /, MOD
  • Сложение и вычитание: +, -

Например, рассмотрим выражение:
result := 2 + 3 * 4;

Здесь сначала выполнится умножение (3 * 4 = 12), затем сложение (2 + 12 = 14). Результат: 14.

Если бы мы хотели сначала сложить, то нужны скобки:

result := (2 + 3) * 4; (* сначала 2+3=5, затем 5*4=20 *)

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

VAR
speed: INT := 10; (* м/с *)
time: INT := 5; (* секунды *)
acceleration: INT := 2; (* м/с? *)
distance: INT;
END_VAR

(* неправильно *)
distance := speed * time + acceleration * time;

(* правильный расчет для равноускоренного движения *)
distance := speed * time + (acceleration * time * time) / 2;

Практический пример с порядком операций

Представим, что мы рассчитываем стоимость электроэнергии:

VAR
baseCost: REAL := 50.0; (* базовая стоимость *)
powerUsed: REAL := 100.0; (* киловатт-часы *)
pricePerKwh: REAL := 5.5; (* рублей за кВт?ч *)
taxRate: REAL := 0.18; (* налог 18% *)
totalCost: REAL;
END_VAR

(* расчет стоимости *)
totalCost := baseCost + powerUsed * pricePerKwh * (1 + taxRate);

(* порядок выполнения:
1. powerUsed * pricePerKwh = 100 * 5.5 = 550
2. 1 + taxRate = 1 + 0.18 = 1.18
3. 550 * 1.18 = 649
4. baseCost + 649 = 50 + 649 = 699 *)

« Углубленное изучение программируемых логических контроллеров (ПЛК) и всех аспектов промышленной автоматизации в Telegram: ПЛК и автоматизация

Работа с целыми и вещественными числами

Одна из самых подвижных областей при работе с арифметикой в ПЛК — это различия между целыми числами (INT, DINT) и вещественными числами (REAL, LREAL).

Целые числа: точность без дробей

Целые числа хранятся в памяти точно. Если вы сохраняете значение 100, оно останется ровно 100, без какой-либо потери точности. Однако целые числа имеют ограниченный диапазон значений.

VAR
count: INT := 100;
doubled: INT;
END_VAR

doubled := count * 2; (* точный результат: 200 *)

Деление целых чисел выполняется с отсечением дробной части:

VAR
result: INT;
END_VAR

result := 10 / 3; (* результат: 3 (не 3.333...) *)
result := 10 / 4; (* результат: 2 (не 2.5) *)

Вещественные числа: диапазон ценой точности

Вещественные числа используют стандарт IEEE 754 и могут хранить дробные части. Однако они имеют ограниченную точность:

VAR
temperature: REAL := 25.5;
corrected: REAL;
END_VAR

corrected := temperature * 1.01; (* результат: 25.755 *)

Точность REAL — около 6-7 значащих цифр. Это означает, что если число имеет много цифр, точность может быть потеряна:

VAR
largeValue: REAL := 123456789.0; (* большое число *)
small: REAL := 0.0001;
result: REAL;
END_VAR

result := largeValue + small; (* может потерять точность *)

Для высокоточных вычислений используется LREAL (64-битное вещественное число):

VAR
pi: LREAL := 3.141592653589793;
radius: LREAL := 10.0;
circumference: LREAL;
END_VAR

circumference := 2 * pi * radius; (* высокая точность *)

Смешивание типов данных при операциях

Когда вы складываете или умножаете значения разных типов, контроллер автоматически преобразует их к общему типу. Правило простое: результат будет иметь более «широкий» тип:

VAR
intValue: INT := 100;
realValue: REAL := 25.5;
result: REAL;
END_VAR

result := intValue + realValue; (* INT преобразуется в REAL, результат: 125.5 *)

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

VAR
realValue: REAL := 25.7;
intValue: INT;
END_VAR

intValue := realValue; (* будет ошибка типа данных! *)
(* нужно явное преобразование *)
intValue := INT(realValue); (* результат: 25 *)

Практический пример: масштабирование аналогового сигнала

Один из типичных применений арифметики в ПЛК — преобразование аналогового сигнала. Предположим, датчик давления выдает напряжение от 0 до 10 вольт, что соответствует давлению от 0 до 100 бар:

VAR
rawVoltage: REAL; (* сырой сигнал от датчика *)
minVoltage: REAL := 0.0; (* минимальный сигнал *)
maxVoltage: REAL := 10.0; (* максимальный сигнал *)
minPressure: REAL := 0.0; (* минимальное давление *)
maxPressure: REAL := 100.0; (* максимальное давление *)
pressure: REAL;
END_VAR

(* формула масштабирования *)
pressure := minPressure + (rawVoltage - minVoltage) *
(maxPressure - minPressure) / (maxVoltage - minVoltage);

(* если rawVoltage = 5V, то:
pressure = 0 + (5 - 0) * (100 - 0) / (10 - 0)
pressure = 0 + 5 * 100 / 10
pressure = 500 / 10
pressure = 50.0 бар *)

Типичные ошибки при расчетах

Ошибка 1: Деление целых чисел вместо вещественных

(* неправильно *)
VAR
average: INT;
END_VAR

average := (10 + 20 + 30) / 3; (* результат: 20, а не 20.0 *)

(* правильно *)
VAR
average: REAL;
END_VAR

average := (10.0 + 20.0 + 30.0) / 3.0; (* результат: 20.0 *)

Ошибка 2: Неправильный порядок операций

(* неправильно - вычисляем процент неправильно *)
VAR
price: REAL := 100.0;
discountPercent: REAL := 10.0;
finalPrice: REAL;
END_VAR

finalPrice := price - discountPercent / 100 * price; (* нарушен порядок *)

(* правильно *)
finalPrice := price * (1 - discountPercent / 100);
(* или *)
finalPrice := price - (price * discountPercent / 100);

Ошибка 3: Переполнение при умножении

VAR
a: INT := 32000;
b: INT := 5;
result: INT;
END_VAR

result := a * b; (* переполнение! INT не может хранить 160000 *)

(* правильно - используем больший тип *)
VAR
a: INT := 32000;
b: INT := 5;
result: DINT;
END_VAR

result := a * b; (* результат: 160000 *)

Ошибка 4: Потеря точности при суммировании больших последовательностей

VAR sum: REAL := 0.0;
i: INT;
END_VAR

(* суммируем много маленьких чисел *)
FOR i := 0 TO 10000 DO
sum := sum + 0.0001;
END_FOR;

(* из-за округления REAL результат может быть неточным *)

Ошибка 5: Деление на ноль

VAR
numerator: REAL := 100.0;
denominator: REAL := 0.0;
result: REAL;
END_VAR

result := numerator / denominator; (* критическая ошибка! *)

(* правильно - проверяем знаменатель *)
IF denominator <> 0.0 THEN
result := numerator / denominator;
ELSE
(* обработка ошибки *)
END_IF;

Ошибка 6: Сравнение вещественных чисел с точным равенством

VAR
a: REAL := 0.1 + 0.2;
b: REAL := 0.3;
END_VAR

(* неправильно *)
IF a = b THEN
(* из-за ошибок округления это может быть FALSE! *)
END_IF;

(* правильно - используем epsilon *)
IF ABS(a - b) < 0.0001 THEN
(* числа практически равны *)
END_IF;

Практический пример: полный расчет с обработкой ошибок

PROGRAM TemperatureAverage
VAR
sensor1: REAL := 25.5;
sensor2: REAL := 26.3;
sensor3: REAL := 24.8;
average: REAL;
minTemp: REAL := 20.0;
maxTemp: REAL := 30.0;
isValid: BOOL;
errorMessage: STRING := '';
END_VAR

(* расчет среднего значения *)
average := (sensor1 + sensor2 + sensor3) / 3.0;

(* проверка диапазона *)
IF average < minTemp THEN
isValid := FALSE;
errorMessage := 'Temperature too low';
ELSIF average > maxTemp THEN
isValid := FALSE;
errorMessage := 'Temperature too high';
ELSE
isValid := TRUE;
errorMessage := '';
END_IF;

END_PROGRAM

Оптимизация арифметических операций

В некоторых случаях производительность критична. Вот несколько советов по оптимизации:

Избегайте возведения в степень в циклах. Умножение быстрее, чем возведение в степень.
Используйте целые числа вместо вещественных, где это возможно. Целые числа вычисляются быстрее.
Кэшируйте результаты часто используемых вычислений.

(* неэффективно *)
FOR i := 0 TO 1000 DO
temp := sensorValue * 10.0 / (maxValue - minValue);
END_FOR;

(* эффективнее *)
VAR
scale: REAL := 10.0 / (maxValue - minValue);
END_VAR

FOR i := 0 TO 1000 DO
temp := sensorValue * scale;
END_FOR;

Математика как основа надежности

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

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

Расширьте ваши знания о программировании ПЛК

Если вы хотите изучить более продвинутые техники вычислений, узнать о численных методах, оптимизации сложных расчетов и увидеть примеры из реальных промышленных приложений, рекомендуем подписаться на канал «ПЛК и автоматизация» в Telegram — https://t.me/plcmasters.

Этот канал посвящен углубленному изучению программируемых логических контроллеров и всех аспектов промышленной автоматизации.

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

Упростите расчеты электрических цепей с помощью удобного приложения:
Онлайн-калькулятор по электротехнике

Интерактивное веб-приложение: Обучение теоретическим основам электротехники (ТОЭ)

Онлайн-калькулятор освещения: Калькулятор освещения LED-светильниками

Интерактивный инструмент для изучения возобновляемой энергетики: Симулятор микросетей

Для повышения вашей продуктивности: Таймер по методу Pomodoro

Развивайте свои профессиональные навыки:
Каталог обучающих вебинаров и курсов для технических специалистов

Выбирайте удобный формат и темы!