Autor Thema: BLIND_NIGHT doesn't work  (Gelesen 77 mal)

0 Mitglieder und 1 Gast betrachten dieses Thema.

Offline dawrut

  • Newbie
  • *
  • Beiträge: 5
    • Profil anzeigen
BLIND_NIGHT doesn't work
« am: 08. April 2021, 07:37:45 »
I've problems with BLIND_NIGHT. This function block seems not to be working in my case. I've been connected to the PLC when the sunset comes and nothing happened
My code looks like this:

FUNCTION_BLOCK Blind
VAR_INPUT
   xBlindDown: BOOL;
   xBlindUp: BOOL;
   xAutoSunset: BOOL := FALSE;
   xAutoSunrise: BOOL := FALSE;
   tSunsetOffset: TIME;
   tSunriseOffset: TIME;
END_VAR
VAR_OUTPUT
   xBlindControlUp: BOOL;
   xBlindControlDown: BOOL;
END_VAR
VAR
   BlindInput: OSCAT_BUILDING.BLIND_INPUT := (SINGLE_SWITCH := FALSE, MAX_RUNTIME := T#25S, MANUAL_TIMEOUT := T#60M, MASTER_MODE := TRUE, IN := TRUE);
   BlindControl: OSCAT_BUILDING.BLIND_CONTROL_S := (T_UP:=T#20S, T_DN:=T#18S);
   BlindNight: OSCAT_BUILDING.BLIND_NIGHT;
   BlindSecurity: OSCAT_BUILDING.BLIND_SECURITY;
   
   SunTime: OSCAT_BASIC.SUN_TIME := (LATITUDE := rLatitude, LONGITUDE := rLongitude);
   CurrentDateTimeUTC: DATE_AND_TIME;
   CurrentDateUTC: DATE;   
END_VAR


And here is the code:

CurrentDateTimeUTC := FuGetDateAndTime();
CurrentDateUTC := TO_DATE(CurrentDateTimeUTC);

SunTime(UTC := CurrentDateUTC);

BlindInput(
   POS:= BlindControl.POS,
   S1:= xBlindUp,
   S2:= xBlindDown,
);

//GVL.xInit is a global variable which is set to true after first PLC cycle
//this switch of IN state is required to stop moving of blinds after a power failure of PLC update
IF (GVL.xInit = TRUE) THEN
   BlindInput.IN := FALSE;
END_IF

BlindNight(
   UP := BlindInput.QU,
   DN := BlindInput.QD,
   S_IN := BlindInput.STATUS,
   PI := BlindInput.PO,
   DTIN := CurrentDateTimeUTC,
   SUNRISE := SunTime.SUN_RISE,
   SUNRISE_OFFSET := tSunriseOffset,
   SUNSET := SunTime.SUN_SET,
   SUNSET_OFFSET := tSunsetOffset,
   E_NIGHT := xAutoSunset,
   E_DAY := xAutoSunrise
);

BlindSecurity(
   UP := BlindNight.QU,
   DN := BlindNight.QD,
   S_IN := BlindNight.STATUS,
   PI := BlindNight.PO
);

// in order to stop moving blinds after a power failure or PLC update we need to check if PLC has been initialized
BlindControl(
   UP := BlindSecurity.QU AND GVL.xInit,
   DN := BlindSecurity.QD AND GVL.xInit,
   S_IN := BlindSecurity.STATUS,
   PI := BlindSecurity.PO
);

xBlindControlDown := BlindControl.MD;
xBlindControlUp := BlindControl.MU;


I also had a problem with the fact that after the power failure the blinds are going automatically up - I didn't want that is why I introduced the xInit global variable which is false by default and is set to true after the first PLC cycle. Thanks to this restart of the PLC is not moving the blinds up.
I was testing the whole code with IN := FALSE for BLIND_INPUT but it also didn't help, the BLIND_NIGHT was not working.

Do you see any obvious problems here?

Offline dawrut

  • Newbie
  • *
  • Beiträge: 5
    • Profil anzeigen
Re: BLIND_NIGHT doesn't work
« Antwort #1 am: 12. April 2021, 07:52:34 »
Is there anyone who can share his code with the working BLIND_NIGHT function block?
I'm out of ideas what might be wrong?


Sorry but I don't speak German at all...

Offline mattsches

  • Sr. Member
  • ****
  • Beiträge: 252
    • Profil anzeigen
Re: BLIND_NIGHT doesn't work
« Antwort #2 am: Gestern um 17:33 »
Hi dawrut,

I found some issues with BLIND_NIGHT when I started using it and more or less rewrote its code. Don't remember if your issue was among my findings (more than seven years ago), but if you want, you can try if my version fixes your problem.

Declaration:
FUNCTION_BLOCK BLIND_NIGHT
VAR_INPUT
UP, DN : BOOL;
S_IN : BYTE;
PI, AI : BYTE;
E_NIGHT : BOOL := TRUE;
E_DAY : BOOL := TRUE;
END_VAR
VAR_INPUT CONSTANT
SUNRISE_OFFSET : TIME;
SUNSET_OFFSET : TIME;
NIGHT_POSITION : BYTE;
NIGHT_ANGLE : BYTE;
END_VAR
VAR_IN_OUT
CX : CALENDAR;
END_VAR
VAR_OUTPUT
QU, QD : BOOL;
STATUS : BYTE;
PO, AO : BYTE;
END_VAR
VAR
night : BOOL;
last_night, last_day : DATE;
END_VAR

(*
version 1.2 6 oct 2007
programmer hugo
tested by tobias


*)

Code:
IF NOT (up AND dn) AND night THEN
(* manual operation at night will cancel operation for one night *)
night := FALSE;
ELSIF (cx.LTOD > cx.SUN_SET + sunset_offset) AND (last_night < cx.LDATE) AND NOT night AND e_night AND UP AND DN THEN
(* enable night *)
night := TRUE;
last_night := DT_TO_DATE(cx.LDT);
ELSIF (cx.LTOD > cx.SUN_RISE + sunrise_offset) AND (last_day < cx.LDATE) AND night AND e_day AND (last_night < cx.LDATE) AND UP AND DN THEN
(* disable night *)
night := FALSE;
last_day := DT_TO_DATE(cx.LDT);
END_IF;

(* shade at night only in auto mode and enable = true *)
IF UP AND DN AND night THEN
status := 141;
po := night_position;
ao := night_angle;
ELSE
po := pi;
ao := ai;
status := s_in;
END_IF;

QU := UP;
QD := DN;


(* revision history
hm 29. sep 2007 rev 1.0
original version

hm 5. oct 2007 rev 1.1
added enable input

hm 6. oct 2007 rev 1.2
added pos and angle inputs and outputs
night position and angle can now be configured
any manual operation at night will cancel night operation

md 29 dec 2013 rev 1.3
added CX variable for sunrise, sunset and date and time information;
activated night program only if automatic mode is detected (i.e.
don't skip auto closing when in manual mode);
corrected missing QU/QD assignment when in night mode

md  12 jan 2015 rev 1.4
removed type conversion for TOD and DATE variables by directly
accessing cx.LTOD and cx.LDATE members

*)

Please note that the block now uses one CALENDAR parameter instead of the SUNRISE, SUNSET and DT parameters. The calendar variable is fed by a CALENDAR_CALC FB instance which does some additional calculations I found useful. If you prefer the original style of dedicated parameters, you can easily change my code back to that approach.

Have you checked the times for sunrise and sunset calculated by SUN_TIME?

Cheers,
mattsches