FUNCTION_BLOCK GEN_SIN
TITLE = 'GEN_SIN'
//
//this signal generator generates a sine wave output. The sine wave signal is defined by period time (PT),
//amplitude (AM), offset (OS) and a specific delay for the output signal (DL).
//The Output waveform will have its max peak at AM/2 + OS and its minimum peak at -AM/2 + OS.
//The delay input can delay a signal up to PT, this can be useful to synchronize different generators
//and generate interleaving signals. A Cos wave can be generated accordingly.
//in addition to a analog output Out there is a second boolean output Q with the corresponding binary signal.
//
//uses: T_PLC_MS [FC64]
// STIME [FB64],IDB_STIME [DB64]
// MODR [FC97]
// FLOOR2 [FC82]
// MULTIME [FC203]
// SIGN_R [FC109]
//
VERSION : '1.6'
AUTHOR : oscat
NAME : GEN_SIN
FAMILY : SIGGEN
VAR_INPUT
PT : TIME;
AM : REAL := 1.0;
OS : REAL;
DL : REAL;
END_VAR
VAR_OUTPUT
Q : BOOL;
OUT : REAL;
END_VAR
CONST
PI2 := 6.28318530717958647692528676655900576; (* PI * 2 *)
END_CONST
VAR
tx : TIME;
last : TIME;
init : BOOL;
temp : REAL;
END_VAR
BEGIN
(* read system time and prepare input data *)
tx := DINT_TO_TIME(DWORD_TO_DINT(T_PLC_MS())) - last;
DL := modR(in:=dl,divi:=1.0);
IF dl < 0.0 THEN dl := 1.0 - dl; END_IF;
(* init section *)
IF NOT init THEN
init := TRUE;
last := tx;
tx := t#0s;
END_IF;
(* add last if one cycle is finished *)
IF tx >= pt THEN
last := last + pt;
tx := tx - pt;
END_IF;
(* generate sine wave *)
IF pt > t#0s THEN temp := SIN(PI2 * DINT_TO_REAL(TIME_TO_DINT(tx + multime(t:=pt,M:=dl))) / DINT_TO_REAL(TIME_TO_DINT(pt))); END_IF;
out := am * 0.5 * temp + os;
(* boolean output Q *)
q := NOT sign_R(temp);
(* revision history
hm 22. jan 2007 rev 1.0
original version
hm 17 sep 2007 rev 1.1
replaced time() with t_plc_ms for compatibilitx reasons
hm 27. nov 2007 rev 1.2
avoid divide by 0 when pt = 0
hm 6. jan 2008 rev 1.3
improved performance
hm 16. mar. 2008 rev 1.4
added type conversion to avoid warnings under codesys 3.0
hm 18. oct. 2008 rev 1.5
using math constants
hm 11. mar. 2009 rev 1.6
changed real constants to use dot syntax
*)
END_FUNCTION_BLOCK