We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you've provided to them or that they've collected from your use of their services.

Complex example - Blinds

Setting and hardware

In one of the rooms there are windows on the Southern and Western walls.  They can be covered with blinds (Blind 1 controlled through OUT1 and OUT2, Blind 2 controlled through OUT3 and OUT4).  On the Western wall there is a 2-button bell-switch (Buttons 1 and 2 connected to IN1 and IN2).  On the opposite, Eastern wall there is also a 2-button bell-switch (Buttons 11 and 12 connected to IN11 and IN22).

There is also a light sensor using 24VDC powered through OUT10 and if light intensity exceeds the given level, returning a signal to IN10.

Functionality

The switch on the Western wall (near one of the windows) is used to 'traditionally' control the blinds.  A short press on a button (1) triggers a movement up of a blind.  Another short click during a movement stops it.  A long press triggers a downward movement. 

The button on the opposite wall near the door is used to control the lights.  Additionally a long press of the button 11 moves both blinds down to a preset position.  A long press of button 22 moves both blinds up.

The possibility of moving the blinds to a 'preset position' is worth considering because it enables a quick:

- moving blind to (for example) the middle of the windows to make same shade on a sunny day,

- moving blinds to an 'almost closed' position, i.e. when the bits are not tightly closed but there are spaces between them letting some light in.  We use it when the kids have a mid-day nap.

With the use of buttons 11 and 22 I have the possibility to - depending on the time of the year and the configured 'preset position' - to set 'scenes' or to open both blinds instantly without the need of even entering the room too far.  

Additionally there is a possibility of moving the blinds up or down according to sun rise/set.  Usually in the winter period the blinds move down at the sunset and move up at 07:00.

Moreover the blinds move automatically to a 'shade' position if during summer the sun is in a given position, the light senor detect intense light and the temperature in the room is higher the preset maximum.

The code in variable definitions:

VAR
	Shade_TemperatureTOF : TOF:=(PT:=T#1h);
	Shade_Flag : BOOL;
	Shade_Enabled, WINTER : BOOL; 

	SunSignal : BOOL;
	SunRise : F_TRIG;
	SunSet : F_TRIG;

	Blind_Room1_S_1, Blind_Room1_S_2: FbScheduleWeekly;
	Blind_R1_Timer_On : R_TRIG;
	Blind_R1_Timer_Off : F_TRIG;

	SWITCH_IN1, SWITCH_IN2 : Fb_ShortLong:=(uiTS_10tel_s:=1, uiTL_10tel_s:=1, uiT_10tel_s:=5);
	SWITCH_IN11, SWITCH_IN22 : Fb_ShortLong:=(uiTS_10tel_s:=1, uiTL_10tel_s:=1, uiT_10tel_s:=10);

	BLIND_ROOM1_UP, BLIND_ROOM1_DOWN : BOOL;
END_VAR

VAR RETAIN PERSISTENT
	Shade_MinTemp: BYTE:=21;
	Blind_R1_Data1, Blind_R1_Data2: typScheduleWeekly;

	Blind_Room1_1_Input : BLIND_INPUT:=(PI:=150, MAX_RUNTIME:=T#25s,

	MANUAL_TIMEOUT:=t#60m, MASTER_MODE:=TRUE); 
	Blind_Room1_1_Shade : BLIND_SHADE_S:=(HORZ1:=100, HORZ2:=215, SHADE_POS:=150, SHADE_DELAY:=T#5m);
	Blind_Room1_1_Control : BLIND_CONTROL_S:=(T_UP:=T#23s, T_DN:=T#22s);

	Blind_Room1_2_Input :BLIND_INPUT:=(PI:=150, MAX_RUNTIME:=T#25s, MANUAL_TIMEOUT:=t#60m, MASTER_MODE:=TRUE);
	Blind_Room1_2_Shade : BLIND_SHADE_S:=(HORZ1:=160, HORZ2:=280, SHADE_POS:=150, SHADE_DELAY:=T#5m);
	Blind_Room1_2_Control : BLIND_CONTROL_S:=(T_UP:=T#23s, T_DN:=T#22s);
END_VAR

Where:

  • Shade_TemperatureTOF - is a timer to signal if the temperature in the room is above the preset maximum.  The use of TOF instead of a regular BOOL variable handles the moments when the temperature oscillates at the preset threshold, what would cause a repetetive switching on- and off of the shading system,
  • Shade_Flag - used to turn on the BLIND_SHADE_S function blocks,
  • Shade_Enabled, WINTER - BOOL variables used to control the system from the visualization,
  • Sunsignal - a variable carrying the sun-sensor signal,
  • Sunrise, Sunset - triggers signaling sun rise and sunset. 
  • Blind_Room1_S_X - Schedulers form WAGO libraries enabling to set a weekly timetable.  There are 2 to set separate programs for working days and weekends,
  • Blind_R1_Timer_X - triggers signaling the schedulers going on and off,
  • SWITCH_INXX - functions blocks sensing long/short button presses.  Watch out for the difference in the time of long-press detection.
  • BLIND_ROOM1_UP, BLIND_ROOM1_DOWN - variables adding up conditions of moving blinds up or down,
  • Shade_MinTemp - stores the temperature threshold
  • Blind_R1_DataX - variables storing the settings of the schedulers,
  • Blind_Room1_X_XXX - function blocks from the  OSCAT Building library used to control blinds;  details can be found in a separate article.

 

The code in the program:

(*Temerature test and Sunlight sensor*)
Shade_TemperatureTOF(IN:=SensorReader.TEMPERATURE_ROOM1/10>Shade_MinTemp);
Shade_Flag:=Shade_Enabled AND Shade_TemperatureTOF.Q AND NOT WINTER;
OUT10:=Shade_Flag;
SunSignal:=IN10;

(*Sunrise and Sunset definition*)
SunRise(CLK:=ReadClock.Calendar.SUN_VER<ReadClock.SunRise_Angle);
SunSet(CLK:=ReadClock.Calendar.SUN_VER>ReadClock.SunSet_Angle);

(*Schedulers*)
Blind_Room1_S_1(xEnable:=TRUE, dtActualTime:=CURRENT_TIME, typScheduleWeekly:=Blind_R1_Data1);
Blind_Room1_S_2(xEnable:=TRUE, dtActualTime:=CURRENT_TIME, typScheduleWeekly:=Blind_R1_Data2);

(*Triggers for Schedulers*)
Blind_R1_Timer_On (CLK:=Blind_Rom1_S_1.xSwitchChannel OR Blind_Room1_S_2.xSwitchChannel);
Blind_R1_Timer_Off(CLK:=Blind_Room1_S_1.xSwitchChannel OR Blind_Room1_S_2.xSwitchChannel);

(*Short/Long Swittches*)
SWITCH_IN1(xSwitch:=IN1);
SWITCH_IN2(xSwitch:=IN2);
SWITCH_IN11(xSwitch:=IN11);
SWITCH_IN22(xSwitch:=IN22);

(*Handling of Schedulers and central switches*)
BLIND_ROOM1_UP:=SWITCH_IN22.xLong OR Blind_R1_Timer_On.Q AND  VIS_Management.LightButtons[0,0])
	OR SunRise.Q AND VIS_Management.LightButtons[0,1]);
BLIND_S_DOWN:=(Blind_R1_Timer_Off.Q AND VIS_Management.LightButtons[1,0]) OR SunSet.Q AND VIS_Management.LightButtons[1,1]);

(*Blind in Room1 from the South*)
Blind_Room1_1_Input(
	S1:=SWITCH_IN1.xShort OR VIS_B_R1_1_UP OR BLIND_ROOM1_UP,
	S2:=SWITCH_IN1.xLong OR VIS_B_R1_1_DOWN OR BLIND_ROOM1_DOWN,
	IN:=SWITCH_IN11.xLong OR VIS_B_R1_1_POS,
	POS:=Blind_Room1_1_Control.POS
	);
Blind_Room1_1_Shade(
	UP:=Blind_Room1_1_Input.QU, DN:=Blind_Room1_1_Input.QD,
	S_IN:=Blind_Room1_1_Input.STATUS, pi:=Blind_Room1_1_Input.PO,
	ENABLE:=Shade_Flag, SUN:=SunSignal, CX:=ReadClock.Calendar
	);
Blind_Room1_1_Control(
	UP:=Blind_Room1_1_Shade.QU, DN:=Blind_Room1_1_Shade.QD,
	S_IN:=Blind_Room1_1_Shade.STATUS, pi:=Blind_Room1_1_Shade.PO
	);
  
OUT1:=Blind_Room1_1_Control.MU;
OUT2:=Blind_Room1_1_Control.MD;

(*Blind in Room1 from the West*)
Blind_Room1_2_Input(
	S1:=SWITCH_IN2.xShort OR VIS_B_R1_2_UP OR BLIND_ROOM1_UP,
	S2:=SWITCH_IN2.xLong OR VIS_B_R1_2_DOWN OR BLIND_ROOM1_DOWN,
	IN:=SWITCH_IN11.xLong OR VIS_B_R1_2_POS,
	POS:=Blind_Room1_2_Control.POS
	);
Blind_Room1_2_Shade(
	UP:=Blind_Room1_2_Input.QU, DN:=Blind_Room1_2_Input.QD,
	S_IN:=Blind_Room1_2_Input.STATUS, pi:=Blind_Room1_2_Input.PO,
	ENABLE:=Shade_Flag, SUN:=SunSignal, CX:=ReadClock.Calendar
	);
Blind_Room1_2_Control(
	UP:=Blind_Room1_2_Shade.QU, DN:=Blind_Room1_2_Shade.QD,
	S_IN:=Blind_Room1_2_Shade.STATUS, pi:=Blind_Room1_2_Shade.PO
	);
	
OUT3:=Blind_Room1_2_Control.MU;
OUT4:=Blind_Room1_2_Control.MD;

Where:

  • Row 2 - Shade_TemepratureTOF uses the value of variables set by the readings of analog inputs (executed in a separate process - SensorReader),
  • Row 3 - Shade_Flag adds up: the main on/off switch of the shading system (Shade_Enabled), the crossing of temperature threshold and no-winter,
  • Rows 4 and 5 - at Shade_Flag = TRUE the light sensor is turned on and its readings are written to the variable SunSignal,
  • Rows 8 and 9 - SunRise i SunSet use variables from a separate process (ReadClock): a variable Calendar type CALENDAR from OSCAT library and variables SunRise_Angle and SunSet_Angle type SINT storing threshort above/below which the sunrise/sunset is signaled. Those thresholds are set through a visualization,
  • Rows 12 and 13 - Schedulers use a global variable CURRENT_TIME type DATE_AND_TIME updated every second in the process  ReadClock(),
  • Rows 16 and 17 - triggers adding up the signals from the schedulers,
  • Row 26 - variable adding up the long-press of button 22 and the signals from the scheduler (under the condition that VIS_Management in an array LightButtons at position [0,0] is TRUE) and a trigger signalling sunrise and sunset (under the condition that VIS_Management.LightButtons[1,0] = TRUE),
  • Row 28 - as above but the button moving all blinds down is excluded.  Instead a long-press of the button 11 moves the blinds to a preset position; to be found in Rows 42 and 58,
  • All variables starting from VIS_B_Rxxxx are type BOOL and are used through visualizations.

 

Example of visualizations:

Blinds1

Blinds2

Blinds3