PDA

Просмотр полной версии : Моя первая программа. Критикуйте



tolik777
25.08.2009, 17:34
Начал изучать контроллеры ОВЕН и среду Codesys.
Моя первая задача такая: есть простейшая схема - кнопка и лампочка. Кнопка без фиксации НО, подключена к DI1. Лампочка через реле подключена к DO1.
Кнопку нажал - лампочка загорелась, второй раз нажал - потухла ну и т.д.
Вот такую программу написал на ST:


PROGRAM PLC_PRG
VAR
RTRIGInst: R_TRIG;
STATUS_BTN1: BOOL;
END_VAR

IF BTN1 = TRUE THEN (*Если нажали кнопку 1*)
RTRIGInst(CLK:= BTN1); (*Вызываем функцию генератора одиночного импульса по переднему фронту*)
IF RTRIGInst.Q = TRUE THEN
IF STATUS_BTN1 = TRUE THEN STATUS_BTN1 := FALSE; (*Если статус первого прожектора был "вкл", то отключаем*)
ELSE STATUS_BTN1 := TRUE; (*Иначе - включаем*)
END_IF
END_IF
ELSE RTRIGInst(CLK:= BTN1); (*Вызываем функцию генератора одиночного импульса по переднему фронту, чтобы сбросить в след. цикле*)
END_IF


IF STATUS_BTN1 = TRUE THEN RELAY1 := TRUE; (*Если статус первого прожектора "вкл", то включаем реле 1*)
ELSE RELAY1 := FALSE;
END_IF


Вроде работает, но..... может быть можно как-то попроще...
Вообщем жду критики и замечаний.
Спасибо.

Kirill
26.08.2009, 09:12
Начал изучать контроллеры ОВЕН и среду Codesys.
Моя первая задача такая: есть простейшая схема - кнопка и лампочка. Кнопка без фиксации НО, подключена к DI1. Лампочка через реле подключена к DO1.
Кнопку нажал - лампочка загорелась, второй раз нажал - потухла ну и т.д.
Вот такую программу написал на ST:


Вроде работает, но..... может быть можно как-то попроще...
Вообщем жду критики и замечаний.
Спасибо.

Сильно проще уже не сделаете. Но если оформите в виде ФБ, то дальше можно будет использовать, как готовый алгоритм))

Crusash
26.08.2009, 09:45
IF STATUS_BTN1 = TRUE THEN RELAY1 := TRUE; (*Если статус первого прожектора "вкл", то включаем реле 1*)
ELSE RELAY1 := FALSE;
END_IF
вот какой смысл огород городить?
весть код умещается в одну строку

RELAY1 :=STATUS_BTN1;
А вообще я бы весь этот код записал бы в событии OnMouseClik на кнопку,


IF Lampa = TRUE THEN
Lampa :=FALSE;
ELSE
Lampa :=TRUE;
END_IF
Зачем лишний раз цикл рабочий загружать?

Crusash
26.08.2009, 09:56
А вообще я бы весь этот код записал бы в событии OnMouseClik на кнопку,
...

Ой, извиняюсь, задание прочитал не внимательно...

nikita
26.08.2009, 11:24
Front(CLK:=knopka);
IF Front.Q AND NOT lampa THEN
lampa:=TRUE;
ELSIF Front.Q AND lampa THEN
lampa:=FALSE;
END_IF

нажали кнопку - включилась лампа, ещё раз нажали - выключилась и т. д.
проще, кажется, некуда

SergeyNG
26.08.2009, 12:30
Front(CLK:=knopka);
IF Front.Q AND NOT lampa THEN
lampa:=TRUE;
ELSIF Front.Q AND lampa THEN
lampa:=FALSE;
END_IF

нажали кнопку - включилась лампа, ещё раз нажали - выключилась и т. д.
проще, кажется, некуда

Пробуем проще:
Front(CLK:=knopka);
IF Front.Q THEN
lampa := NOT lampa;
END_IF

nikita
26.08.2009, 12:47
Пробуем проще:
Front(CLK:=knopka);
IF Front.Q THEN
lampa := NOT lampa;
END_IF
:eek: :eek: :eek:
действительно, нет предела совершенству

Сергей71
26.08.2009, 12:52
А есть еще библиотека Oscat там много прибомбасов для работы лампочек и кнопок (Диммеры и тп).

SergeyNG
26.08.2009, 13:09
конечно, если использовать спец.фб или написать свой фб, то можно и уложиться в одну строчку. тут важно разобраться, отимальности в чем пытаемся достичь: в компактности текста программы, быстроты отработки кода процессором, объеме кода, понимании текста программы ...

tolik777
26.08.2009, 18:22
Пробуем проще:
Front(CLK:=knopka);
IF Front.Q THEN
lampa := NOT lampa;
END_IF
А Front это какая библиотека?

Малышев Олег
26.08.2009, 20:44
B наконец... свои 5 копеек.
VAR
SR_1:SR;
R_TRIG1:RTRIG;
end_var
R_TRIG1(CLK:=KNOPKA);
SR(SET1:= R_TRIG1.q AND NOT LAMPA,RESET:= R_TRIG1.q AND LAMPA,Q=>lampa);

nikita
27.08.2009, 08:42
А Front это какая библиотека?

Front - это не библиотека, это имя триггера в программе

bango
27.08.2009, 17:32
Привет, просмотрел тему и стало интересно на сколько можно компактней написать эту прогу.

PROGRAM PLC_PRG
VAR
power: BOOL;
stop: BOOL;
tim1: TON;
reset: BOOL;
Favar: BOOL;
END_VAR
-----------------------------
IF avar THEN (*авария*)
IF reset THEN(*опрос кнопки reset*)
avar:=FALSE;
stop:=FALSE;
END_IF
ELSE
out:=(NOT stop AND out)OR power;
(*тригер кнопок пуск стоп*)
IF KQ THEN(*контакт реле*)
;
ELSE
tim1( IN :=out , PT := T#5s);(*счетчик аварии*)
Favar:=tim1.Q;
IF Favar THEN(*флаг аварии*)
stop := TRUE;
avar:=TRUE;
out:=FALSE;
END_IF
END_IF
END_IF;

tolik777
29.08.2009, 19:40
подскажите, что-то никак не могу додуматься как реализовать такое:
при нажатии на кнопку, последовательно (с интервалом в 2 сек) включаются выхода.

bango
30.08.2009, 12:15
выкладываю полную версию там есть визуализация там все должно быть понятно.1521

Николаев Андрей
30.08.2009, 12:45
подскажите, что-то никак не могу додуматься как реализовать такое:
при нажатии на кнопку, последовательно (с интервалом в 2 сек) включаются выхода.

В зависимости от того кнопка с фиксацией или без...
Если с фиксацией - нужен таймер с задержкой включения - TON.
Если без фиксации - тогда в зависимости от языка используем детектор фронтов и фиксацию\сброс.

tolik777
30.08.2009, 13:21
кнопка без фиксации. после нажатия должны включатся выхода к примеру: №1, затем через 2 сек №2, еще через 2 сек №3 и т.д.

magirus
30.08.2009, 13:52
например так.
ПЛК100 r.l.

tolik777
30.08.2009, 18:38
спасибо. работает. правда сделал немного по другому.

tolik777
30.08.2009, 19:18
Вот еще такой вопрос. Промучился весь вечер не могу понять, почему при первом прогоне таймеры работает как надо(выхода переключаются последовательно). А когда второй раз вызываю, то выхода переключаются без задержек.
Фрагмент кода:



IF flag_Step_On THEN
Ti1(IN:=TRUE,PT:=T#1s);
Ti2(IN:=TRUE,PT:=T#2s);
RELAY1:=Ti1.Q;
RELAY2:=Ti2.Q;
END_IF
(*Где Ti1,Ti2 - TON таймеры)

tolik777
31.08.2009, 11:40
А сбрасывать их надо так:
Ti2(IN:=FALSE,PT:=T#2s);

???

tolik777
31.08.2009, 18:21
разобрался спасибо.

tolik777
06.09.2009, 14:38
Приведу фрагмент моего кода:


....
Ti1(IN:=TRUE,PT:=T#1s); (*Запускаем таймер, 1 сек.*)
Ti2(IN:=TRUE,PT:=T#2s);
RELAY1:=Ti1.Q OR RELAY1; (*По окончании переключаем выход*)
RELAY2:=Ti2.Q OR RELAY2 ;
IF Ti2.Q (*Когда закончил считать 2-ой таймер*)
THEN
Ti1(IN:=FALSE,PT:=T#0s); (*Сбрасываем таймер*)
Ti2(IN:=FALSE,PT:=T#0s);
......
END_IF
....

Ключевое слово здесь для сброса таймера: IN:=FALSE

Малышев Олег
07.09.2009, 08:28
Может так? Без if
Ti1(IN:=flag_Step_On ,PT:=T#1s);
Ti2(IN:=flag_Step_On ,PT:=T#2s);
RELAY1:=Ti1.Q;
RELAY2:=Ti2.Q;