PHP код:
FUNCTION_BLOCK ValveControl
VAR_INPUT
PIDOutput: REAL; // 0-100% от PID-регулятора
FullTime: REAL; // Время полного хода клапана в секундах
OpenState: BOOL; // Состояние клапана "Открыт"
CloseState: BOOL; // Состояние клапана "Закрыт"
UnixTime: UDINT; // Текущее время в Unix формате (секунды)
END_VAR
VAR_OUTPUT
OpenOutput: BOOL; // Выход "Открыть"
CloseOutput: BOOL; // Выход "Закрыть"
OpenTime: REAL; // Рассчитанное время открытия (секунды)
CloseTime: REAL; // Рассчитанное время закрытия (секунды)
END_VAR
VAR
PreviousOutput: REAL; // Предыдущее значение сигнала PID
OpenTimeCounter: REAL; // Счетчик времени открытия
CloseTimeCounter: REAL; // Счетчик времени закрытия
OpenTimerStarted: BOOL; // Флаг запуска таймера открытия
CloseTimerStarted: BOOL; // Флаг запуска таймера закрытия
Initialized: BOOL; // Флаг инициализации
LastOpenTime: UDINT; // Время начала таймера открытия
LastCloseTime: UDINT; // Время начала таймера закрытия
END_VAR
// Инициализация переменных при первом вызове функции
IF NOT Initialized THEN
PreviousOutput := 0;
OpenTimeCounter := 0;
CloseTimeCounter := 0;
OpenTimerStarted := FALSE;
CloseTimerStarted := FALSE;
Initialized := TRUE;
END_IF
// Проверка состояния клапана
IF OpenState THEN
OpenTimeCounter := 0; // Сбрасываем счетчик времени открытия
OpenTimerStarted := FALSE;
OpenOutput := FALSE; // Сбрасываем выход "Открыть"
ELSIF CloseState THEN
CloseTimeCounter := 0; // Сбрасываем счетчик времени закрытия
CloseTimerStarted := FALSE;
CloseOutput := FALSE; // Сбрасываем выход "Закрыть"
END_IF
// Вычисление времени удержания выхода
IF PIDOutput > PreviousOutput THEN
OpenTimeCounter := OpenTimeCounter + (PIDOutput - PreviousOutput) / 100 * FullTime;
ELSIF PIDOutput < PreviousOutput THEN
CloseTimeCounter := CloseTimeCounter + (PreviousOutput - PIDOutput) / 100 * FullTime;
END_IF
// Установка выхода "Открыть"
IF OpenTimeCounter > 0 AND NOT OpenTimerStarted THEN
OpenTimerStarted := TRUE;
LastOpenTime := UnixTime; // Запоминаем начальное время
OpenOutput := TRUE;
END_IF
// Проверка таймера открытия
IF OpenTimerStarted THEN
// Сбрасываем выход "Открыть" только если таймер сработал
IF UnixTime - LastOpenTime >= REAL_TO_UDINT(OpenTimeCounter) THEN
OpenOutput := FALSE;
OpenTimerStarted := FALSE;
OpenTimeCounter := 0;
END_IF
// Сбрасываем выход "Открыть" если клапан уже открыт
IF OpenState THEN
OpenOutput := FALSE;
OpenTimerStarted := FALSE;
OpenTimeCounter := 0;
END_IF
END_IF
// Установка выхода "Закрыть"
IF CloseTimeCounter > 0 AND NOT CloseTimerStarted THEN
CloseTimerStarted := TRUE;
LastCloseTime := UnixTime; // Запоминаем начальное время
CloseOutput := TRUE;
END_IF
// Проверка таймера закрытия
IF CloseTimerStarted THEN
// Сбрасываем выход "Закрыть" только если таймер сработал
IF UnixTime - LastCloseTime >= REAL_TO_UDINT(CloseTimeCounter) THEN
CloseOutput := FALSE;
CloseTimerStarted := FALSE;
CloseTimeCounter := 0;
END_IF
// Сбрасываем выход "Закрыть" если клапан уже закрыт
IF CloseState THEN
CloseOutput := FALSE;
CloseTimerStarted := FALSE;
CloseTimeCounter := 0;
END_IF
END_IF
// Сохранение текущего значения сигнала PID
PreviousOutput := PIDOutput;
// Установка выходных значений OpenTime и CloseTime
OpenTime := OpenTimeCounter;
CloseTime := CloseTimeCounter;
END_FUNCTION_BLOCK