PDA

Просмотр полной версии : Программа на языке ST



Slait_gul
03.07.2017, 18:20
Добрый день, необходимо написать программу для запуска подогревом, дизель генератором (ДГУ) и вентиляцией в зависимости от напряжения АКБ и температуры, большая проблема с счетчиками, не могу понять как задать цикл, и сброс.

Задача такова, необходимо запускать ДГУ при падении напряжения на аккумуляторе ниже 50В.
В зависимости от внешних условий.
1) Если летом температура с датчика больше 40 градусов, то необходимо включить вентилятор за 5 минут до включения ДГУ.
Выключение ДГУ произвести как напряжение на АКБ превысит 56В.

2) В зимнем режиме.
Перед формированием вкл.ДГУ необходимо вкл.обогрев на определенное время:
- при температуре от -5 до +5, время обогрева 45 минут;
- при температуре от -20 до -5, время обогрева 60 минут;
- при температуре от -30 до -20, время обогрева 75 минут.
После запуска обогрева проверить температуру через 15 минут, если она не увеличилась на 10 градусов (т.е. обогрев не включился), то сигнал обогрева выключить и включить заново, повторить 3 раза, если после 3х раз обогрев не включился, то ДГУ не включать, а сформировать сигнал тревоги.
По окончании подогрева, включить ДГУ пока напряжение на АКБ не превысит 56В, но не более чем на 120 минут.

Большая проблема с таймерами и их сбросом, если летнее условие выполняется я включаю вентиляцию, после завожу таймер на задержку включения для ДГУ, после 5 минут ДГУ включается, при заряде АКБ>56В выключаю вентиляцию и ДГУ, но при повторной просадке напряжения, включается вентиляция и одновременно с ней ДГУ, т.к. таймер не сбросился с прошлого раза.....

Кто чем может, буду рад помощи..

жекон
04.07.2017, 07:02
Ну а сам код то где?

Василий Кашуба
04.07.2017, 10:31
Совершенно верно, где программа? На форуме экстрасенсов и ясновидящих нет.

Dimensy
04.07.2017, 11:28
А что за таймеры используются - TOF, TP, TON?
Просто в библиотеке OSCAT, вроде, были TOF и TP со сбросом

Slait_gul
04.07.2017, 11:57
Вот маленький кусочек, в котором если напряжение на АКБ падает меньше порога, то при температуре выше 40 летом включить вентилятор и через 10 сек, таймером с задержкой включения, запустить Генератор. При заряде АКБ выше порога заряда, отключить. Все выполняется, но при повторном разряде АКБ таймер не запускается, а включается вентилятор и Генератор одновременно т.к. выход таймера не сбрасывается,а находится все время в положении TRUE.

PROGRAM PLC_PRG
VAR
U_in_1_conv: REAL; (*Напряжение канал 1*)
U_porog_AKB: REAL := 50; (*Порог разряда АКБ*)
U_porog_AKB_zrd: REAL := 55.9; (*Порог заряда АКБ*)
Timer_letom: TON; (*Таймер_запуска_ДГУ_летом_через_5_мин_после_венти лятора*)
Start: BOOL;
Temp_1: REAL; (*температура*)
T_porog_1: REAL := 40; (*Порог_температуры_летом_40_градусов*)
U_out_1: BOOL; (*Вкл. Генератора*)
U_out_2: BOOL; (*Вкл. вентилятора*)
END_VAR

Программа:

IF U_in_1_conv <= U_porog_AKB THEN
Start := 1;
END_IF

IF Start = 1 AND Temp_1 >= T_porog_1 THEN
U_out_2 := 1;
Timer_letom(IN:=U_out_2 , PT:=T#10s , Q=> , ET=> );
U_out_1 := Timer_letom.Q;
ELSE
U_out_2 := 0;
U_out_1 := 0;
END_IF

IF U_in_1_conv >= U_porog_AKB_zrd THEN
Start := 0;
END_IF

Василий Кашуба
04.07.2017, 13:51
Сделайте так.

IF U_in_1_conv >= U_porog_AKB_zrd THEN
Start := 0;
U_out_2 := 0;
END_IF

capzap
04.07.2017, 14:17
Сделайте так.

IF U_in_1_conv >= U_porog_AKB_zrd THEN
Start := 0;
U_out_2 := 0;
END_IF

ну и зачем? Разве не разглядели, что
U_out_2 := 1;
Timer_letom(IN:=U_out_2 , PT:=T#10s , Q=> , ET=> );в любом случае небудет сброса таймера и включение чего то с задержкой

Slait_gul
04.07.2017, 14:17
U_out_2 переходит в False , эту проблему решил, путем выноски таймера за цикл

IF U_in_1_conv <= U_porog_AKB THEN
Start := 1;
END_IF

Timer_letom(IN:=U_out_2 , PT:=T#10s , Q=> , ET=> );

IF Start = 1 AND Temp_1 >= T_porog_1 THEN
U_out_2 := 1;
U_out_1 := Timer_letom.Q;
ELSE
U_out_2 := 0;
U_out_1 := 0;
END_IF

IF U_in_1_conv >= U_porog_AKB_zrd THEN
Start := 0;
END_IF

capzap
04.07.2017, 14:28
U_out_2 := Start = 1 AND Temp_1 >= T_porog_1
Timer_letom(IN:=U_out_2 , PT:=T#10s , Q=> U_out_1 );
должно быть достаточно такого кода

Slait_gul
04.07.2017, 14:32
Есть другой вопрос, как реализовать проверку работы вентилятора в течении часа, в момент подачи сигнала на вентилятор запомнить значение температуры, и после 15 минут снять новое значени и сравнить с прошлым, понизилась ли она на 10 градусов или нет, если да, то все хорошо,а если нет, то сформировать сигнал выключения и включения заново, если после трех раз он не включился, то выдать сигнал тревоги на какой либо датчик.....

Slait_gul
04.07.2017, 14:40
U_out_2 := Start = 1 AND Temp_1 >= T_porog_1
Timer_letom(IN:=U_out_2 , PT:=T#10s , Q=> U_out_1 );
должно быть достаточно такого кода

Его достаточно будет, если одно условие, я так понимаю, но мне надо включить еще условия при различных температурах с включением подогрева и контролем температуры.(

жекон
05.07.2017, 04:24
Я обычно собираю все условия в одну переменную, а уже её управляю таймером, счетчиком и т.д

Uniqum
07.07.2017, 20:44
Доброго дня, сделайте массив для записи. В ячейку записываете температуру по запуску вентилятора, далее таймер работы вентилятора и т.д.

Slait_gul
11.07.2017, 14:10
Набросал такой алгоритм, работа получается, только вот, если температура в пороге от -5 до 5 градусов включается (режим 2) обогрев и Вебасто, но в течении режима работы 2 происходит увеличение температуры, и цикл не дорабатывает до конца, а сразу переходит в режим работы 1, где при температуре выше +5 градусов сразу запускается дизель....

код:

VAR
Start: BOOL;
U_in_1_conv: REAL; (*напряжение канал_1*)
U_in_2_conv: REAL; (*напряжение канал_2*)

Timer_letom: TON; (*таймер запуска ДГУ летом через 5 минут после вентиляции*)
Timer_TP23: TP;
Obog: BOOL;
Indikator0: BOOL;
Indikator1: BOOL;
Indikator2: BOOL;
Timer_viklDGU: TOF;
Timer_Webasto: TON;
Timer_raboti_Webasto: TP;
Timer_zad_vkl_DGU: TOF;
F_TRIG1: F_TRIG;
Timer_DGU: TP;
END_VAR
VAR RETAIN
END_VAR
VAR CONSTANT RETAIN
T_porog_1: REAL := 40; (*порог температуры летом 40 градусов*)
T_porog_2: REAL := +5; (*порог температуры_+5*)
T_porog_3: REAL := -5; (*порог температуры_-5*)
T_porog_4: REAL := -20; (*порог температуры_-20*)
T_porog_5: REAL := -30; (*порог температуры_-30*)
U_porog_AKB: REAL := 50; (*порог разряда АКБ*)
U_porog_AKB_zrd: REAL := 55.9; (*порог заряда АКБ*)
U_porog_AKB_start: REAL := 12 ; (*порог напряжения АКБ стартового*)
END_VAR

PLC_PRG

U_in_1_conv := DWORD_TO_REAL(U_in_11)*4.768372E-006; (*напряжение канал_1*)
U_in_2_conv := DWORD_TO_REAL(U_in_2)*4.768372E-006; (*напряжение канал_2*)

IF U_in_1_conv <= U_porog_AKB THEN
Start := 1; (*старт программы*)
END_IF

Timer_letom(IN:=U_out_2 , PT:=T#5m , Q=> , ET=> ); (*таймер на вкл.дгу после вентиляции*)
Timer_TP23(IN:=Obog , PT:=T#45m , Q=> , ET=> ); (*таймер работы подогрева картера*)
Timer_Webasto(IN:=U_out_3 , PT:=T#15s , Q=> , ET=> ); (*таймер задержки включения обогрева webasto*)
Timer_raboti_Webasto(IN:=Timer_Webasto.Q , PT:=T#43m45s , Q=> , ET=> ); (*таймер работы обогрева*)
Timer_zad_vkl_DGU(IN:=U_out_3 , PT:=T#10s , Q=> , ET=> ); (*таймер задержки вкл.ДГУ после обогрева через 10 сек*)
F_TRIG1(CLK:=Timer_zad_vkl_DGU.Q , Q=> ); (*триггер активации таймера работы дгу*)
Timer_DGU(IN:=F_TRIG1.Q , PT:=T#120m , Q=> , ET=> ); (*таймер работы ДГУ*)

(*Если старт программы и температура от 5 до 40 то запустить ДГУ*)
IF Start = 1 AND Temp_1 >= T_porog_2 AND Temp_1 <= T_porog_1 THEN (*режим_0*)
Indikator0 := 1;
U_out_1 := 1;
U_out_3 := 0;
U_out_4 := 0;
Obog := 0;
(*если старт программы и температура больше 40 то включить вентиляцию и ДГУ*)
ELSIF Start = 1 AND Temp_1 >= T_porog_1 THEN (*режим_1*)
Indikator1 := 1;
U_out_2 := 1;
U_out_1 := Timer_letom.Q;
(*Если старт программы и температура от -5 до +5 то включить подогрев картера, обогрев и ДГУ*)
ELSIF Start = 1 AND Temp_1 > T_porog_3 AND Temp_1 < T_porog_2 THEN (*режим_2*)
Indikator2 := 1;
Obog := 1;
U_out_3 := Timer_TP23.Q;
U_out_4 := Timer_raboti_Webasto.Q;
U_out_1 := Timer_DGU.Q;
ELSE
Obog := 0;
Indikator0 := 0;
Indikator1 := 0;
Indikator2 := 0;
U_out_1 := 0;
U_out_2 := 0;
U_out_3 := 0;
U_out_4 := 0;
END_IF
(*если АКБ зарядился то выключить все*)
IF U_in_1_conv >= U_porog_AKB_zrd(* OR F = 0*) THEN
Start := 0;
(* U_out_2 := 0; Rele_2 := 0;
U_out_1 := 0; Rele_1 := 0;
U_out_3 := 0;*)
END_IF

Необходимо чтобы если запускался какой либо из режимов и начале работы программы, то дорабатывал до конца. Я новичок в этом деле, может необходимо пользоваться системными событиями и как можно это реализовать? желательно с примером...

задача такова, как только напряжение на аккумуляторе падает ниже 50В то активируется программа:
0 режим: если температура больше 40 градусов, то включается вентиляция и через 5 минут включается Дизель-генератор, и отрабатывает пока АКБ не зарядится до 55.9 В, но не более 120 минут.
1 режим: если температура от +5 до 40 градусов, то сразу включается Дизель-генератор и отрабатывает пока АКБ не зарядится до 55.9 В, но не более 120 минут.
2 режим: если температура от -5 до +5 градусов, то включается подогрев картера, через 15 секунд включается обогреватель на 45 минут, после выключаются и через 10 сек, после выключения обогревателя и подогрева картера запускается дизель-генератор и отрабатывает пока АКБ не зарядится до 55.9 В, но не более 120 минут.

К этому необходимо проконтролировать запуск обогрева (после того как запускается второй режим, где температура -5 - +5, запоминаем температуру, после 10 минут работы обогрева нужно сравнить реальную и зафиксированную температуру, если она поднялась на 10 градусов, то продолжить отработку режима до конца, если не поднялась, то провести запуск режима еще раз с самого начала, при 3х неудачных попытках выдать сигнал тревоги)

capzap
11.07.2017, 14:15
Необходимо чтобы если запускался какой либо из режимов и начале работы программы, то дорабатывал до конца.
не используйте IF-ы, а перейдите на CASE

и кто Вам предложил использовать такую запись VAR CONSTANT RETAIN

Slait_gul
11.07.2017, 15:36
не используйте IF-ы, а перейдите на CASE

и кто Вам предложил использовать такую запись VAR CONSTANT RETAIN

энергонезависимые константы чем-то отличаются от просто энергонезависимых переменных?

не могли бы вы проиллюстрировать (хоть словами) как можно заменить на case?

capzap
11.07.2017, 15:48
энергонезависимые константы чем-то отличаются от просто энергонезависимых переменных?
Вы не там ищите разницу, константа и без энергонезависимости при включении останется с таким же значением, а сохранение при пропадании питания нужно только изменяемым переменным

по поводу кейсов, в теле условия наступления старта, присвойте переменной номер режима, далее откройте кейс с этой переменной и пропишите все действия необходимые для данного режима

Slait_gul
11.07.2017, 15:54
по поводу кейсов, в теле условия наступления старта, присвойте переменной номер режима, далее откройте кейс с этой переменной и пропишите все действия необходимые для данного режима

так если я через иф присваиваю номер режима, запускаю кейс, то при повышении температуры изменится номер режима, и кейс прекратит свою работу

capzap
11.07.2017, 15:56
фронт события, так будет понятно когда задавать режимы

Slait_gul
11.07.2017, 16:05
фронт события, так будет понятно когда задавать режимы

понял, попробую, спасибо) а по поводу контроля проверки, запустился или нет, как можно реализовать?

ferret_maybe
11.07.2017, 16:12
понял, попробую, спасибо) а по поводу контроля проверки, запустился или нет, как можно реализовать?
А кто запустился обогрев или ДГУ? Если ДГУ запустился, то должно быть напряжение на выходе - использовать реле контроля напряжения или реле контроля фаз.

capzap
11.07.2017, 16:17
понял, попробую, спасибо) а по поводу контроля проверки, запустился или нет, как можно реализовать?

да все так же по фронту старта, если режим такой то, то запоминаем реальное значение, а в соответствующем кейсе сравниваем запомненное с текущим

Slait_gul
11.07.2017, 16:32
А кто запустился обогрев или ДГУ? Если ДГУ запустился, то должно быть напряжение на выходе - использовать реле контроля напряжения или реле контроля фаз.

проверка запустился ли обогрев, при запуске запоминаем температуру, и сравниваем ее с температурой через 10 минут, если она поднялась на сколько то градусов, значит обогрев работает, не знаю как сделать, если обогрев не запустился как повторить попытку и так 3 раза

ferret_maybe
12.07.2017, 08:59
проверка запустился ли обогрев, при запуске запоминаем температуру, и сравниваем ее с температурой через 10 минут, если она поднялась на сколько то градусов, значит обогрев работает, не знаю как сделать, если обогрев не запустился как повторить попытку и так 3 раза
Посмотри во вложении сделал функциональный блок, но не знаю для твоих условий сможет ли подойти. Кстати нужно протестировать)))

Slait_gul
12.07.2017, 11:20
Посмотри во вложении сделал функциональный блок, но не знаю для твоих условий сможет ли подойти. Кстати нужно протестировать)))

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

Я пока не особо понимаю работу с конфигурацией задач и конфигурацией тревог, обязательно ли их использовать и зачем, какие плюсы, и принципы....

ferret_maybe
12.07.2017, 12:27
Функциональный блок реализован в формате конечного автомата с 4 состояниями.
CASE State OF
0: (*Начальное состояние*)
//Условия перехода в другие состояния в формате. Количество переходов из состояния 0 в число состояний автомата N
IF условие 1 THEN State:= 1; END_IF;
IF условие 2 THEN State:= 2; END_IF;
...
IF условие N THEN State:= Номер состояния N; END_IF;

// Воздействия в шаге: задание значений переменных (выходных воздействий ФБ), запуск таймеров минимального времени шага, максимального времени шага и т.д.

1:
//Условия перехода в другие состояния в формате. Количество переходов из состояния 1 в число состояний автомата N
IF условие 0 THEN State:= 0; END_IF;
IF условие 2 THEN State:= 2; END_IF;
...
IF условие N THEN State:= Номер состояния N; END_IF;

// Воздействия в шаге: задание значений переменных (выходных воздействий ФБ), запуск таймеров минимального времени шага, максимального времени шага и т.д.


ELSE
STATE:=0; (*так на всякий случай*)
END_CASE;
// здесь вызов таймеров, и других функциональных блоков. Конечно можно и внутри Case делать, если не нужно чтобы он вызывался отдельно от шага (состояния).

На рисунке диаграмма состояний как пример системы
32036
Можно как-то так еще программировать)

Юрий27
15.08.2017, 15:33
32626
Подскажите, что не так написал.

Юрий27
15.08.2017, 15:41
32626
Подскажите, что не так написал.

Понял, выход не тот написал)

Scream
15.08.2017, 16:20
32626
Подскажите, что не так написал.

= TRUE писать не обязательно