FUNCTION_BLOCK fb19
VAR_INPUT
FansSelection : INT; // HMI Fans Selections
Update_Bt : BOOL := FALSE; // HMI Update button
FTP_Start : BOOL;
FTP_Stop : BOOL;
END_VAR
VAR_OUTPUT
Fan1_start : BOOL;
Fan2_start : BOOL;
Fan3_start : BOOL;
END_VAR
VAR_TEMP
index : INT;
target_fan_to_run : INT;
Update_Button :BOOL ;
END_VAR
CONST
ST_IDLE := 0;
ST_WAIT := 1;
ST_TURN_ON_TARGET_FAN := 2;
ST_NORAML_OP_2FANS := 3;
ST_NORAML_OP_3FANS := 4;
ST_TURN_OFF_UNWANTED_FAN := 5;
END_CONST
VAR
Fan_Lookuptable : ARRAY[0..3, 0..2] OF INT :=
1, 2, 0,
2, 3, 0,
3, 1, 0,
1, 2, 3;
Index_Selection : ARRAY[0..8] OF INT:= -1, 0, 1, -1, 2, -1, -1, -1, 3;
Fan_Run : ARRAY[0..2] OF BOOL := 0, 0, 0;
old_running : ARRAY[0..2] OF INT := 0, 0, 0;
already_started : BOOL;
Update_Button_old : BOOL;
updated : BOOL := FALSE ;
No_TargetFans : INT;
unused_fan : INT;
State : INT; // FSM current state
TON_timer : sfb4;
Running_fan : INT := 0;
END_VAR
BEGIN
IF FansSelection < 1 THEN
FansSelection := 1;
END_IF;
//index := REAL_TO_INT(LN(FansSelection) / LN(2.0));
index := Index_Selection[FansSelection];
Update_Button:= Update_Bt AND NOT Update_Button_old;
Update_Button_old:=Update_Bt;
CASE State OF
// ----------------------
ST_IDLE :
// ----------------------
No_TargetFans := 2 + BOOL_TO_INT(FansSelection=8);
Fan1_start := FALSE;
Fan2_start := FALSE;
Fan3_start := FALSE;
already_started := FALSE;
updated:= FALSE;
Running_fan := 0 ;
// Reset timer
TON_timer(IN := 0);
IF FTP_Start THEN
State := ST_WAIT;
END_IF;
// ----------------------
ST_WAIT :
// ----------------------
IF NOT TON_timer.Q THEN
TON_timer(IN := 1, PT:= T#5s);
END_IF;
IF TON_timer.Q THEN
State := ST_TURN_ON_TARGET_FAN;
END_IF;
// ----------------------
ST_TURN_ON_TARGET_FAN :
// ----------------------
IF NOT already_started THEN
target_fan_to_run := Fan_Lookuptable[index,Running_fan];
ELSE
target_fan_to_run := 6 - (old_running[0] + old_running[1]);
END_IF;
Fan_Run[target_fan_to_run - 1] := TRUE;
old_running[Running_fan] := target_fan_to_run;
Running_fan := Running_fan + 1;
// Reset timer
TON_timer(IN := 0);
IF Running_fan < No_TargetFans THEN
State := ST_WAIT;
ELSE
already_started := TRUE;
State := ST_NORAML_OP_2FANS + BOOL_TO_INT(Running_fan = 3);
END_IF;
// ----------------------
ST_NORAML_OP_2FANS :
// ----------------------
IF NOT updated THEN
old_running[0] := Fan_Lookuptable[index,0];
old_running[1] := Fan_Lookuptable[index,1];
updated := TRUE;
END_IF;
IF Update_Button THEN
IF FansSelection = 8 THEN
No_TargetFans := 3;
State := ST_TURN_ON_TARGET_FAN;
ELSE
State := ST_TURN_OFF_UNWANTED_FAN;
END_IF;
updated := False;
END_IF;
IF FTP_Stop THEN
State := ST_IDLE;
END_IF ;
// ----------------------
ST_NORAML_OP_3FANS :
// ----------------------
No_TargetFans := 3;
IF Update_Button AND (FansSelection <> 8) THEN
No_TargetFans := 2;
State := ST_TURN_OFF_UNWANTED_FAN;
END_IF;
IF FTP_Stop THEN
State := ST_IDLE;
END_IF ;
// ----------------------
ST_TURN_OFF_UNWANTED_FAN :
// ----------------------
unused_fan := 6 - (Fan_Lookuptable[index,0] + Fan_Lookuptable[index,1] + Fan_Lookuptable[index,2]);
Fan_Run[unused_fan - 1] := FALSE;
Running_fan := Running_fan - 1;
IF Running_fan = 2 THEN
State := ST_NORAML_OP_2FANS;
ELSE
State := ST_WAIT;
END_IF;
END_CASE;
// Update_Button := FALSE ;
Fan1_start := Fan_Run[0];
Fan2_start := Fan_Run[1];
Fan3_start := Fan_Run[2];
END_FUNCTION_BLOCK