Yes, I know it's an old thread; close it now if that is your policy, no harm no foul.
But AFAICT the OP's fundamental understanding was never addressed. Yes, OP is almost certainly long gone, but others might find this thread and have a similar question.
Is there no other way of doing a simple delay? In other languages there is a simple function called "waittime, delay, wait..." etc. I've tried with %S6 also
I need a timer here. I can't understand how it works.
IF not PB_1 and not PB_2
THEN
DIOD_1:=1
DIOD_2:=0;
ELSEIF PB_1 OR PB_2
THEN
*DELAY 2 sec* (* <=== PLCs do not work like C! *)
DIOD_1:=0
DIOD_2:=1;
END_IF;
This would be super easy in another programming language. It's just the timer making it difficult...
"Toto, I've a feeling we're not in Kansas anymore."
It's not the programming language, it is the
environment that is "other;" once the environment is understood, it becomes easy again. Trying to write PLC code based on C code experience is akin to treating the Land of Oz like Kansas.
In a PLC environment, the PLC code written by the programmer is executed in a loop, and that loop executes repeatedly as long as the PLC is in RUN mode. Each pass through that loop is called a scan cycle and executes
ALL of the PLC code
on each pass. Each pass must complete within a certain "watchdog" timeout period, or else the PLC Executive, which is "outside" of and runs the scan cycle, will detect a watchdog timeout and halt the PLC.
So the code cannot be designed as if it were to be executed in a linear fashion; specifically, PLC code
cannot have a long delay in the code where execution stops during a single scan cycle, or else the PLC Executive process will trigger a watchdog timeout and halt the PLC.
An over-simplified model of a PLC would look like the following. Everything in
red is part of the PLC Executive process and executes unconditionally and independently of any PLC code the programmer writes.
while (IN_RUN_MODE) // The Executive starts the scan cycle
{ // C-style shownread_inputs()l // The Executive copies physical input states into local memory buffer
(* Start programmer's ST code *)
VAR
ton_2s : TON;
END_VAR;
IF not PB_1 and not PB_2
AND NOT button_was_pressed
THEN
DIOD_1:=1
DIOD_2:=0;
ELSEIF (PB_1 OR PB_2)
AND NOT button_was_pressed
THEN
*DELAY 2 sec*
button_was_pressed := 1;
ELSEIF expiry_2s_timer
THENDIOD_1:=0
DIOD_2:=1;
END_IF;
(* The TON timer is a time accumulator that runs *)
(* on every scan cycle. As long as its input .IN *)
(* Boolean assignment evaluates to True, the time *)
(* accumulation, .CV, increases by the amount of *)
(* time since the previous TON's call. Once the *)
(* time accumulation reaches the Preset Time .PT, *)
(* i.e. once the timer expires, the .OUT Boolean *)
(* becomes 1. When the .IN assignment evaluates *)
(* to False, then the .CV accumulation value is *)
(* reset to 0, and the .OUT Boolean is reset to 0 *)
(* N.B. those resets happen whether the timer had *)
(* expired or not. *)
ton_2s(IN:=button_was_pressed
,PT:=T#2s
,OUT=>expiry_2s_timer
);
(* End programmer's ST code *)
write_outputs(); // The Executive writes buffered output values in memory to physical outputs
} // Executive ends this pass of the "while" loop
Caveat: that code is incomplete: there should be some condition that resets the value of
button_was_pressed back to 0.