а т.к. в ST нет ретайнов, то требуется внешнюю обертку делать и получится что ПР не в роли контроллера технологического процесса а как счетчик наработки с визуализацией
Вид для печати
Это выглядит примерно так:
Вложение 82829
Код:function_block WorkTime
var_input
in: bool; // Состояние оборудования
end_var
var_output
Q, Q1, Q2, Q3, Q4 : udint; // Наработка текущая и недельная в секундах
end_var
var
rtWeek: SYS.RTRIG; // Триггер начала недели
rt: SYS.RTRIG; // Триггер включения
ft: SYS.FTRIG; // Триггер выключения
ts: udint; // Метка времени включения
end_var
// Фиксируем начало новой недели
rtWeek(I := (dt_to_udint(get_date_time()) / 86400 mod 7 = 2));
if rtWeek.Q then
if in then // Сохраняем текущую наработку и начинаем следующую
Q := Q + dt_to_udint(get_date_time()) - ts; ts := dt_to_udint(get_date_time());
end_if
Q4 := Q3; Q3 := Q2; Q2 := Q1; Q1 := Q; Q := 0; // Сдвигаем наработки
end_if
// Накопление наработки
rt(I:=in); ft(I:=in);
if rt.Q then ts := dt_to_udint(get_date_time()); end_if
if ft.Q then Q := Q + dt_to_udint(get_date_time()) - ts; end_if
end_function_block
Примитивно, но работает и, главное, энергонезависимое
Вложение 82836
ребята, здравствуйте!
подскажите пожалуйста, начинаю первый проект на ПР205 (ПР205-230.1211.26.2.0), с паскалем знаком, нужен простейший пример, хочу дергать выходом контактор 220В для включения насоса по таймеру.
Есть ли где-то уроки или типа такого, для начинающих?
В чистом виде ST код если написать, его куда-то можно вставить или нужно только FDB схему рисовать для начала?
Цитата:
PROGRAM WaterPumpControl
VAR
Timer : TON; (* Таймер на 4 часа *)
PumpControl : BOOL := FALSE; (* Управление насосом *)
LowLevel : BOOL; (* Нижний уровень *)
HighLevel : BOOL; (* Верхний уровень *)
Overflow : BOOL; (* Аварийный уровень *)
StartTime : TIME := T#4H; (* Время цикла включения насоса *)
END_VAR
(* Логика работы *)
IF Overflow THEN
PumpControl := FALSE; (* Выключение насоса при переполнении *)
ELSIF HighLevel THEN
PumpControl := FALSE; (* Выключение при достижении верхнего уровня *)
ELSIF NOT HighLevel AND NOT Timer.Q THEN
Timer(IN := TRUE, PT := StartTime); (* Запуск таймера каждые 4 часа *)
END_IF;
IF Timer.Q AND LowLevel THEN
PumpControl := TRUE; (* Включение насоса если сработал таймер и низкий уровень воды *)
END_IF;
(* Управление выходом реле *)
OUT_PUMP := PumpControl; (* OUT_PUMP - выход, управляющий контактором насоса *)
В Лоджике ST немного другой (урезанный), есть только ФБ и функции (программ нет, как нет и глобальных переменных), таймеры есть системные и самописные,
тут 3 пример, наработка, ротация 4 насосов по времени и включение от уровня https://owen.ru/forum/showthread.php...l=1#post426052
В данном примере наработка не сохраняется ври выключении питания ( смотри примеры 4 и 5, там сохраняется)
по сбросу понял, спасибо.
вода появляется в скважине каждые 4 часа, чтобы набирать воду. малый дебет очень.
ST2K Вызов таймера должен быть ВСЕГДА в теле основной программы - ни в каких IF.
Если удобно потратить чуть-чуть времени, то вот тут я писал со скриншотами про это (нужен заголовок 7): https://cs-cs.net/funkciya-fun-i-fun...n_tof_tp_blink
Может быть тут вообще применить BLINK? И сделать так, чтобы насос мог запускаться не ранее чем каждые 4 часа?
Понятно.
Я бы так сделал
Код:function_block WaterPumpControl
var_input //объявление входных переменных
Enable : bool; //разрешение на работу
LowLevel : bool; //низкий уровень
HightLevel : bool; //высокий уровень
Overflow : bool; //аварийный высокий уровень
AlarmPump : bool; //авария насоса (защита от сухого хода)
ForseStart : bool; //принудительное наполнение
end_var
var_output //объявление выходных переменных
Q : bool;
end_var
var //объявление локальных переменных
PumpControl : SYS.RS; // управление насосом
Timer : SYS.TON; // таймер
rtrig : SYS.RTRIG; // триггер
end_var
Timer(I := not Q, T := t#4h); //до повторного запуска насоса должно пройти 4 часа
rtrig(I := ForseStart); //принудительное включение насоса (не дожидаясь таймера)
PumpControl(R := HightLevel or Overflow or AlarmPump or not Enable , S := (LowLevel and Timer.Q) or rtrig.Q); //условие запуска и остановки насоса
Q := PumpControl.Q;
end_function_block
Прошу сильно не пинать, первые шаги в освоении ST....
использовал учебник Иванова и мануал по ПР-205:
решил с простого начать:
Задача модели мониторить датчики в емкости и обрабатывать принудительный ручной запуск набора воды в емкость. Насос скважины качает соленую воду, прогоняет через осмос (в осмосе свой насос высокого давления)
и набирает емкость 750 литров до уровня FULL. включение по датчику LOW. На всякий случай аварийный датчик переполнения, если с датчиком FULL что-то произойдет.
В модели 4 клапана, один подает воду в емкость 750 литров, второй (на будущее) будет подавать воду во вторую емкость 5000 литров, если 750 наполнена уже или принудительно. Третий открывает дренаж на слив грязной воды.
Четвертый открывается чтобы подавать неочищенную воду, естественно, закрывая все остальные.(это тоже TODO...)
1. не совсем понял как в режиме симуляции в интерактивном режиме менять значения на входах реле, чтобы увидеть как работает модель.(выставлять 0 или 1 на выбранном входе и наблюдать изменения).
нашел только что можно открыт окно просмотра при запущенной симуляции и там добавить вход и в нем поменять переменную... а вот чтобы щелкнуть на виртуальную кнопку (как, например, в Proteus) такого там нет?
2. как работает в принципе функциональный блок, исполняется ли он в цикле или же разово? т.е. крутится в цикле, опрашивает входы или же выполняется как только происходит изменения на входных переменных?
или же мониторинг входов нужно вешать на триггеры, которые срабатывают при изменении одного из входов и тогда запускать на выполнение функциональный блок? Хочу понять принцип и подход. Как я понимаю, постоянно гонять
опрос входов - это грузить процессор на 100%? или тут другая ситуация?
3. как отключить насос скважины через 5 секунд после остановки насоса осмоса. Не выключается выход реле через 5 секунд. Включение насоса c задержкой 10 секунд идет нормально, клапана тоже все открываются нормально, при сбросе I4 в 0 все выключается , а PumpSKV остается работать...
d
Код://включение режима подачи воды из скважины и очистки ее установкой осмоса
//с подачей очищенной воды в емкость 750 литров.
function_block OsmosHomeMode
var_input
Level750_Overflow : bool;
Level750_LOW : bool;
Level750_FULL : bool;
Manual_Start : bool;
end_var
var_output
PumpSKV : bool; //выход на контактор насоса скважины
PumpOSMOS : bool; //выход на контактор насоса установки обратного осмоса
Klapan750 : bool;//клапан на емкость 750 литров для подачи в дом
Klapan5000 : bool;//клапан на емкость 5000 литров для полива
KlapanSLIV : bool;//клапан открывает дренажную трубу для слива грязной воды, концентрата
KlapanRAW : bool; //клапан подачи неочищенной воды
end_var
var
OSMOSPump_ON_Delay : SYS.TON;
SKVPump_OFF_Delay : SYS.TOF;
NeedSTOP : bool;
end_var
IF Level750_LOW or Manual_Start THEN //нажали кнопку с фиксацией или уровень упал ниже минимального
Klapan750 := TRUE; //открываем клапан на набор очищенной воды в емкость 750л
KlapanSLIV := TRUE; //открываем клапан на дренаж концентрата после осмоса
Klapan5000 := FALSE; //закрываем клапан на емкость 5000
KlapanRAW := FALSE; //закрываем клапан слива неочищенной воды
PumpSKV:=TRUE; //включаем насос скважины
OSMOSPump_ON_Delay(I:=Level750_LOW or Manual_Start,T:=T#10S,Q=>PumpOSMOS);//включение насоса осмоса через10 секунд после насоса скважины
ELSE
PumpOSMOS:=FALSE; //отключаем насос установки осмоса
Klapan750 := FALSE; //закрываем клапан на набор очищенной воды в емкость 750л
Klapan5000 := FALSE; //закрываем клапан на емкость 5000
KlapanRAW := FALSE; //закрываем клапан слива неочищенной воды
//NeedSTOP := NOT ((NOT Manual_Start) OR Level750_FULL or Level750_Overflow); //если отключится кнопка или сработает датчик наполнения или аварийный
NeedSTOP:=TRUE;
SKVPump_OFF_Delay(I:=NeedSTOP,T:=T#5S);//выключение насоса скважины через 5 секунд после насоса осмоса
PumpSKV:=SKVPump_OFF_Delay.Q; //!!! насос не выключается через 5 секунд
KlapanSLIV := FALSE; //закрываем клапан на дренаж
END_IF;
end_function_block