Files
PLC_Library/AI/PLC_Library_API.md

669 lines
30 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PLC_Library — API Reference (для использования LLM/ИИ)
> Формат: справочник интерфейсов (аналог API-документации). Для каждого POU указаны: тип, путь в дереве проекта, входы/выходы с типами, значениями по умолчанию и назначением, а также краткое описание поведения и особые примечания. Тела реализации (код) намеренно не включены — только то, что нужно, чтобы **вызвать** блок правильно.
>
> Язык: CoDeSys 3.5, Structured Text (ST).
> Скармливайте этот файл ИИ вместо исходников — этого достаточно, чтобы сгенерировать корректные вызовы блоков библиотеки.
---
## Индекс
- [Filters — Фильтры](#filters--фильтры)
- [Fastwel — Модули ввода/вывода](#fastwel--модули-вводавывода)
- [Преобразование значений](#преобразование-значений)
- [Общие — Common](#общие--common)
- [Дискретные сигналы / кнопки / таймеры](#дискретные-сигналы--кнопки--таймеры)
- [Пороговые сигналы / гистерезис](#пороговые-сигналы--гистерезис)
- [Статус аналоговых сигналов](#статус-аналоговых-сигналов)
- [Диагностика связи](#диагностика-связи)
- [Регулирование](#регулирование)
- [Структуры данных (очереди/стеки)](#структуры-данных-очередистеки)
- [Иное](#иное)
- [Structs](#structs)
- [Общие правила / соглашения библиотеки](#общие-правила--соглашения-библиотеки)
---
## Filters — Фильтры
`Path: Filters`
### ExpRunAverage — FUNCTION : REAL
Экспоненциальное скользящее среднее с постоянным коэффициентом.
```
FUNCTION ExpRunAverage : REAL
VAR_INPUT
In : REAL; // входное значение
Old : REAL; // предыдущее значение EMA (нужно хранить самому вызывающему)
K : REAL; // коэффициент сглаживания [0..1], чем больше — тем быстрее реакция
END_VAR
```
Формула: `Out := (1-K)*Old + K*In`. Без внутреннего состояния — вызывающий код сам хранит `Old` между циклами.
### ExpRunAverageAdaptive — FUNCTION : REAL
Как `ExpRunAverage`, но коэффициент переключается на увеличенный `K2`, если скачок входа больше `Delta` (быстрая реакция на резкие изменения).
```
FUNCTION ExpRunAverageAdaptive : REAL
VAR_INPUT
In : REAL;
Old : REAL;
K1 : REAL; // обычный коэффициент
Delta : REAL; // порог |In-Old| для переключения на K2
K2 : REAL; // ускоренный коэффициент (обычно K2 > K1)
END_VAR
```
### RunMiddleArifm — FUNCTION_BLOCK
Скользящее среднее арифметическое по кольцевому буферу (собственное состояние, хранит буфер сам).
```
FUNCTION_BLOCK RunMiddleArifm
VAR_INPUT
In : REAL; // входное значение
N : INT := 32; // размер окна усреднения, диапазон 0..32
RST : BOOL; // TRUE => переинициализация буфера текущим In
END_VAR
VAR_OUTPUT
Y : REAL; // результат — скользящее среднее
END_VAR
```
Особенность: при `RST` или на первом скане буфер заполняется значением `In`, а `Y := In`.
### MultipleClick — FUNCTION_BLOCK
Детектор серии кликов кнопки (одиночный/двойной/тройной).
```
FUNCTION_BLOCK MultipleClick
VAR_INPUT
In : BOOL; // сигнал кнопки
TimeToWait : TIME := T#500MS; // макс. пауза между нажатиями, после — фиксация результата
TimeRelease : TIME := T#0S; // время удержания результата на выходах
END_VAR
VAR_OUTPUT
Click1 : BOOL; // TRUE — зафиксирован 1 клик
Click2 : BOOL; // TRUE — зафиксировано 2 клика
Click3 : BOOL; // TRUE — зафиксировано 3 клика
Click : WORD; // число нажатий (0, если результат уже "отпущен")
END_VAR
```
---
## Fastwel — Модули ввода/вывода
`Path: Fastwel`
Преобразование "сырых" значений АЦП/кодов модулей Fastwel в физические единицы и обратно.
### AIM721_AI — FUNCTION : REAL
```
FUNCTION AIM721_AI : REAL
VAR_INPUT
ADC : DINT; // код АЦП
END_VAR
```
АЦП → 0…20 мА (коэффициент модуля AIM721).
### AIM722_AI — FUNCTION : REAL
```
FUNCTION AIM722_AI : REAL
VAR_INPUT
ADC : DINT;
END_VAR
```
АЦП → 0…20 мА (коэффициент модуля AIM722, отличается от AIM721).
### AIM723_AI — FUNCTION : REAL
```
FUNCTION AIM723_AI : REAL
VAR_INPUT
ADC : DINT;
END_VAR
```
АЦП → 4…20 мА.
### AIM726_AI — FUNCTION : REAL
```
FUNCTION AIM726_AI : REAL
VAR_INPUT
ADC : DWORD; // код АЦП (DWORD!)
END_VAR
```
АЦП → 0…40 В.
### AIM727_AI — FUNCTION : REAL
```
FUNCTION AIM727_AI : REAL
VAR_INPUT
ADC : DINT; // код АЦП (DINT — отличие от AIM726)
END_VAR
```
АЦП → 0…40 В.
### AIM791_AI — FUNCTION : REAL
```
FUNCTION AIM791_AI : REAL
VAR_INPUT
ADC : WORD;
RANGE : BYTE := 0; // 0=0..5мА; 1=0..20мА; 2=4..20мА
END_VAR
```
Универсальный вход, диапазон выбирается `RANGE`. Значение по умолчанию `RANGE` вне 0/1/2 → возвращает `0.0`.
### AIM730_AO — FUNCTION : WORD
```
FUNCTION AIM730_AO : WORD
VAR_INPUT
DAC : REAL; // миллиамперы
RANGE : BYTE; // 0=0..20мА; 1=4..20мА
END_VAR
```
мА → код ЦАП. При `RANGE=1` и `DAC<4` принудительно возвращает код, соответствующий 4 мА.
### AIM731_AO — FUNCTION : WORD
```
FUNCTION AIM731_AO : WORD
VAR_INPUT
DAC : REAL; // вольты
RANGE : BYTE; // 0 = -10..+10В; 1 = 0..+10В
END_VAR
```
Вольты → код ЦАП модуля AIM731.
### DIM764_DI — FUNCTION : REAL
```
FUNCTION DIM764_DI : REAL
VAR_INPUT
IN : DWORD; // период/интервал от модуля, единицы АЦП
RANGE : BYTE; // 0=Period; 1=Interval
END_VAR
```
Возвращает частоту в Гц. При `IN=0` и `RANGE=0` — возвращает 0 (защита от деления на 0).
### AIM725_Status — FUNCTION_BLOCK
Формирование статуса аналогового канала с гистерезисом/задержками + диагностика по битам статуса модуля.
```
FUNCTION_BLOCK AIM725_Status
VAR_INPUT
Input : REAL; // контролируемое значение
fail_hi : REAL := 3.402823466E+38;
delta_fail_hi : REAL := 0;
time_fail_hi : TIME := T#0S;
warn_hi : REAL := 3.402823466E+38;
delta_warn_hi : REAL := 0;
time_warn_hi : TIME := T#0S;
warn_low : REAL := -3.402823466E+38;
delta_warn_low : REAL := 0;
time_warn_low : TIME := T#0S;
fail_low : REAL := -3.402823466E+38;
delta_fail_low : REAL := 0;
time_fail_low : TIME := T#0S;
time_no_signal : TIME := T#0S;
Modul_status : BYTE; // байт диагностики модуля АЦП (побитовые флаги ошибок канала)
Chanel_num : BYTE; // номер канала модуля (1 или 2) — выбирает, какие биты Modul_status проверять
END_VAR
VAR_OUTPUT
Status : AnalogValueState; // итоговый статус (см. раздел Structs)
T_mod : INT; // Input, приведённое к INT; -500 при no_signal
END_VAR
```
Приоритет статусов: `no_signal > fail_hi > fail_low > warn_hi > warn_low > normal`.
`no_signal` срабатывает если: `Input <= -200`, либо соответствующие биты `Modul_status` (зависящие от `Chanel_num`), либо биты 2/3 (общие ошибки модуля).
---
## Преобразование значений
`Path: Преобразование значений`
### DW_TO_REAL — FUNCTION : REAL
```
FUNCTION DW_TO_REAL : REAL
VAR_INPUT
X : DWORD;
END_VAR
```
**Побитовая** реинтерпретация DWORD как REAL через указатель (`ADR`) — НЕ конвертация значения. Платформозависимо.
### REAL_TO_DW — FUNCTION : DWORD
```
FUNCTION REAL_TO_DW : DWORD
VAR_INPUT
X : REAL;
END_VAR
```
Обратная операция к `DW_TO_REAL`. Побитовая реинтерпретация.
### DWORD_OF_2WORD — FUNCTION : DWORD
```
FUNCTION DWORD_OF_2WORD : DWORD
VAR_INPUT
W1 : WORD; // старшее слово, биты 16..31 результата
W0 : WORD; // младшее слово, биты 0..15 результата
END_VAR
```
### WORD_OF_DWORD — FUNCTION : WORD
```
FUNCTION WORD_OF_DWORD : WORD
VAR_INPUT
in : DWORD; // исходное значение
N : BYTE; // 0 = младшее слово (биты 0..15), 1 = старшее (биты 16..31)
END_VAR
```
### Norm_real — FUNCTION : REAL
Линейная нормировка (масштабирование по двум опорным точкам).
```
FUNCTION Norm_real : REAL
VAR_INPUT
X : REAL; // входное (ненормированное) значение
X1 : REAL; // точка 1, вход
Y1 : REAL; // точка 1, выход
X2 : REAL; // точка 2, вход
Y2 : REAL; // точка 2, выход
END_VAR
```
Если `X2=X1` — возвращает `Y1` (защита от деления на 0).
### NTC_termistor_T — FUNCTION : REAL
Перевод сопротивления NTC-термистора в температуру (уравнение Beta).
```
FUNCTION NTC_termistor_T : REAL
VAR_INPUT
Res : REAL; // измеренное сопротивление
R0 : REAL; // сопротивление при температуре T0
T0 : REAL; // опорная температура, °C
b : REAL; // коэффициент Beta термистора
END_VAR
```
Возвращает температуру в °C. При `Res<=0`, `R0<=0` или `b=0` возвращает `0.0`.
---
## Общие — Common
`Path: Общие`
### Дискретные сигналы / кнопки / таймеры
#### Button_acceleration — FUNCTION_BLOCK
Ускоренное изменение значения при удержании кнопки (для регулировки уставок и т.п.).
```
FUNCTION_BLOCK Button_acceleration
VAR_INPUT
Button : BOOL;
D_0 : REAL := 0; // приращение при одиночном (коротком) нажатии
T_W_1 : TIME := T#0S; // время до начала "короткого удержания"
T_D_1 : TIME := T#200MS; // шаг приращения при коротком удержании
D_1 : REAL := 0; // величина приращения на шаге T_D_1
T_W_2 : TIME := T#0S; // время до начала "длинного удержания"
T_D_2 : TIME := T#200MS; // шаг приращения при длинном удержании
D_2 : REAL := 0; // величина приращения на шаге T_D_2
Zeroes : BOOL := FALSE; // если TRUE — обнулять Out, когда |Out| < |D_0|
END_VAR
VAR_IN_OUT
Out : REAL; // изменяемое значение (передаётся и изменяется по ссылке!)
END_VAR
```
⚠️ Нет `VAR_OUTPUT` — результат только через `VAR_IN_OUT Out`.
#### Pulse_Switch — FUNCTION_BLOCK
```
FUNCTION_BLOCK Pulse_Switch
VAR_INPUT
Switch_ctrl : BOOL;
END_VAR
VAR_OUTPUT
Switch_on : BOOL; // импульс 500мс при фронте 0->1
Switch_off : BOOL; // импульс 500мс при фронте 1->0
END_VAR
```
#### TONOF — FUNCTION_BLOCK
Комбинированная задержка включения (TON) + выключения (TOF) для одного сигнала.
```
FUNCTION_BLOCK TONOF
VAR_INPUT
IN : BOOL;
T_ON : TIME := T#0S; // задержка появления TRUE на Q
T_OFF : TIME := T#0S; // задержка снятия TRUE с Q
END_VAR
VAR_OUTPUT
Q : BOOL;
END_VAR
```
#### TOF_RST — FUNCTION_BLOCK
Таймер выключения (TOF) с принудительным сбросом.
```
FUNCTION_BLOCK TOF_RST
VAR_INPUT
IN : BOOL;
PT : TIME; // задержка выключения
RST : BOOL; // немедленный сброс Q и таймера, приоритет над IN
END_VAR
VAR_OUTPUT
Q : BOOL;
ET : TIME; // текущее время таймера
END_VAR
```
#### TP_RST — FUNCTION_BLOCK
Одиночный импульс (TP) с принудительным сбросом.
```
FUNCTION_BLOCK TP_RST
VAR_INPUT
IN : BOOL; // фронт 0->1 запускает импульс (повторный фронт во время импульса игнорируется)
PT : TIME; // длительность импульса
RST : BOOL; // немедленно прерывает импульс
END_VAR
VAR_OUTPUT
Q : BOOL;
ET : TIME;
END_VAR
```
#### BLINK_LMP — FUNCTION_BLOCK
Управление лампой по коду состояния.
```
FUNCTION_BLOCK BLINK_LMP
VAR_INPUT
State : WORD := 0; // 0=выкл; 1=вкл; 2/3/4=мигание с частотой 1/2/3
Inp_BL_1 : BOOL := FALSE; // внешний "пульсар" (меандр) частоты 1
Inp_BL_2 : BOOL := FALSE; // частоты 2
Inp_BL_3 : BOOL := FALSE; // частоты 3
END_VAR
VAR_OUTPUT
LMP : BOOL;
END_VAR
```
#### BUZZER_CTRL — FUNCTION_BLOCK
Управление звонком/зуммером по коду состояния с отключением звука (временным и перманентным).
```
FUNCTION_BLOCK BUZZER_CTRL
VAR_INPUT
State : WORD := 0; // 0=выкл;1=вкл;2/3/4=мигание частота1/2/3
Sound_off : BOOL; // кнопка отключения звука
Inp_BL_1 : BOOL := FALSE; // пульсар частоты 1
Inp_BL_2 : BOOL := FALSE; // пульсар частоты 2
Inp_BL_3 : BOOL := FALSE; // пульсар частоты 3
PermanentOFF_Enable : BOOL := FALSE; // разрешить перманентное отключение звука
T_PermanentOFF : TIME := T#10S; // время удержания Sound_off для перманентного откл.
END_VAR
VAR_OUTPUT
BUZZER : BOOL;
END_VAR
```
#### CONFIRMATION — FUNCTION_BLOCK
Логика квитирования аварии (лампы + звонок).
```
FUNCTION_BLOCK CONFIRMATION
VAR_INPUT
Alarm : BOOL; // авария активна
ControlState_On : BOOL; // управление ведётся с данного поста
Sound_Off : BOOL; // сигнал снятия звука
Confirmation : BOOL; // сигнал квитирования
END_VAR
VAR_OUTPUT
Lamp_Alarm_C : WORD; // код для лампы аварии (0/1/2)
Lamp_Confirmation_C : WORD; // код для лампы квитирования (0/1)
Buzzer_C : WORD; // код для зуммера (0/2)
END_VAR
```
Коды ламп совместимы с входом `State`/`Inp_BL_*` блоков `BLINK_LMP`/`BUZZER_CTRL` (2 = "мигание частота 1").
### Пороговые сигналы / гистерезис
#### HYST — FUNCTION_BLOCK
Гистерезисный компаратор с раздельными порогами включения/выключения (прямая и обратная логика).
```
FUNCTION_BLOCK HYST
VAR_INPUT
In : REAL; // контролируемое значение
ON : REAL; // порог срабатывания
OFF : REAL; // порог возврата
END_VAR
VAR_OUTPUT
Q : BOOL; // состояние компаратора
win : BOOL; // TRUE — значение внутри зоны гистерезиса (неопределённая зона)
END_VAR
```
Если `ON >= OFF` — прямая логика (растущий сигнал включает); если `ON < OFF` — обратная (падающий сигнал включает).
#### ALARM_1 — FUNCTION_BLOCK
Контроль выхода `X` за диапазон `[LO_1..HI_1]` с гистерезисом.
```
FUNCTION_BLOCK ALARM_1
VAR_INPUT
X : REAL;
LO_1 : REAL;
HI_1 : REAL;
HYS : REAL; // полный гистерезис (берётся ±HYS/2 от границы)
END_VAR
VAR_OUTPUT
Q1_LO : BOOL; // X ниже LO_1
Q1_HI : BOOL; // X выше HI_1
END_VAR
```
#### ALARM_2 — FUNCTION_BLOCK
То же, для двух независимых диапазонов одновременно.
```
FUNCTION_BLOCK ALARM_2
VAR_INPUT
X : REAL;
LO_1, HI_1 : REAL;
LO_2, HI_2 : REAL;
HYS : REAL;
END_VAR
VAR_OUTPUT
Q1_LO, Q1_HI : BOOL;
Q2_LO, Q2_HI : BOOL;
END_VAR
```
#### ALARM_3 — FUNCTION_BLOCK
То же, для трёх диапазонов одновременно.
```
FUNCTION_BLOCK ALARM_3
VAR_INPUT
X : REAL;
LO_1, HI_1 : REAL;
LO_2, HI_2 : REAL;
LO_3, HI_3 : REAL;
HYS : REAL;
END_VAR
VAR_OUTPUT
Q1_LO, Q1_HI : BOOL;
Q2_LO, Q2_HI : BOOL;
Q3_LO, Q3_HI : BOOL;
END_VAR
```
### Статус аналоговых сигналов
#### STATUS_ANALOG_M — FUNCTION_BLOCK
Статус аналогового значения REAL с гистерезисом возврата и задержками срабатывания по каждому уровню; поддерживает принудительную установку статуса извне.
```
FUNCTION_BLOCK STATUS_ANALOG_M
VAR_INPUT
Input : REAL;
fail_hi : REAL := 3.402823466E+38;
delta_fail_hi : REAL := 0;
time_fail_hi : TIME := T#0S;
warn_hi : REAL := 3.402823466E+38;
delta_warn_hi : REAL := 0;
time_warn_hi : TIME := T#0S;
warn_low : REAL := -3.402823466E+38;
delta_warn_low : REAL := 0;
time_warn_low : TIME := T#0S;
fail_low : REAL := -3.402823466E+38;
delta_fail_low : REAL := 0;
time_fail_low : TIME := T#0S;
no_signal : REAL := -3.402823466E+38;
delta_no_signal : REAL := 0;
time_no_signal : TIME := T#0S;
In_fail_hi : BOOL := FALSE; // принудительно выставить статус fail_hi
In_warn_hi : BOOL := FALSE;
In_warn_low : BOOL := FALSE;
In_fail_low : BOOL := FALSE;
In_no_signal : BOOL := FALSE;
END_VAR
VAR_OUTPUT
Status : AnalogValueState;
END_VAR
```
Приоритет: `no_signal > fail_hi > fail_low > warn_hi > warn_low > normal`. Возврат из состояния — при пересечении порога `± delta_*`, срабатывание — с задержкой `time_*` (TON).
#### STATUS_ANALOG_M_I — FUNCTION_BLOCK
Полный аналог `STATUS_ANALOG_M`, но все пороги/входное значение типа **INT**, а не REAL. Сигнатура идентична по составу переменных (см. выше), только типы `Input`, `fail_hi`, `delta_fail_hi`, `warn_hi`, `delta_warn_hi`, `warn_low`, `delta_warn_low`, `fail_low`, `delta_fail_low`, `no_signal`, `delta_no_signal``INT` (диапазон по умолчанию ±32767/-32768).
### Диагностика связи
#### Status_SU_Connect — FUNCTION_BLOCK
Контроль связи по "сердцебиению" (сигнал должен периодически менять состояние).
```
FUNCTION_BLOCK Status_SU_Connect
VAR_INPUT
HeartBit : BOOL; // меняющийся сигнал от удалённого устройства
T_Pulse : TIME; // макс. допустимая длительность одного состояния HeartBit
END_VAR
VAR_OUTPUT
ERROR_CONNECT : BOOL; // TRUE — HeartBit не менялся дольше T_Pulse
END_VAR
```
#### Status_Connect_Counter — FUNCTION_BLOCK
Контроль связи по инкрементируемому счётчику от удалённого устройства.
```
FUNCTION_BLOCK Status_Connect_Counter
VAR_INPUT
Counter : WORD; // счётчик, инкрементируемый удалённым устройством
T_Error : TIME; // время без изменений счётчика для фиксации обрыва связи
END_VAR
VAR_OUTPUT
CounterIsChanged : BOOL; // TRUE в цикле, где счётчик изменился
ERROR_CONNECT : BOOL; // TRUE — счётчик не менялся дольше T_Error
END_VAR
```
### Регулирование
#### PIDcontrol — FUNCTION_BLOCK
ПИД-регулятор с фильтрацией D-составляющей, зоной нечувствительности, антивиндапом и ручным режимом.
```
FUNCTION_BLOCK PIDcontrol
VAR_INPUT
ProcessVariable : REAL := 0.0; // измеренное значение (обратная связь)
Setpoint : REAL := 0.0; // уставка
Kp : REAL := 0.001; // пропорциональный коэффициент
Ki : REAL := 0.001; // интегральный коэффициент
Kd : REAL := 0.0; // дифференциальный коэффициент
Kdf : REAL := 1.0; // коэффициент фильтра D-части (1/Tdf)
DBmax : REAL := 0.01; // верхняя граница зоны нечувствительности (по ошибке)
DBmin : REAL := -0.01; // нижняя граница зоны нечувствительности
OutMax : REAL := 100.0; // верхний предел выхода
OutMin : REAL := 0.0; // нижний предел выхода
Ts : REAL := 0.1; // период дискретизации, с
Manual : REAL := 25.0; // значение выхода в ручном режиме
ManOn : BOOL := FALSE; // TRUE — ручной режим
Reset : BOOL := FALSE; // сброс интегратора и D-части
AntiWindup : BOOL := TRUE; // включить компенсацию накопления интегратора
END_VAR
VAR_OUTPUT
Out : REAL := 0.0; // выходной сигнал регулятора
Err : REAL := 0.0; // текущая ошибка регулирования (Setpoint-ProcessVariable)
OutLimited : BOOL := FALSE; // TRUE — выход ограничен (насыщение) или некорректны параметры
END_VAR
```
Если `OutMin>=OutMax`, `DBmin>=DBmax` или `Ts<=0` — блок сразу выставляет `Out:=0`, `OutLimited:=TRUE` и выходит.
### Структуры данных (очереди/стеки)
Общая сигнатура для всех 4 блоков (`QUEUE_I16`, `QUEUE_I32`, `STACK_I16`, `STACK_I32`) — идентична, отличаются только ёмкость и дисциплина (FIFO/LIFO):
```
FUNCTION_BLOCK <Имя>
VAR_INPUT
Din : INT; // значение для записи
E : BOOL := TRUE; // включение блока (при FALSE — операции не выполняются)
POP : BOOL; // извлечь элемент
PUSH: BOOL; // добавить элемент
RST : BOOL; // сброс (очистка)
END_VAR
VAR_OUTPUT
Dout : INT; // извлечённое значение (при POP)
EMPTY : BOOL := TRUE; // TRUE — пусто
FULL : BOOL; // TRUE — заполнено (достигнут предел)
END_VAR
```
| Имя | Дисциплина | Ёмкость |
|---|---|---|
| `QUEUE_I16` | FIFO (очередь) | 16 элементов INT |
| `QUEUE_I32` | FIFO (очередь) | 32 элемента INT |
| `STACK_I16` | LIFO (стек) | 16 элементов INT |
| `STACK_I32` | LIFO (стек) | 32 элемента INT |
Примечание: при одновременном `PUSH` и `POP` в одном скане — оба выполняются (POP обрабатывается первым в теле, затем PUSH).
---
## Иное
`Path: Иное`
### DFS — PROGRAM
Обход графа в глубину (Depth-First Search) по матрице смежности фиксированного размера.
```
PROGRAM DFS
VAR_INPUT
graph : POINTER TO ARRAY[1..n, 1..n] OF BOOL; // матрица смежности, редактируется извне: DFS.graph[i,j]
connected : POINTER TO ARRAY[1..n] OF INT; // выход: список посещённых вершин (заполняется программой)
Start : INT := 1; // вершина, с которой начинается обход
END_VAR
VAR CONSTANT
n : INT := 12; // фиксированное количество вершин графа
END_VAR
```
⚠️ Это **PROGRAM**, а не FUNCTION_BLOCK — не инстанцируется через `:` в декларации переменной, а копируется целиком в проект пользователя (как указано в исходном комментарии `Копировать в свою программу`). Использует `STACK_I16` внутри. Результат — заполненный массив `connected^[1..k-1]` с номерами вершин, достижимых из `Start`.
---
## Structs
`Path: Structs`
### AnalogValueState — DUT (перечисление)
```
{attribute 'qualified_only'}
{attribute 'strict'}
TYPE AnalogValueState :
(
undefined := INT#0,
normal := INT#1,
warn_low := INT#2,
fail_low := INT#3,
warn_hi := INT#4,
fail_hi := INT#5,
no_signal := -INT#1
) := undefined;
END_TYPE
```
`qualified_only` — обращаться только как `AnalogValueState.normal` и т.п. (без квалификатора не компилируется).
Используется как тип выхода `Status` в `AIM725_Status`, `STATUS_ANALOG_M`, `STATUS_ANALOG_M_I`.
---
## Общие правила / соглашения библиотеки
1. **Приоритет статусов** во всех блоках статуса аналоговых сигналов (`AIM725_Status`, `STATUS_ANALOG_M`, `STATUS_ANALOG_M_I`) одинаков:
`no_signal > fail_hi > fail_low > warn_hi > warn_low > normal`.
2. **Гистерезис срабатывания/возврата**: срабатывание уровня — по достижению порога с задержкой `time_*` (аналог TON), возврат — при пересечении `порог ± delta_*` (без задержки).
3. Блоки `TOF_RST`/`TP_RST` — это стандартные МЭК TOF/TP с добавленным принудительным входом `RST` (сброс приоритетнее `IN`).
4. `DW_TO_REAL`/`REAL_TO_DW` — это **не** преобразование значения (не `DWORD_TO_REAL`), а побитовая реинтерпретация памяти через указатель. Использовать только когда явно нужна побитовая переупаковка (например, чтение REAL-регистра Modbus, пришедшего как два WORD → DWORD → REAL).
5. `QUEUE_I16`/`STACK_I16` — фиксированный размер 16 (`n:=15` внутри), `QUEUE_I32`/`STACK_I32` — размер 32. Чтобы изменить ёмкость — нужно менять исходник (константу `n` и объявление массива).
6. `DFS` — не библиотечный вызываемый блок, а шаблон программы под конкретный размер графа (`n:=12`); предназначен для копирования и адаптации в проекте пользователя.
7. Все входы с `VAR_IN_OUT` (только у `Button_acceleration.Out`) передаются **по ссылке** — вызывающая сторона должна сама объявить и инициализировать переменную, изменения применяются напрямую.
8. Единицы времени — везде тип `TIME` (`T#...`), единицы физических величин указаны в комментариях к каждому входу/выходу (мА, В, Гц, °C, Ом, °C и т.д.).