--- a +++ b/trunk/d-logg/d-logg.library.md @@ -0,0 +1,147 @@ +--- + +~~~ST +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 + +~~~ +~~~ST +// 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 + +~~~ +--- +~~~ST +METHOD raw2temp: REAL +VAR_INPUT + raw: WORD; +END_VAR +VAR + tmp: INT; +END_VAR + +~~~ +~~~ST +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