Structured Text (ST): текстовое программирование

Зачем

Structured Text (ST) для начинающих: переменные, условия IF/CASE и масштабирование сигнала 4–20 мА. Главный рабочий язык инженера АСУ ТП.

Предложить правку

Ментальная модель: Pascal для автоматики

ST похож на обычные языки программирования (ближе всего к Pascal). Те же переменные, условия, циклы — но работает он внутри цикла сканирования ПЛК: весь код ST прогоняется целиком каждый скан, сверху вниз.

Переменные и типы данных

Сначала переменные объявляют (в разделе VAR), указывая тип. Тип определяет, что переменная хранит.

Тип Что хранит Пример
BOOL TRUE/FALSE — дискретный сигнал pump_on : BOOL;
INT целое число count : INT;
REAL число с дробной частью level_m : REAL;
TIME интервал времени delay : TIME := T#5S;
VAR
    start_btn : BOOL;       // кнопка пуск (DI)
    level_raw : INT;        // сырое значение с входа AI
    level_m   : REAL;       // уровень в метрах
    pump_on   : BOOL;       // команда на насос (DO)
END_VAR

Важно

В ST присваивание — это := (двоеточие-равно), а сравнение на равенство — =. Их путают чаще всего. level_m := 1.5; — «положить 1.5 в переменную». IF level_m = 1.5 — «а равно ли оно 1.5?». Перепутаешь — логика молча сломается.

Условия: IF и CASE

IF ветвит логику по условию:

IF level_m > 2.8 THEN
    pump_on := FALSE;       // бак почти полон — выключить насос
ELSIF level_m < 0.5 THEN
    pump_on := TRUE;        // воды мало — включить насос
END_IF;

CASE удобен, когда вариантов много (например, режимы работы):

CASE mode OF
    0: pump_on := FALSE;            // стоп
    1: pump_on := TRUE;             // ручной
    2: pump_on := auto_logic;       // авто
END_CASE;

Разобранный пример: масштабирование 4–20 мА

Помнишь формулу из раздела про датчики? Вот как она живёт в ПЛК. Аналоговый вход даёт «сырое» целое (например, 0…32767 для 4–20 мА), а нам нужны метры.

Разобранный пример

Датчик уровня 4–20 мА на диапазон 0…3 м. Модуль AI выдаёт level_raw в диапазоне 0…32767. Переведём в метры:

// 0 соответствует 0 м, 32767 — 3 м (линейно)
level_m := INT_TO_REAL(level_raw) / 32767.0 * 3.0;

// защита от сухого хода: если уровень критично мал — стоп
IF level_m < 0.2 THEN
    pump_on := FALSE;
    dry_run_alarm := TRUE;
END_IF;

Три строки — и сырое число превратилось в метры, плюс защита. На LD то же масштабирование выглядело бы как нагромождение арифметических блоков. Вот почему вычисления пишут на ST.

Совет

Комментируй код (// для строки). Через полгода ты сам не вспомнишь, почему тут 32767, а коллега на пусконаладке — тем более. Хороший комментарий объясняет «зачем», а не «что».

Проверь себя

  1. Чем отличается := от = в ST?
  2. Объяви переменную типа REAL для температуры и положи в неё 20.5.
  3. Напиши на ST условие: «если давление больше 8 бар — поднять аварию».

Предложить правку

Практическое задание

Напиши на ST (в CODESYS/симуляторе или на бумаге) фрагмент управления баком:

  1. объяви переменные: temp_raw : INT (сырое с AI, 0…32767 для 0…150 °C), temp_c : REAL, heater_on : BOOL, overheat : BOOL;
  2. масштабируй temp_raw в temp_c в градусах;
  3. логика нагревателя: включать heater_on, если temp_c < 60, выключать при temp_c > 65 (гистерезис, чтобы не «дребезжал»);
  4. защита: если temp_c > 90overheat := TRUE и heater_on := FALSE.

Критерий самопроверки: подставь temp_raw = 16384 (середина шкалы) — какая температура получится? Сработает ли нагреватель? Проверь руками, что твоя формула масштабирования даёт ~75 °C.

Предложить правку

Поддержи проект!

IndustrialProfi пока разрабатывается на энтузиазме силами одного человека. Помоги создать лучшую открытую энциклопедию для востребованных и полезных профессий. Спасибо за участие!