diff --git a/PLC_Library.library b/PLC_Library.library index 41db08e..be96d90 100644 Binary files a/PLC_Library.library and b/PLC_Library.library differ diff --git a/README.md b/README.md index f59086f..ee4783e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,140 @@ # PLC_Library -Моя библиотека для CoDeSys 3.5 +Библиотека функций (FUNCTION) и функциональных блоков (FUNCTION_BLOCK) на языке **Structured Text (ST)** для CoDeSys 3.5. +Библиотека содержит фильтры сигналов, обработку кнопок и дискретных сигналов, работу со статусами и авариями аналоговых величин, преобразование типов данных, драйверы модулей Fastwel и вспомогательные структуры/алгоритмы. + +## Структура + +```text +PLC_Library/ +├── Filters/ — фильтрация и усреднение сигналов +├── Fastwel/ — преобразование сигналов модулей Fastwel (АЦП/ЦАП) +├── Преобразование значений/ — преобразование типов данных +├── Общие/ — общие блоки (кнопки, таймеры, статусы, очереди/стеки, ПИД, сигнализация) +├── Иное/ — прочие алгоритмы +└── Structs/ — пользовательские типы данных +``` + +--- + +## Filters — Фильтры + +| Имя | Тип | Описание | +| --- | --- | --- | +| `ExpRunAverage` | FUNCTION (REAL) | Экспоненциальное скользящее среднее с постоянным коэффициентом `K`. | +| `ExpRunAverageAdaptive` | FUNCTION (REAL) | Экспоненциальное скользящее среднее с адаптивным коэффициентом: если изменение входа превышает `Delta`, используется увеличенный коэффициент `K2` вместо `K1` (быстрая реакция на резкие изменения). | +| `RunMiddleArifm` | FUNCTION_BLOCK | Скользящее среднее арифметическое по кольцевому буферу размером до 32 отсчётов (`N`), с возможностью сброса/переинициализации (`RST`). | +| `MultipleClick` | FUNCTION_BLOCK | Детектор серии нажатий кнопки (одиночный/двойной/тройной клик) по паузе между нажатиями `TimeToWait`, с удержанием результата на `TimeRelease`. | + +--- + +## Fastwel — Модули ввода/вывода Fastwel + +Функции перевода "сырых" значений АЦП/кодов модулей Fastwel в физические единицы (мА, В, Гц) и обратно (ЦАП), а также формирование статуса аналогового канала. + +| Имя | Тип | Описание | +| --- | --- | --- | +| `AIM721_AI` | FUNCTION (REAL) | АЦП → 0…20 мА. | +| `AIM722_AI` | FUNCTION (REAL) | АЦП → 0…20 мА (свой коэффициент модуля). | +| `AIM723_AI` | FUNCTION (REAL) | АЦП → 4…20 мА. | +| `AIM726_AI` | FUNCTION (REAL) | АЦП (DWORD) → 0…40 В. | +| `AIM727_AI` | FUNCTION (REAL) | АЦП (DINT) → 0…40 В. | +| `AIM791_AI` | FUNCTION (REAL) | АЦП → 0…5 мА / 0…20 мА / 4…20 мА (выбор диапазона через `RANGE`). | +| `AIM730_AO` | FUNCTION (WORD) | мА (0…20 или 4…20, выбор `RANGE`) → код ЦАП модуля AIM730. | +| `AIM731_AO` | FUNCTION (WORD) | В (±10 или 0…10, выбор `RANGE`) → код ЦАП модуля AIM731. | +| `DIM764_DI` | FUNCTION (REAL) | Период/интервал импульсного входа модуля → частота в Гц (выбор режима `RANGE`). | +| `AIM725_Status` | FUNCTION_BLOCK | Формирование статуса аналогового канала (`AnalogValueState`): аварии/предупреждения по верхнему и нижнему порогам с гистерезисом и выдержками времени, а также диагностика обрыва связи по битам `Modul_status` конкретного канала (`Chanel_num`). Дополнительно выдаёт `T_mod` — значение, приведённое к INT. | + +--- + +## Преобразование значений — Conversions + +| Имя | Тип | Описание | +| --- | --- | --- | +| `DW_TO_REAL` | FUNCTION (REAL) | Побитовая реинтерпретация DWORD как REAL (без изменения значения, через указатель). | +| `REAL_TO_DW` | FUNCTION (DWORD) | Побитовая реинтерпретация REAL как DWORD (обратное преобразование). | +| `DWORD_OF_2WORD` | FUNCTION (DWORD) | Сборка DWORD из двух WORD (старшее + младшее слово). | +| `WORD_OF_DWORD` | FUNCTION (WORD) | Извлечение младшего или старшего слова (WORD) из DWORD по флагу `N`. | +| `Norm_real` | FUNCTION (REAL) | Линейная нормировка значения `X` по двум точкам `(X1,Y1)`–`(X2,Y2)` (масштабирование диапазона). | +| `NTC_termistor_T` | FUNCTION (REAL) | Перевод сопротивления NTC-термистора в температуру по уравнению Бета (`R0`, `T0`, `b`). | + +--- + +## Общие — Common + +### Дискретные сигналы / кнопки / таймеры + +| Имя | Тип | Описание | +| --- | --- | --- | +| `Button_acceleration` | FUNCTION_BLOCK | Ускоренное изменение значения (`Out`, VAR_IN_OUT) при удержании кнопки: одиночный клик даёт приращение `D_0`, короткое удержание — приращения `D_1` с шагом `T_D_1` после `T_W_1`, длительное удержание — `D_2` с шагом `T_D_2` после `T_W_2`. Есть опция обнуления `Zeroes`. | +| `Pulse_Switch` | FUNCTION_BLOCK | Формирует импульсы по 500 мс по переднему (`Switch_on`) и заднему (`Switch_off`) фронтам управляющего сигнала. | +| `TONOF` | FUNCTION_BLOCK | Комбинированная задержка включения/выключения (TON + TOF) для одного сигнала. | +| `TOF_RST` | FUNCTION_BLOCK | Таймер выключения (TOF) с принудительным сбросом `RST`. | +| `TP_RST` | FUNCTION_BLOCK | Одиночный импульс (TP) с принудительным сбросом `RST`; повторный фронт во время импульса игнорируется. | +| `BLINK_LMP` | FUNCTION_BLOCK | Управление лампой по коду состояния `State` (выкл/вкл/мигание с одной из 3 частот, задаваемых внешними пульсарами). | +| `BUZZER_CTRL` | FUNCTION_BLOCK | Управление звонком/зуммером по коду состояния, с возможностью временного и перманентного отключения звука (`Sound_off`, `PermanentOFF_Enable`). | +| `CONFIRMATION` | FUNCTION_BLOCK | Логика квитирования аварии: формирует сигналы ламп аварии/квитирования и управления звонком. | + +### Пороговые сигналы / гистерезис + +| Имя | Тип | Описание | +| --- | --- | --- | +| `HYST` | FUNCTION_BLOCK | Гистерезисный компаратор с раздельными порогами включения (`ON`) и выключения (`OFF`); поддерживает прямую и обратную логику. | +| `ALARM_1` | FUNCTION_BLOCK | Контроль значения `X` на выход за один диапазон `[LO_1…HI_1]` с гистерезисом `HYS`. | +| `ALARM_2` | FUNCTION_BLOCK | То же для двух диапазонов одновременно. | +| `ALARM_3` | FUNCTION_BLOCK | То же для трёх диапазонов одновременно. | + +### Статус аналоговых сигналов + +| Имя | Тип | Описание | +| --- | --- | --- | +| `STATUS_ANALOG_M` | FUNCTION_BLOCK | Формирование статуса аналогового значения REAL (`AnalogValueState`) с гистерезисом возврата и задержками срабатывания по каждому из уровней (fail/warn hi/low, no_signal); поддерживает принудительную установку каждого статуса извне. | +| `STATUS_ANALOG_M_I` | FUNCTION_BLOCK | Аналог `STATUS_ANALOG_M`, но для входа типа INT. | + +### Диагностика связи + +| Имя | Тип | Описание | +| --- | --- | --- | +| `Status_SU_Connect` | FUNCTION_BLOCK | Контроль связи по "сердцебиению" (`HeartBit`): авария, если сигнал не меняет состояние дольше `T_Pulse`. | +| `Status_Connect_Counter` | FUNCTION_BLOCK | Контроль связи по счётчику `Counter` от удалённого устройства: авария, если счётчик не меняется дольше `T_Error`. | + +### Регулирование + +| Имя | Тип | Описание | +| --- | --- | --- | +| `PIDcontrol` | FUNCTION_BLOCK | ПИД-регулятор с фильтрацией дифференциальной составляющей, зоной нечувствительности (`DBmin/DBmax`), ограничением выхода, антивиндапом и ручным режимом (`ManOn`/`Manual`). | + +### Структуры данных + +| Имя | Тип | Описание | +| --- | --- | --- | +| `QUEUE_I16` | FUNCTION_BLOCK | Кольцевая очередь FIFO на 16 элементов типа INT (`PUSH`/`POP`, флаги `EMPTY`/`FULL`, сброс `RST`). | +| `QUEUE_I32` | FUNCTION_BLOCK | Кольцевая очередь FIFO на 32 элемента типа INT (`PUSH`/`POP`, флаги `EMPTY`/`FULL`, сброс `RST`). | +| `STACK_I16` | FUNCTION_BLOCK | Стек LIFO на 16 элементов типа INT (`PUSH`/`POP`, флаги `EMPTY`/`FULL`, сброс `RST`). | +| `STACK_I32` | FUNCTION_BLOCK | Стек LIFO на 32 элемента типа INT (`PUSH`/`POP`, флаги `EMPTY`/`FULL`, сброс `RST`). | + +--- + +## Иное — Other + +| Имя | Тип | Описание | +| --- | --- | --- | +| `DFS` | PROGRAM | Обход графа в глубину (Depth-First Search) по матрице смежности `graph` фиксированного размера (12 вершин); использует `STACK_I16`. Возвращает список посещённых из `Start` вершин в массиве `connected`. Предназначен для копирования в пользовательскую программу. | + +--- + +## Structs — Пользовательские типы + +| Имя | Тип | Описание | +| --- | --- | --- | +| `AnalogValueState` | DUT (перечисление, `qualified_only`, `strict`) | Статус аналогового значения: `undefined`(0), `normal`(1), `warn_low`(2), `fail_low`(3), `warn_hi`(4), `fail_hi`(5), `no_signal`(-1). Используется в `AIM725_Status`, `STATUS_ANALOG_M`, `STATUS_ANALOG_M_I`. | + +--- + +## Замечания по использованию + +- Функции `DW_TO_REAL` / `REAL_TO_DW` выполняют **побитовую** реинтерпретацию через указатель (`ADR`), а не преобразование значения — использовать осторожно, с учётом платформозависимости работы с указателями. +- Блоки `STATUS_ANALOG_M[_I]` и `AIM725_Status` используют единый тип `AnalogValueState` и схожую логику приоритетов статусов: `no_signal` > `fail_hi` > `fail_low` > `warn_hi` > `warn_low` > `normal`. +- `TOF_RST` и `TP_RST` — версии стандартных МЭК-таймеров TOF/TP с добавленным входом принудительного сброса `RST`. +- `QUEUE_I16` и `STACK_I16` имеют фиксированный размер 16 элементов (константа `n:=15`); для изменения размера нужно менять константу `n` и размер массива. +- `DFS` рассчитан на графы фиксированного размера (константа `n:=12`) и предназначен для копирования кода в пользовательскую программу, а не для использования "как есть" в виде библиотечного вызова. diff --git a/compiled library/PLC_Library v1.6.1.compiled-library b/compiled library/PLC_Library v1.6.1.compiled-library new file mode 100644 index 0000000..dc1cba3 Binary files /dev/null and b/compiled library/PLC_Library v1.6.1.compiled-library differ diff --git a/plc_src/POU/Общие/QUEUE_I32.st b/plc_src/POU/Общие/QUEUE_I32.st new file mode 100644 index 0000000..f56804e --- /dev/null +++ b/plc_src/POU/Общие/QUEUE_I32.st @@ -0,0 +1,66 @@ +(* +=============================================================================== + Project : PLC_Library + Device : - + Path : Общие + Name : QUEUE_I32 + Type : FUNCTION_BLOCK +=============================================================================== +*) + +FUNCTION_BLOCK QUEUE_I32 +(* + Очередь FIFO на 32 элемента типа INT +*) +VAR_INPUT + Din : INT; (* Переменная для записи в очередь *) + E : BOOL := TRUE; (* Включение очереди *) + POP : BOOL; (* Извлечение из очереди *) + PUSH : BOOL; (* Добавление в очередь *) + RST : BOOL; (* Сброс *) +END_VAR +VAR_OUTPUT + Dout : INT; (* Значение, извлеченное из очереди *) + EMPTY : BOOL := TRUE; + FULL : BOOL; +END_VAR +VAR + queue : ARRAY[0..n] OF INT; + Head : INT; (* индекс чтения *) + Tail : INT; (* индекс записи *) + Count : INT; (* количество элементов *) +END_VAR +VAR CONSTANT + n : INT := 31; (* 32 элемента *) +END_VAR +(*----- IMPLEMENTATION -----*) +IF RST THEN + Head := 0; + Tail := 0; + Count := 0; + EMPTY := TRUE; + FULL := FALSE; + Dout := 0; +ELSIF E THEN + (* Извлечение *) + IF POP AND NOT EMPTY THEN + Dout := queue[Head]; + Head := Head + 1; + IF Head > n THEN + Head := 0; + END_IF; + Count := Count - 1; + END_IF; + (* Добавление *) + IF PUSH AND NOT FULL THEN + queue[Tail] := Din; + Tail := Tail + 1; + IF Tail > n THEN + Tail := 0; + END_IF; + Count := Count + 1; + END_IF; + EMPTY := (Count = 0); + FULL := (Count = n + 1); +END_IF; +END_FUNCTION_BLOCK diff --git a/plc_src/POU/Общие/STACK_I16.st b/plc_src/POU/Общие/STACK_I16.st index fb963c4..497374c 100644 --- a/plc_src/POU/Общие/STACK_I16.st +++ b/plc_src/POU/Общие/STACK_I16.st @@ -10,7 +10,7 @@ FUNCTION_BLOCK STACK_I16 (* - Стек на 16 элементов типа INT + Стек LIFO на 16 элементов типа INT *) VAR_INPUT Din : INT; (* Переменная для записи в стек *) @@ -29,12 +29,11 @@ VAR pt : INT; END_VAR VAR CONSTANT - n : INT := 15; (* changing this value will chage the number of stored elements in the fifo *) + n : INT := 15; (* 16 элементов *) END_VAR (*----- IMPLEMENTATION -----*) IF RST THEN - (* asynchronous reset for the fifo *) pt := 0; EMPTY := TRUE; FULL := FALSE; diff --git a/plc_src/POU/Общие/STACK_I32.st b/plc_src/POU/Общие/STACK_I32.st new file mode 100644 index 0000000..3691ccd --- /dev/null +++ b/plc_src/POU/Общие/STACK_I32.st @@ -0,0 +1,55 @@ +(* +=============================================================================== + Project : PLC_Library + Device : - + Path : Общие + Name : STACK_I32 + Type : FUNCTION_BLOCK +=============================================================================== +*) + +FUNCTION_BLOCK STACK_I32 +(* + Стек LIFO на 32 элемента типа INT +*) +VAR_INPUT + Din : INT; (* Переменная для записи в стек *) + E : BOOL := TRUE; (* Включение стека *) + POP : BOOL; (* Извлечение из стека *) + PUSH : BOOL; (* Запись в стек *) + RST : BOOL; (* Обнуление стека *) +END_VAR +VAR_OUTPUT + Dout : INT; (* Значение, извлеченное из стека при POP *) + EMPTY : BOOL := TRUE; (* Флаг "стек пуст" *) + FULL : BOOL; (* Флаг "стек заполнен" (достигнут предел n) *) +END_VAR +VAR + stack: ARRAY[0..n] OF INT; + pt : INT; +END_VAR +VAR CONSTANT + n : INT := 31; (* 32 элемента *) +END_VAR + +(*----- IMPLEMENTATION -----*) +IF RST THEN + pt := 0; + EMPTY := TRUE; + FULL := FALSE; + Dout := 0; +ELSIF E THEN + IF NOT EMPTY AND POP THEN + pt := pt - 1; + Dout := stack[pt]; + EMPTY := pt = 0; + FULL := FALSE; + END_IF; + IF NOT FULL AND PUSH THEN + stack[pt] := Din; + pt := pt + 1; + FULL := pt > n; + EMPTY := FALSE; + END_IF; +END_IF; +END_FUNCTION_BLOCK