Jump to content
View in the app

A better way to browse. Learn more.

T.M.I IThub

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Что такое ПЛК и почему это не просто "мощный Arduino"

ПЛК (Программируемый Логический Контроллер) — это специализированный промышленный компьютер, разработанный для управления технологическими процессами в реальном времени. Главное отличие от обычного компьютера или Arduino — детерминизм: гарантированное время реакции на входные сигналы, независимо от загрузки процессора.

Когда на производстве нужно, чтобы насос включился строго через 50 мс после срабатывания датчика — это ПЛК. Когда допустима задержка в секунду — можно обойтись более дешёвыми решениями. Когда вопрос в надёжности и работе в условиях вибраций, пыли, температур от -40 до +70°C — снова ПЛК.

Другие ключевые отличия:

  • Цикличность: программа выполняется повторяющимися циклами (обычно 1–100 мс). Каждый цикл: считать все входы → выполнить программу → записать все выходы

  • Гальваническая развязка входов/выходов: промышленные сигналы (24В DC, 220В AC) изолированы от внутренней логики

  • Горячая замена модулей: во многих системах можно менять I/O-модули без остановки контроллера

  • Встроенная диагностика: ПЛК сам следит за собственным здоровьем


Архитектура ПЛК: как это устроено

Центральный процессорный модуль (CPU)

Выполняет программу, управляет обменом данных, содержит основную память. В S7-1200 CPU также имеет встроенные входы/выходы, Ethernet порт и возможность расширения.

Модули ввода-вывода (I/O Modules)

Дискретные входы (DI): Воспринимают сигналы "есть напряжение / нет напряжения". Обычно 24В DC или 220В AC. Примеры источников: кнопки, концевые выключатели, датчики приближения (индуктивные, ёмкостные), фотодатчики, реле.

Дискретные выходы (DO): Управляют исполнительными устройствами. Бывают транзисторные (24В DC, быстрые) и релейные (любое напряжение до 250В AC, медленные, но универсальные).

Аналоговые входы (AI): Принимают непрерывные сигналы: 4–20мА, 0–10В, термопары (тип K, J, T...), термосопротивления (Pt100, Pt1000). Преобразуют в число (обычно 0–27648 для диапазона 0–100%).

Аналоговые выходы (AO): Выдают аналоговые сигналы для управления частотниками, регулирующими клапанами, позиционерами.

Память ПЛК (на примере Siemens)

Область

Обозначение

Описание

Входы

I, %IX

Образ входов, обновляется каждый цикл

Выходы

Q, %QX

Образ выходов, пишется в физику после цикла

Меркеры

M, %MX

Внутренние биты/байты/слова — "рабочая память"

Таймеры

T (S7-classic) / IEC-timer

Отсчёт времени

Счётчики

C (S7-classic) / IEC-counter

Счёт импульсов

Data Blocks

DB

Блоки данных: рецепты, уставки, история


Стандарт МЭК 61131-3: пять языков программирования

Международный стандарт определяет пять языков для ПЛК. Хороший инженер знает минимум два-три.

1. Ladder Diagram (LD) — Релейно-контактная схема

Исторически первый язык — имитация схем из физических реле. Читается слева направо, как электрическая цепь. Левая шина — "фаза", правая — "ноль". Ток "течёт" если путь замкнут.

         I0.0        I0.1        Q0.0
Пуск     Стоп (НЗ)   Выход насос
 ──┤ ├────┤/├──────────( )──
   
   Q0.0    (самоподхват)
 ──┤ ├──

Эта схема — классика: кнопка ПУСК (I0.0) запускает насос (Q0.0), контакт самоподхвата удерживает его включённым, кнопка СТОП (I0.1, нормально-закрытый) его отключает.

Преимущества LD: Понятен электрикам без IT-образования, визуально отображает логику цепей, легко отлаживать онлайн (подсвечиваются активные цепи).

Недостатки: Громоздкий для сложных вычислений и работы с данными.

2. Function Block Diagram (FBD) — Диаграмма функциональных блоков

Программа строится из готовых блоков (AND, OR, NOT, таймеры, счётчики, ПИД-регуляторы), соединённых сигнальными линиями. Хорошо подходит для управления потоками сигналов.

I0.0 ──┐
       ├──[AND]──── Q0.0
I0.1 ──┘

3. Structured Text (ST) — Структурированный текст

Язык высокого уровня, похожий на Pascal/Ada. Самый мощный для математических вычислений, работы с массивами, строками.

(* Программа управления насосом с ПИД *)
IF Start AND NOT Stop THEN
    Running := TRUE;
END_IF;

IF Stop THEN
    Running := FALSE;
END_IF;

(* Расчёт ПИД *)
IF Running THEN
    Error    := Setpoint - Feedback;
    Integral := Integral + Error * CycleTime;
    Integral := LIMIT(-100.0, Integral, 100.0); (* Ограничение интеграла *)
    
    Output := Kp * Error + Ki * Integral + Kd * (Error - PrevError) / CycleTime;
    Output := LIMIT(0.0, Output, 100.0);
    
    PrevError := Error;
ELSE
    Output   := 0.0;
    Integral := 0.0;
END_IF;

4. Instruction List (IL) — Список инструкций

Ассемблер для ПЛК. Устаревший язык, в новом стандарте МЭК 61131-3 третьей редакции официально deprecated. Знать необязательно.

5. Sequential Function Chart (SFC) — Диаграмма последовательных функций

Похоже на блок-схему или граф состояний. Идеален для описания технологических последовательностей: шаг 1 → условие перехода → шаг 2 → условие → шаг 3...


Реальный проект: управление насосной станцией

Разберём полноценный пример — система управления двумя насосами с чередованием и защитами.

Техническое задание:

  • 2 насоса, работают поочерёдно для равномерного износа

  • Автоматическое включение второго при отказе первого

  • Защита от сухого хода (датчик уровня)

  • Защита от давления (реле давления)

  • Ручной/автоматический режим

  • Счётчик моточасов каждого насоса

Распределение входов/выходов:

ВХОДЫ:
I0.0 — Кнопка ПУСК (автоматический режим)
I0.1 — Кнопка СТОП
I0.2 — Переключатель Авт/Ручной
I0.3 — Датчик уровня (нижний предел — сухой ход)
I0.4 — Датчик уровня (верхний предел — бак полон)
I0.5 — Реле давления насос 1 (авария — нет давления)
I0.6 — Реле давления насос 2
I0.7 — Тепловое реле насос 1 (перегрев)
I1.0 — Тепловое реле насос 2
I1.1 — Ручное управление насос 1 (в ручном режиме)
I1.2 — Ручное управление насос 2

ВЫХОДЫ:
Q0.0 — Контактор насос 1
Q0.1 — Контактор насос 2
Q0.2 — Лампа "Работа авто"
Q0.3 — Лампа "Авария"
Q0.4 — Сирена (авария критическая)

Программа на Structured Text (ST):

PROGRAM PumpStation

(* ===== ПЕРЕМЕННЫЕ ===== *)
VAR
    // Входы
    btnStart         AT %I0.0 : BOOL;
    btnStop          AT %I0.1 : BOOL;
    swAutoManual     AT %I0.2 : BOOL;  // TRUE = авто
    snsLevelLow      AT %I0.3 : BOOL;  // TRUE = уровень низкий (авария)
    snsLevelHigh     AT %I0.4 : BOOL;  // TRUE = бак полон
    relPressure1     AT %I0.5 : BOOL;  // FALSE = нет давления (авария)
    relPressure2     AT %I0.6 : BOOL;
    thmRelay1        AT %I0.7 : BOOL;  // TRUE = перегрев (авария)
    thmRelay2        AT %I1.0 : BOOL;
    btnPump1Manual   AT %I1.1 : BOOL;
    btnPump2Manual   AT %I1.2 : BOOL;
    
    // Выходы
    outPump1         AT %Q0.0 : BOOL;
    outPump2         AT %Q0.1 : BOOL;
    lampAutoRun      AT %Q0.2 : BOOL;
    lampFault        AT %Q0.3 : BOOL;
    siren            AT %Q0.4 : BOOL;
    
    // Внутренние переменные
    SystemRun        : BOOL := FALSE;
    ActivePump       : INT  := 1;      // Какой насос сейчас основной
    Fault            : BOOL := FALSE;
    FaultCode        : INT  := 0;
    Pump1Fault       : BOOL := FALSE;
    Pump2Fault       : BOOL := FALSE;
    
    // Таймеры
    TimerPumpStart   : TON;            // Задержка пуска насоса
    TimerRotation    : TON;            // Таймер чередования (8 часов)
    TimerAlarmDelay  : TON;            // Задержка подтверждения аварии
    
    // Счётчики моточасов
    Hours_Pump1      : DINT := 0;
    Hours_Pump2      : DINT := 0;
    TimerH_Pump1     : TON;
    TimerH_Pump2     : TON;
END_VAR

(* ===== ЛОГИКА АВАРИЙ ===== *)
// Авария сухого хода — критическая, немедленная остановка
IF snsLevelLow THEN
    Fault     := TRUE;
    FaultCode := 1;  // Сухой ход
    SystemRun := FALSE;
END_IF;

// Задержанные аварии давления (3 секунды для исключения ложных срабатываний)
TimerAlarmDelay(IN := (outPump1 AND NOT relPressure1) OR
                       (outPump2 AND NOT relPressure2),
                PT := T#3S);

IF TimerAlarmDelay.Q THEN
    IF outPump1 AND NOT relPressure1 THEN
        Pump1Fault := TRUE;
        FaultCode  := 2;  // Нет давления насос 1
    END_IF;
    IF outPump2 AND NOT relPressure2 THEN
        Pump2Fault := TRUE;
        FaultCode  := 3;  // Нет давления насос 2
    END_IF;
END_IF;

// Тепловая защита
IF thmRelay1 THEN
    Pump1Fault := TRUE;
    FaultCode  := 4;  // Перегрев насос 1
END_IF;
IF thmRelay2 THEN
    Pump2Fault := TRUE;
    FaultCode  := 5;  // Перегрев насос 2
END_IF;

// Оба насоса в аварии
IF Pump1Fault AND Pump2Fault THEN
    Fault     := TRUE;
    SystemRun := FALSE;
END_IF;

(* ===== КОМАНДЫ ПУСК/СТОП ===== *)
IF btnStart AND NOT Fault THEN
    SystemRun := TRUE;
END_IF;

IF btnStop OR snsLevelHigh THEN  // Стоп или бак полон
    SystemRun := FALSE;
END_IF;

// Квитирование аварии (нажать СТОП для сброса)
IF btnStop THEN
    Fault      := FALSE;
    FaultCode  := 0;
    Pump1Fault := FALSE;
    Pump2Fault := FALSE;
END_IF;

(* ===== АВТОМАТИЧЕСКИЙ РЕЖИМ ===== *)
IF swAutoManual AND SystemRun THEN
    
    // Чередование каждые 8 часов
    TimerRotation(IN := SystemRun, PT := T#28800S);  // 8 часов = 28800 секунд
    IF TimerRotation.Q THEN
        IF ActivePump = 1 THEN
            ActivePump := 2;
        ELSE
            ActivePump := 1;
        END_IF;
        TimerRotation(IN := FALSE);  // Сброс таймера
        TimerRotation(IN := TRUE);
    END_IF;
    
    // При аварии основного насоса — переключаемся на резервный
    IF ActivePump = 1 AND Pump1Fault AND NOT Pump2Fault THEN
        ActivePump := 2;
    ELSIF ActivePump = 2 AND Pump2Fault AND NOT Pump1Fault THEN
        ActivePump := 1;
    END_IF;
    
    // Задержка пуска 1 секунда (защита от дребезга)
    TimerPumpStart(IN := SystemRun, PT := T#1S);
    
    outPump1 := TimerPumpStart.Q AND (ActivePump = 1) AND NOT Pump1Fault;
    outPump2 := TimerPumpStart.Q AND (ActivePump = 2) AND NOT Pump2Fault;

(* ===== РУЧНОЙ РЕЖИМ ===== *)
ELSIF NOT swAutoManual THEN
    outPump1 := btnPump1Manual AND NOT Pump1Fault;
    outPump2 := btnPump2Manual AND NOT Pump2Fault;
    
ELSE
    outPump1 := FALSE;
    outPump2 := FALSE;
END_IF;

(* ===== СЧЁТЧИКИ МОТОЧАСОВ ===== *)
TimerH_Pump1(IN := outPump1, PT := T#1S);
IF TimerH_Pump1.Q THEN
    Hours_Pump1 := Hours_Pump1 + 1;
    TimerH_Pump1(IN := FALSE);
    TimerH_Pump1(IN := TRUE);
END_IF;

TimerH_Pump2(IN := outPump2, PT := T#1S);
IF TimerH_Pump2.Q THEN
    Hours_Pump2 := Hours_Pump2 + 1;
END_IF;

(* ===== ИНДИКАЦИЯ ===== *)
lampAutoRun := SystemRun AND swAutoManual;
lampFault   := Fault OR Pump1Fault OR Pump2Fault;
siren       := Fault;  // Сирена только при критической аварии

END_PROGRAM

Таймеры и счётчики: подробно

Таймеры и счётчики — основа любой программы ПЛК. В стандарте МЭК 61131-3 они реализованы как функциональные блоки.

Типы таймеров

TON (Timer On Delay) — таймер с задержкой включения:

TimerFan(IN := MotorRun, PT := T#5S);
// Q становится TRUE через 5 секунд после включения MotorRun
FanStart := TimerFan.Q;

TOF (Timer Off Delay) — таймер с задержкой выключения:

TimerFan(IN := MotorRun, PT := T#30S);
// Q остаётся TRUE ещё 30 секунд после выключения MotorRun
// Используется для дополнительного охлаждения после остановки
FanRun := TimerFan.Q;

TP (Timer Pulse) — таймер импульса:

TimerBuzzer(IN := AlarmNew, PT := T#2S);
// При фронте AlarmNew генерирует импульс 2 секунды
// Независимо от того, сколько ещё держится AlarmNew
Buzzer := TimerBuzzer.Q;

Счётчики

CTU (Count Up) — счётчик вперёд:

CounterBottles(CU := BottleSensor, R := ResetButton, PV := 100);
// Считает бутылки, при достижении 100 — Q=TRUE
BatchComplete := CounterBottles.Q;
CurrentCount  := CounterBottles.CV;  // Текущее значение

CTD (Count Down) — счётчик назад:

CounterProducts(CD := ProductSensor, LD := LoadButton,
                PV := OrderQty);  // PV загружается при LD=TRUE
OrderComplete := CounterProducts.Q;  // Q=TRUE когда CV=0

Работа с аналоговыми сигналами

Масштабирование аналогового входа

Аналоговый модуль S7-1200 возвращает значение 0–27648 для диапазона 0–100% входного сигнала (4–20мА или 0–10В). Для получения реального значения нужно масштабирование:

FUNCTION_BLOCK ScaleAnalog
VAR_INPUT
    RawValue    : INT;    // Сырое значение от АЦП (0..27648)
    RawMin      : INT;    // Мин значение АЦП (обычно 0 или 5530 для 4мА)
    RawMax      : INT;    // Макс значение АЦП (обычно 27648)
    PhysMin     : REAL;   // Физический минимум (например, 0.0 бар)
    PhysMax     : REAL;   // Физический максимум (например, 16.0 бар)
END_VAR
VAR_OUTPUT
    PhysValue   : REAL;   // Результат в физических единицах
    Broken      : BOOL;   // Обрыв линии (значение ниже 4мА)
END_VAR

// Проверка обрыва линии (для 4-20мА: ниже ~5% = обрыв)
Broken := (RawValue < (RawMin - 1000));

IF NOT Broken THEN
    // Линейное масштабирование
    PhysValue := PhysMin + (REAL(RawValue - RawMin) / REAL(RawMax - RawMin))
                           * (PhysMax - PhysMin);
    // Ограничение выхода
    PhysValue := MAX(PhysMin, MIN(PhysMax, PhysValue));
ELSE
    PhysValue := PhysMin;  // При обрыве — безопасное значение
END_IF;

END_FUNCTION_BLOCK

Использование:

// Датчик давления 4-20мА, диапазон 0-16 бар
PressureSensor(
    RawValue := %IW64,      // Адрес аналогового входа
    RawMin   := 5530,       // 4мА соответствует 5530
    RawMax   := 27648,      // 20мА соответствует 27648
    PhysMin  := 0.0,
    PhysMax  := 16.0
);

Pressure       := PressureSensor.PhysValue;  // Давление в барах
PressureAlarm  := PressureSensor.Broken;     // Авария обрыва линии

IF Pressure > 12.0 THEN
    HighPressureAlarm := TRUE;
END_IF;

Организационные блоки и структура программы

Профессиональная программа ПЛК разделена на функциональные блоки:

Организация в TIA Portal (Siemens):

OB1 (Main) — Главный цикл
├── FC10: ReadInputs         — Чтение и нормализация входов
├── FC20: SafetyLogic        — Приоритетные защиты (всегда первыми!)
├── FB30: PumpControl [DB30] — Управление насосами (с памятью)
├── FB40: PIDControl [DB40]  — ПИД-регулятор
├── FC50: WriteOutputs       — Запись выходов
└── FC60: Diagnostics        — Диагностика и коммуникации

OB35 (Cyclic Interrupt, 10ms) — Быстрые задачи
└── FB35: FastCounter        — Высокоскоростной счётчик

OB82 (I/O Error) — Обработка ошибок I/O-модулей

OB121 (Programming Error) — Обработка ошибок программы

Принцип: защиты и аварии — всегда в начале главного цикла. Они должны отработать независимо от состояния остальной программы.


Отладка и диагностика программы

Онлайн-мониторинг

В TIA Portal при подключении к ПЛК все блоки отображают реальные значения переменных. В Ladder Diagram активные цепи подсвечиваются зелёным — мгновенно видно что работает.

Форсирование переменных (Force)

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

Трассировка

Запись значений переменных в реальном времени с временной меткой. Незаменима для поиска редко возникающих ошибок — включаете запись и ждёте появления проблемы.

Типичные ошибки начинающих:

1. Использование выходных катушек несколько раз в Ladder

НЕПРАВИЛЬНО:
Цепь 1: I0.0 → Q0.0 (катушка)
Цепь 2: I0.1 → Q0.0 (катушка снова!)

Вторая катушка перезаписывает первую. Результат Q0.0 определяется только второй цепью.

ПРАВИЛЬНО:
Цепь 1: I0.0 ──┐
               ├── Q0.0
Цепь 2: I0.1 ──┘

2. Гонка состояний при SET/RESET

// ОПАСНО: порядок операций важен
IF Condition1 THEN  SET(Coil);    END_IF;
IF Condition2 THEN  RESET(Coil);  END_IF;
// Если оба условия TRUE — RESET побеждает (последний)
// Убедитесь, что это желаемое поведение!

3. Деление на ноль

// ВСЕГДА проверяйте делитель
IF Denominator <> 0.0 THEN
    Result := Numerator / Denominator;
ELSE
    Result := 0.0;  // Безопасное значение
END_IF;

Коммуникация ПЛК с внешним миром

Modbus TCP (через Ethernet)

Большинство современных ПЛК поддерживают Modbus TCP "из коробки". Это самый распространённый протокол для связи с SCADA, HMI и частотниками.

В S7-1200 для Modbus TCP используются системные функциональные блоки:

  • MB_CLIENT — ПЛК как Modbus-мастер (опрашивает устройства)

  • MB_SERVER — ПЛК как Modbus-сервер (отвечает на запросы SCADA)

OPC UA

Современный открытый протокол для промышленной коммуникации. Поддерживает семантику данных, безопасность, публикацию/подписку. Все серьёзные ПЛК последних поколений имеют встроенный OPC UA сервер.

PROFINET/EtherCAT

Промышленные реальном-временные сети. PROFINET — стандарт Siemens и Profibus International. EtherCAT — от Beckhoff, исключительно быстрый (цикл 250 мкс). Используются для связи с распределёнными I/O-модулями, сервоприводами, vision-системами.


Советы по надёжности программы

  1. Всегда инициализируйте переменные — не полагайтесь на "нулевое" начальное значение

  2. Используйте watchdog-таймер — если программа "зависла", таймер переводит выходы в безопасное состояние

  3. Документируйте каждую переменную — через полгода вы забудете что значит переменная b47

  4. Разделяйте задачи по функциональным блокам — один блок = одна задача

  5. Тестируйте на симуляторе перед загрузкой в реальный ПЛК

  6. Делайте резервные копии программы перед каждым изменением — версионирование спасало многих

  7. Стандартизируйте именование: btnStart — кнопка, snsLevel — датчик, outPump — выход, tmrDelay — таймер


Заключение

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

Начните с Ladder Diagram — он прозрачен и хорошо отлаживается онлайн. Освойте Structured Text для сложных вычислений. Используйте SFC для технологических последовательностей. И всегда: сначала безопасность, потом функциональность.

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

User Feedback

Create an account or sign in to leave a review

There are no reviews to display.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.