Autor Thema: Save blind position in case of power failure  (Gelesen 1130 mal)

0 Mitglieder und 1 Gast betrachten dieses Thema.

Offline dawrut

  • Newbie
  • *
  • Beiträge: 10
    • Profil anzeigen
Save blind position in case of power failure
« am: 28. April 2021, 22:44:27 »
How are you saving the position of the blind in case of a power failure?

Function BLIND_CONTROL_S has built-in automatic calibration which is needed to know the position of the blind in case of power failure or PLC restart. In such a case, the blind goes up. Is there a way to store the current position so that after the power failure the blind won't go up?
I was trying to add the whole BLIND_CONTROL_S  function block to the VAR RETAIN PERSISTENT memory area but this didn't help. I was also trying to store the POS output of the BLIND_CONTROL_S (which is the input for the POS of the BLIND_INPUT) but this also doesn't stop blinds to go up in case of power failure.

Any ideas?

Offline dawrut

  • Newbie
  • *
  • Beiträge: 10
    • Profil anzeigen
Re: Save blind position in case of power failure
« Antwort #1 am: 30. April 2021, 09:50:31 »
I started to do small POC, I almost finish coding and what I have is:
  • I'm storing the output POS of the BLIND_CONTROL in the PERSISTENT memory area of the PLC
  • In the first PLC cycle after power failure I'm putting that value to the PI input variable of the BLIND_CONTROL - this will cause that during the calibration the blinds will go up and then come back to the previous position. Almost done but still, blinds will unnecessary goes up as I know the position!
  • In order to stop the physicals move of the blinds I'm using TON which will allow to set up PLC outputs (which triggers relays) after 90s so when the calibration is done by BLIND_CONTROL - so I've no blinds movement.

The code looks like this (without sunset and sunrise calculation code):

FUNCTION_BLOCK Blind
VAR_INPUT
    xBlindDown: BOOL;
    xBlindUp: BOOL;
    xAutoSunset: BOOL := FALSE;
    xAutoSunrise: BOOL := FALSE;
    tMaxRuntime: TIME := T#32S;
    tTimeUp: TIME := T#30S;
    tTimeDown: TIME := T#30S;


END_VAR
VAR_OUTPUT
    xBlindControlUp: BOOL;
    xBlindControlDown: BOOL;
END_VAR
VAR_IN_OUT
    PersistentData: BlindData; //this data is stored in VAR RETAIN PERSISTENT in the PLC_PRG
END_VAR
VAR
    _oBlindInput: OSCAT_BUILDING.BLIND_INPUT := (MAX_RUNTIME := tMaxRuntime, MANUAL_TIMEOUT := T#2M);
    _oBlindNight: OSCAT_BUILDING.BLIND_NIGHT;
    _oBlindSecurity: OSCAT_BUILDING.BLIND_SECURITY;
    _oBlindControl: OSCAT_BUILDING.BLIND_CONTROL_S;   
    _xInitPosition: BOOL := FALSE;
    _byBlindControlPosition: BYTE;
    _calibrationBlocker: TON;
    _xMasterMode: BOOL := FALSE;       
END_VAR

_calibrationBlocker(IN := TRUE, PT := T#90S);


_oBlindInput(
    POS:= PersistentData.byCurrentPosition,
    S1:= xBlindUp,
    S2:= xBlindDown,
    MASTER_MODE := _xMasterMode
);


_oBlindNight(
    UP := _oBlindInput.QU,
    DN := _oBlindInput.QD,
    S_IN := _oBlindInput.STATUS,
    PI := _oBlindInput.PO,
    DTIN := _dtCurrentDateTimeUTC,
    SUNRISE := _oSunTime.SUN_RISE,
    SUNSET := _oSunTime.SUN_SET,
    E_NIGHT := xAutoSunset,
    E_DAY := xAutoSunrise
);


_oBlindSecurity(
    UP := _oBlindNight.QU,
    DN := _oBlindNight.QD,
    S_IN := _oBlindNight.STATUS,
    PI := _oBlindNight.PO,
);


IF (NOT _xInitPosition) THEN
    // in the first cycle lets read last position saved before the power failure and set it to _oBlindControl PI input
    // this will casue the _oBlindControl to move to last position after calibration
    // we are reading the position only onece - in the first cycle after the power is back
    _byBlindControlPosition := PersistentData.byCurrentPosition;
END_IF


IF (_calibrationBlocker.Q) THEN
    // then, after calibration, just read the position from previous block (standard behaviour)
    _byBlindControlPosition := _oBlindSecurity.PO;
   
    // switch master mode back to true, initially it is false because we need to transfer PersistentData.byCurrentPosition change to all
    // the block (when the _oBlindControl is calibrating)   
    _xMasterMode := TRUE;
END_IF


_xInitPosition := TRUE;


_oBlindControl(
    T_UP := tTimeUp,
    T_DN := tTimeDown,
    UP := _oBlindSecurity.QU,
    DN := _oBlindSecurity.QD,
    S_IN := _oBlindSecurity.STATUS,
    PI := _byBlindControlPosition,
    POS => PersistentData.byCurrentPosition
);


// set outputs after the calibration (when _calibrationBlocker.Q is TRUE after 90 seconds)
// we don't need real calibration as we are saving last know position (before the power failure/full download) in PersistentData.byCurrentPosition
xBlindControlDown := _oBlindControl.MD AND _calibrationBlocker.Q;
xBlindControlUp := _oBlindControl.MU AND _calibrationBlocker.Q;

What I have is:
  • BLIND_CONTROL is doing calibration without physical movement of the blinds movement is not needed because I remember the position
  • BLIND_CONTROL after doing this "virtual" calibration will move gets back to the previously remembered position which I push to the PI input

I Will be doing some real testing today but so far it looks good in the simulation model.

Is the MASTER_MODE := TRUE actually needed in the BLIND_INPUT? What it actually does?


Any other ideas? Other approaches?