Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- FUNCTION_BLOCK TMZ_DM
- VAR_INPUT
- START: BOOL; (* Start request transmission on rising edge *)
- portHandle: DWORD; (* COM port handle *)
- devAddr: BYTE; (* Sensor address *)
- timeout: TIME := T#300ms; (* Response timeout *)
- convUnit: DM_MEAS_UNIT; (* Desired measurement unit *)
- END_VAR
- VAR_OUTPUT
- rawunit: DM_MEAS_UNIT; (* Sensor's measurement unit *)
- raw: REAL; (* Readout in sensor's units *)
- value: REAL; (* Readout in desired units *)
- done: BOOL; (* Communication is over for whatever reason *)
- success: BOOL; (* Communication has been successful *)
- END_VAR
- VAR
- cmdBuf: ARRAY[0..11] OF BYTE :=
- 16#FF, 16#FF, 16#FF, 16#82,
- 16#FF, 16#FF, 16#FF, 16#FF,
- 16#00, 16#01, 16#00, 16#83; (* Tx template/buffer *)
- rcvBuf: ARRAY[0..31] OF BYTE; (* Rx buffer *)
- step, _step: DM_XSTATE;
- sum: BYTE; (* CRC rx temp *)
- stepTimer: TON := (PT := T#30d);
- starter: R_TRIG;
- i, validFramesCount, invalidFramesCount: DWORD;
- END_VAR
- starter(CLK := START);
- IF starter.Q THEN
- step := DM_X_START;
- END_IF
- stepTimer(IN := step = _step);
- _step := step;
- CASE step OF
- DM_X_START: (* Prepare *)
- done := success := FALSE;
- (* Discard any rx leftovers *)
- WHILE SysComRead(portHandle, ADR(i), SIZEOF(i), 0) > 0 DO
- ;
- END_WHILE
- i := 0;
- step := DM_X_TX;
- DM_X_TX: (* Send data request *)
- cmdBuf[8] := devAddr;
- cmdBuf[11] := 0;
- (* tx CRC *)
- FOR i := 3 TO 10 DO
- cmdBuf[11] := cmdBuf[11] XOR cmdBuf[i];
- END_FOR
- SysComWrite(portHandle, ADR(cmdBuf), SIZEOF(cmdBuf), 0);
- step := DM_X_RX;
- i := 0;
- DM_X_RX: (* Receive data *)
- (* Read to the length field rcvBuf[10] at fixed position *)
- IF i < 11 THEN
- i := i + SysComRead(portHandle, ADR(rcvBuf) + i, 11 - i, 0);
- (* Read the rest using value in rcvBuf[10] *)
- ELSE
- i := i + SysComRead(portHandle, ADR(rcvBuf) + i, rcvBuf[10] - i + 11 + 3, 0);
- IF i >= rcvBuf[10] + 14 AND (rcvBuf[10] + 14) <= SIZEOF(rcvBuf) THEN
- (* rx CRC *)
- sum := 0;
- FOR i := 3 TO rcvBuf[10] + 12 DO
- sum := sum XOR rcvBuf[i];
- END_FOR
- success := sum = rcvBuf[10 + rcvBuf[10] + 3];
- IF success THEN
- SysMemSwap(ADR(rcvBuf) + 14, 4, 1);
- SysMemCpy(ADR(raw), ADR(rcvBuf) + 14, SIZEOF(raw));
- rawunit := rcvBuf[13];
- value := DM_CONVERT(raw, rawunit, convUnit);
- validFramesCount := validFramesCount + 1;
- step := DM_X_SUCCESS;
- ELSE
- invalidFramesCount := invalidFramesCount + 1;
- step := DM_X_MALFORMED;
- END_IF
- done := TRUE;
- END_IF
- END_IF
- IF stepTimer.ET > timeout THEN
- invalidFramesCount := invalidFramesCount + 1;
- step := DM_X_TIMEOUT;
- done := TRUE;
- END_IF
- END_CASE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement