dimmer
und hier noch ein code zum anschauen
der code entstammt der freien lib unter
www.oscat.de
FUNCTION_BLOCK dimm_i
VAR_INPUT
set : BOOL;
in : BOOL;
rst : BOOL;
END_VAR
VAR_INPUT CONSTANT
T_debounce : TIME := T#10ms;
T_reconfig : TIME := T#10s;
T_on_max : TIME := T#0h;
T_dimm_start : TIME := T#1s;
T_dimm: TIME := T#3s;
END_VAR
VAR_OUTPUT
Q : BOOL := 0;
out : BYTE := 0;
END_VAR
VAR
tx : TIME := T#0s;
last_edge : BOOL;
state : BYTE := 0;
edge : BOOL := 0;
r_edge : BOOL := 0;
T_on : TIME;
dimm_up: BOOL;
ramp : rmp_B;
last_step : TIME;
END_VAR
(*
version 1.0 4 aug 2006
programmer hugo
tested by tobias
this is an intelligent dimmer interface with an autoset feature for "in" it will automatically detect the type of switch:
low active pulses or high high active pulses are allowd for in.
a configurable debounce timer will debounce input signals
if t_on_max is set to anything other then 0 the output will be turned off after the max on time is reached.
the times for debounce, dimming ramp, wait time before dimming and max on time are all programmable.
the dimmer has outputs Q for on and off and also out with the analog dimm value.
*)
IF rst THEN
state := 0;
Q := 0;
dimm_up := TRUE;
ELSIF set THEN
state := 0;
Q := TRUE;
out := 255;
dimm_up := FALSE;
T_on := TIME();
ELSE
CASE state OF
(* state 0 wait for activity *)
0 : IF (r_edge AND in AND NOT edge) OR (NOT r_edge AND NOT in AND edge) THEN
state := 1;
tx := TIME();
last_edge := in;
END_IF
(* state 1 debouncing *)
1: IF TIME() - T_debounce >= tx THEN
state := 2;
tx := TIME();
END_IF;
(* state 2 wait for second edge to toggle output *)
2: IF TIME() - T_dimm_start >= tx THEN
state := 3;
tx := TIME();
(* time to switch elapsed without switching if Q = 0 turn on output and start dimming at 1 *)
IF NOT Q THEN
Q := TRUE;
t_on := tx;
out := 1;
dimm_up := TRUE;
ELSE
IF out =255 THEN dimm_up := FALSE; END_IF;
END_IF;
ELSIF in XOR edge THEN
(* wait for edge to toggle output and stop all activity *)
IF Q THEN
Q := FALSE;
state := 0;
ELSE
Q := TRUE;
state := 3;
IF out = 0 THEN out := 255; END_IF
IF out = 255 THEN dimm_up := FALSE; END_IF;
tx := TIME();
t_on := tx;
END_IF;
END_IF;
(* state 3 entered dimming phase *)
3: IF in AND r_edge THEN
(* generate ramp *)
tx := TIME();
IF tx >= last_step + T_dimm / 255 THEN
last_step := tx;
IF dimm_up AND out < 255 THEN
out := out + 1;
IF out = 255 THEN
dimm_up := FALSE;
state := 0;
END_IF;
ELSIF NOT dimm_up AND out > 0 THEN
out := out -1;
IF out = 0 THEN
Q := FALSE;
state := 0;
dimm_up := TRUE;
END_IF;
END_IF;
END_IF;
ELSE
dimm_up := NOT dimm_up;
state := 0;
END_IF;
END_CASE;
(* check for max t_on time and reset output if too long *)
IF Q AND t_on_max > T#0s AND TIME() - t_on_max >= T_on THEN Q := 0; END_IF;
(* check for reconfig and set R_edge to high for rising edge sensitivity *)
IF TIME() - T_reconfig >= tx THEN R_edge := NOT in; END_IF;
(* set edge to follow in for next edge detection *)
edge := in;
END_IF;