1
Programowanie / Odp: OSCAT - kalibracja rolet
« dnia: Kwietnia 30, 2021, 11:20:40 am »to zablokuj wyjście sterownika (logicznie) na ok minutę czy dwie po powrocie zasilania to otwarcie i ponowne zamknięcie zostanie wykonane ale bez "1" na wyjściu.
Ostatecznie zrobiłem tak:
- Zapisuje wyjście POS z BLIND_CONTROL w VAR RETAIN PERSISTENT
- W pierwszym cyklu zaraz po powrocie zasilania daje tą pozycję na wejście PI bloczku BLIND_CONTROL - dzięki temu jak odpali się kalibracja to roleta podjedzie do góry a następnie wróci w poprzedniej pozycij (właśnie tej wpisanej w PI). Prawie to co chiałem ale jeszcze nie do końca
- Aby zapobiec faktycznemu otwieraniu się rolet po powrocie zasilania wrzuciłem TON'a tak jak sugerowałeś
Kod wygląda mniej więcej tak (zbędne linijki wywalone):
Kod: [Zaznacz]
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
Kod: [Zaznacz]
_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;