FUNCTION_BLOCK WetterStationV2
VAR_INPUT
Windwarnung:INT; // Ab wieviel m/s gibt der Baustein Windwarnung aus
Windwarnung_Rueck:INT; // Ab wieviel m/s wird die WIndwarnung zurückgesetzt
Verz_Windwarnung:TIME;
Verz_Windwarnung_Rueck:TIME;
Hell_Schwelle:INT; // Ab wieviel Lux ist es Hell genug für Verschattung
END_VAR
VAR_OUTPUT
o_Temperatur:REAL;
o_Sonne_Sued:INT; (*1-99klx*)
o_Sonne_West:INT; (*1-99klx*)
o_Sonne_Ost:INT; (*1-99klx*)
o_Daemmerung:BOOL;
o_Tageslicht:INT; (*1-999Lx*)
o_Wind:REAL; (*m/s*)
o_Regen:BOOL;
o_Windwarnung:BOOL;
o_Sonne_West_Hell:BOOL;
o_Sonne_Ost_Hell:BOOL;
o_Sonne_Sued_Hell:BOOL;
END_VAR
VAR
sInterface:FbSerialInterface_cpt;
x_Open: BOOL;
x_IsOpen: BOOL;
x_IsIdle: BOOL;
x_Error: BOOL;
x_TxTrigger: BOOL;
x_TxBuffer: STRING;
x_RxBuffer: ARRAY[1..40] OF BYTE;
AsciiBuffer: ARRAY[1..40] OF STRING;
udiRxIndex: UDINT;
x_BufferFull: BOOL;
x_RxOverflow: BOOL;
x_ResetStatus: BOOL;
st_Starus: STRING;
Counter: INT;
BufferIndex: INT;
Watchdog:TON;
Watchdog_Trigger: R_TRIG;
close_status: WAGOAPPCOM.FbResult;
close_error: BOOL;
close_done: BOOL;
close_busy: BOOL;
ResetWatchdog: BOOL;
falsch: BOOL;
index: UDINT;
SearchCounter: INT;
DataBegin:INT;
DataEnd:INT;
CorrectedIndex: INT;
Windwarnung_Hoch_TON:TON;
Windwarnung_Niedrig_TON:TON;
Temp_Windwarnung_Hoch:BOOL;
Temp_Windwarnung_Niedrig:BOOL;
Windwarnung_Start:R_TRIG;
Windwarnung_Stop:R_TRIG;
tSonneWestHell:BOOL;
tSonneOstHell:BOOL;
tSonneSuedHell:BOOL;
TOF_SonneWestHell:TOF;
TOF_SonneOstHell:TOF;
TOF_SonneSuedHell:TOF;
END_VAR
IF NOT x_IsOpen THEN
x_Open := TRUE;
sInterface(
oStatus=> ,
xOpen:= x_Open,
xIsOpen=> x_IsOpen,
xIsIdle=> x_IsIdle,
xError=> x_Error,
xTxTrigger:= x_TxTrigger,
pTxBuffer:= ADR(x_TxBuffer),
udiTxNBytes:= INT_TO_UDINT(LEN(x_TxBuffer)),
pRxBuffer:= ADR(x_RxBuffer),
udiRxBufferSize:= SIZEOF(x_RxBuffer),
udiRxIndex:= udiRxIndex,
xRxBufferFull=> x_BufferFull,
xRxOverflow=> x_RxOverflow,
xResetStatus:= x_ResetStatus,
I_Port:= COM1,
udiBaudrate:= 19200,
usiDataBits:= 8,
eParity:= eTTYParity.None,
eStopBits:= eTTYStopBits.One,
eHandshake:= eTTYHandshake.None,
ePhysical:= eTTYPhysicalLayer.RS485_HalfDuplex);
st_Starus := sInterface.oStatus.GetDescription();
ELSE
sInterface(xTxTrigger := x_TxTrigger, udiRxIndex := udiRxIndex);
END_IF
IF udiRxIndex = 40 THEN BufferIndex := BufferIndex + 1; END_IF
IF x_RxBuffer[udiRxIndex] = 87 THEN
index := udiRxIndex;
//udiRxIndex := 0;
// falsch := TRUE;
END_IF
// WAtchdog
Watchdog_Trigger(CLK := (udiRxIndex = 40));
Watchdog(IN:=(x_IsOpen AND NOT Watchdog_Trigger.Q AND NOT ResetWatchdog), PT := T#5S);
IF Watchdog.Q THEN
//sInterface.finish();
// x_Open := FALSE;
//x_ResetStatus := TRUE;
// sInterface.I_Port.Close(ADR(PLC_PRG.Wetter2));
ResetWatchdog := TRUE;
ELSE
ResetWatchdog := FALSE;
END_IF
// Wenn Puffer voll ist, werden die Werte ausgewertet...
IF sInterface.xRxBufferFull THEN
// Suche Anfang und Ende des Puffers
FOR SearchCounter:= 1 TO SIZEOF(x_RxBuffer) DO
IF x_RxBuffer[SearchCounter] = 87 THEN DataBegin := SearchCounter; END_IF
IF x_RxBuffer[SearchCounter] = 3 THEN DataEnd := SearchCounter; END_IF
END_FOR
FOR Counter:= 1 TO SIZEOF(x_RxBuffer) DO
CorrectedIndex := DataBegin + Counter - 1;
IF CorrectedIndex > SIZEOF(x_RxBuffer) THEN CorrectedIndex := CorrectedIndex - SIZEOF(x_RxBuffer); END_IF
AsciiBuffer[Counter] := ASCIIByte_To_String(b:=x_RxBuffer[CorrectedIndex] );
END_FOR
// Boolsche Werte
IF AsciiBuffer[13] = 'J' THEN o_Daemmerung := TRUE; ELSE o_Daemmerung := FALSE; END_IF
IF AsciiBuffer[21] = 'J' THEN o_Regen := TRUE; ELSE o_Regen := FALSE; END_IF
// Real Werte
// Temperatur
o_Temperatur := (STRING_TO_INT(AsciiBuffer[3]) * 10) + STRING_TO_INT(AsciiBuffer[4]) + (STRING_TO_INT(AsciiBuffer[6]) * 0.1);
IF AsciiBuffer[2] = '+' THEN o_Temperatur := o_Temperatur; ELSE o_Temperatur := o_Temperatur * -1; END_IF
// Wind
o_Wind := (STRING_TO_INT(AsciiBuffer[17]) * 10) + STRING_TO_INT(AsciiBuffer[18]) + (STRING_TO_INT(AsciiBuffer[20]) * 0.1);
// Int Werte
// Sonne Süden
o_Sonne_Sued := (STRING_TO_INT(AsciiBuffer[7]) * 10) + STRING_TO_INT(AsciiBuffer[8]);
// Sonne West
o_Sonne_West := (STRING_TO_INT(AsciiBuffer[9]) * 10) + STRING_TO_INT(AsciiBuffer[10]);
// Sonne Ost
o_Sonne_Ost := (STRING_TO_INT(AsciiBuffer[11]) * 10) + STRING_TO_INT(AsciiBuffer[12]);
// Tageslicht
o_Tageslicht := (STRING_TO_INT(AsciiBuffer[14]) * 100) + (STRING_TO_INT(AsciiBuffer[15]) * 10) + STRING_TO_INT(AsciiBuffer[16]);
// und dann der Index wieder auf 0 zurückgesetzt
udiRxIndex := 0;
END_IF
// Überprüfung auf Windwarnung
IF o_Wind > Windwarnung THEN Temp_Windwarnung_Hoch := TRUE;
ELSE Temp_Windwarnung_Hoch := FALSE;
END_IF
// WIndwarnung setzen
Windwarnung_Hoch_TON(IN := Temp_Windwarnung_Hoch, PT := Verz_Windwarnung);
Windwarnung_Start(CLK := Windwarnung_Hoch_TON.Q);
IF Windwarnung_Start.Q THEN o_Windwarnung := TRUE; END_IF
IF o_Wind < Windwarnung_Rueck THEN Temp_Windwarnung_Niedrig := TRUE;
ELSE Temp_Windwarnung_Niedrig := FALSE;
END_IF
Windwarnung_Niedrig_TON(IN := Temp_Windwarnung_Niedrig, PT := Verz_Windwarnung_Rueck);
Windwarnung_Stop(CLK := Windwarnung_Niedrig_TON.Q);
IF Windwarnung_Stop.Q THEN o_Windwarnung := FALSE; END_IF
IF o_Sonne_Ost > Hell_Schwelle THEN
tSonneOstHell := TRUE;
ELSE
tSonneOstHell := FALSE;
END_IF
IF o_Sonne_West > Hell_Schwelle THEN
tSonneWestHell := TRUE;
ELSE
tSonneWestHell := FALSE;
END_IF
IF o_Sonne_Sued > Hell_Schwelle THEN
tSonneSuedHell := TRUE;
ELSE
tSonneSuedHell := FALSE;
END_IF
TOF_SonneWestHell(IN := tSonneWestHell, PT := T#15M, Q => o_Sonne_West_Hell);
TOF_SonneOstHell(IN := tSonneOstHell, PT := T#15M, Q => o_Sonne_Ost_Hell);
TOF_SonneSuedHell(IN := tSonneSuedHell, PT := T#15M,Q => o_Sonne_Sued_Hell);