FUNCTION_BLOCK DLogg
VAR_INPUT
udtInput: IoDrvInput;
udtConfig: IoDrvConfig;
END_VAR
VAR_OUTPUT
udtOutput: IoDrvOutput;
END_VAR
VAR
stream: SerialStream;
i: LINT;
byByte: BYTE;
nRead: UDINT;
nWrote: ULINT;
dwState: DWORD;
udiNumDL: UDINT;
audtSensor: ARRAY [..] OF ;
audtSolar1: ARRAY [..] OF ;
audtSolar2: ARRAY [..] OF ;
byChecksum: BYTE;
Delay: TON;
END_VAR
// Execute the FB only every second
// Quicker sampling is not supported by the logger
Delay(IN:=TRUE, PT:=T#1S);
IF NOT(Delay.Q) THEN
RETURN;
END_IF
Delay(IN:=FALSE);
// Start with the state machine
CASE dwState OF
0: stream.Open(1, 115200);
next();
// Read number of data loggers
1: nWrote := stream.WriteByte(16#81);
IF nWrote = 1 THEN
next();
END_IF
2: IF stream.Length >= 1 THEN
stream.Read(ADR(byByte), 1);
CASE byByte OF
16#A8: udiNumDL := 1;
16#D1: udiNumDL := 2;
END_CASE
next();
END_IF
// Read Data-Logger Type (also polls for new data)
3: nWrote := stream.WriteByte(16#AB);
IF nWrote = 1 THEN
next();
END_IF
4: IF stream.Length >= 1 THEN
byByte := stream.ReadByte();
CASE byByte OF
16#AB: reset(); // no new data
16#80: next(); // UVR1611
16#90: next(); // UVR61-3
END_CASE
END_IF
// Read sensor data
5: IF stream.Length >= (39 + 16 + 1) * udiNumDL THEN
FOR i:=0 TO udiNumDL-1 DO
stream.Read(ADR(audtSensor[i]), 39);
stream.Read(ADR(audtSolar1[i]), 8);
stream.Read(ADR(audtSolar2[i]), 8);
byChecksum := stream.ReadByte();
END_FOR
next();
END_IF
// Convert RAW data to temperatures and boolean actor data
6: udtInput.C0_S1 := THIS^.raw2temp(audtSensor[0].auiTemperature[0]);
udtInput.C0_S2 := THIS^.raw2temp(audtSensor[0].auiTemperature[1]);
udtInput.C0_S3 := THIS^.raw2temp(audtSensor[0].auiTemperature[2]);
udtInput.C0_S4 := THIS^.raw2temp(audtSensor[0].auiTemperature[3]);
udtInput.C0_S5 := THIS^.raw2temp(audtSensor[0].auiTemperature[4]);
udtInput.C0_S6 := THIS^.raw2temp(audtSensor[0].auiTemperature[5]);
udtInput.C0_S7 := THIS^.raw2temp(audtSensor[0].auiTemperature[6]);
udtInput.C0_S8 := THIS^.raw2temp(audtSensor[0].auiTemperature[7]);
udtInput.C0_S9 := THIS^.raw2temp(audtSensor[0].auiTemperature[8]);
udtInput.C0_S10 := THIS^.raw2temp(audtSensor[0].auiTemperature[9]);
udtInput.C0_S11 := THIS^.raw2temp(audtSensor[0].auiTemperature[10]);
udtInput.C0_S12 := THIS^.raw2temp(audtSensor[0].auiTemperature[11]);
udtInput.C0_S13 := THIS^.raw2temp(audtSensor[0].auiTemperature[12]);
udtInput.C0_S14 := THIS^.raw2temp(audtSensor[0].auiTemperature[13]);
udtInput.C0_S15 := THIS^.raw2temp(audtSensor[0].auiTemperature[14]);
udtInput.C0_S16 := THIS^.raw2temp(audtSensor[0].auiTemperature[15]);
udtInput.C1_S1 := THIS^.raw2temp(audtSensor[1].auiTemperature[0]);
udtInput.C1_S2 := THIS^.raw2temp(audtSensor[1].auiTemperature[1]);
udtInput.C1_S3 := THIS^.raw2temp(audtSensor[1].auiTemperature[2]);
udtInput.C1_S4 := THIS^.raw2temp(audtSensor[1].auiTemperature[3]);
udtInput.C1_S5 := THIS^.raw2temp(audtSensor[1].auiTemperature[4]);
udtInput.C1_S6 := THIS^.raw2temp(audtSensor[1].auiTemperature[5]);
udtInput.C1_S7 := THIS^.raw2temp(audtSensor[1].auiTemperature[6]);
udtInput.C1_S8 := THIS^.raw2temp(audtSensor[1].auiTemperature[7]);
udtInput.C1_S9 := THIS^.raw2temp(audtSensor[1].auiTemperature[8]);
udtInput.C1_S10 := THIS^.raw2temp(audtSensor[1].auiTemperature[9]);
udtInput.C1_S11 := THIS^.raw2temp(audtSensor[1].auiTemperature[10]);
udtInput.C1_S12 := THIS^.raw2temp(audtSensor[1].auiTemperature[11]);
udtInput.C1_S13 := THIS^.raw2temp(audtSensor[1].auiTemperature[12]);
udtInput.C1_S14 := THIS^.raw2temp(audtSensor[1].auiTemperature[13]);
udtInput.C1_S15 := THIS^.raw2temp(audtSensor[1].auiTemperature[14]);
udtInput.C1_S16 := THIS^.raw2temp(audtSensor[1].auiTemperature[15]);
udtInput.C0_A0 := audtSensor[0].abyDOUT[0];
udtInput.C0_A1 := audtSensor[0].abyDOUT[1];
udtInput.C1_A0 := audtSensor[1].abyDOUT[0];
udtInput.C1_A1 := audtSensor[1].abyDOUT[1];
next();
// End
7: reset();
END_CASE
METHOD raw2temp: REAL
VAR_INPUT
raw: WORD;
END_VAR
VAR
tmp: INT;
END_VAR
tmp := WORD_TO_INT(raw AND 16#8000);
tmp := SHR(tmp, 3);
tmp := UINT_TO_INT(WORD_TO_UINT(raw AND 16#0FFF) OR INT_TO_UINT(tmp));
raw2temp := tmp / 10;
VAR_GLOBAL
cClassID: DWORD;
cDriverName: string;
cDeviceName: string;
cVendorName: string;
cModuleType: WORD;
END_VAR