Advertisement
Guest User

Untitled

a guest
Dec 8th, 2014
400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
SCL 2.63 KB | None | 0 0
  1. FUNCTION_BLOCK TMZ_DM
  2. VAR_INPUT
  3.     START: BOOL;        (* Start request transmission on rising edge *)
  4.     portHandle: DWORD;  (* COM port handle *)
  5.     devAddr: BYTE;      (* Sensor address *)
  6.     timeout: TIME := T#300ms; (* Response timeout *)
  7.     convUnit: DM_MEAS_UNIT; (* Desired measurement unit *)
  8. END_VAR
  9. VAR_OUTPUT
  10.     rawunit: DM_MEAS_UNIT;  (* Sensor's measurement unit *)
  11.     raw: REAL;      (* Readout in sensor's units *)
  12.     value: REAL;    (* Readout in desired units *)
  13.     done: BOOL;     (* Communication is over for whatever reason *)
  14.     success: BOOL;  (* Communication has been successful *)
  15. END_VAR
  16. VAR
  17.     cmdBuf: ARRAY[0..11] OF BYTE :=
  18.         16#FF, 16#FF, 16#FF, 16#82,
  19.         16#FF, 16#FF, 16#FF, 16#FF,
  20.         16#00, 16#01, 16#00, 16#83; (* Tx template/buffer *)
  21.     rcvBuf: ARRAY[0..31] OF BYTE;   (* Rx buffer *)
  22.     step, _step: DM_XSTATE;
  23.     sum: BYTE;                      (* CRC rx temp *)
  24.     stepTimer: TON := (PT := T#30d);
  25.     starter: R_TRIG;
  26.     i, validFramesCount, invalidFramesCount: DWORD;
  27. END_VAR
  28.  
  29. starter(CLK := START);
  30. IF starter.Q THEN
  31.     step := DM_X_START;
  32. END_IF
  33. stepTimer(IN := step = _step);
  34. _step := step;
  35. CASE step OF
  36.     DM_X_START: (* Prepare *)
  37.         done := success := FALSE;
  38.         (* Discard any rx leftovers *)
  39.         WHILE SysComRead(portHandle, ADR(i), SIZEOF(i), 0) > 0 DO
  40.             ;
  41.         END_WHILE
  42.         i := 0;
  43.         step := DM_X_TX;
  44.     DM_X_TX: (* Send data request *)
  45.         cmdBuf[8] := devAddr;
  46.         cmdBuf[11] := 0;
  47.         (* tx CRC *)
  48.         FOR i := 3 TO 10 DO
  49.             cmdBuf[11] := cmdBuf[11] XOR cmdBuf[i];
  50.         END_FOR
  51.         SysComWrite(portHandle, ADR(cmdBuf), SIZEOF(cmdBuf), 0);
  52.         step := DM_X_RX;
  53.         i := 0;
  54.     DM_X_RX: (* Receive data *)
  55.         (* Read to the length field rcvBuf[10] at fixed position *)
  56.         IF i < 11 THEN
  57.             i := i + SysComRead(portHandle, ADR(rcvBuf) + i, 11 - i, 0);
  58.         (* Read the rest using value in rcvBuf[10] *)
  59.         ELSE
  60.             i := i + SysComRead(portHandle, ADR(rcvBuf) + i, rcvBuf[10] - i + 11 + 3, 0);
  61.             IF i >= rcvBuf[10] + 14 AND (rcvBuf[10] + 14) <= SIZEOF(rcvBuf) THEN
  62.                 (* rx CRC *)
  63.                 sum := 0;
  64.                 FOR i := 3 TO rcvBuf[10] + 12 DO
  65.                     sum := sum XOR rcvBuf[i];
  66.                 END_FOR
  67.                 success := sum = rcvBuf[10 + rcvBuf[10] + 3];
  68.                 IF success THEN
  69.                     SysMemSwap(ADR(rcvBuf) + 14, 4, 1);
  70.                     SysMemCpy(ADR(raw), ADR(rcvBuf) + 14, SIZEOF(raw));
  71.                     rawunit := rcvBuf[13];
  72.                     value := DM_CONVERT(raw, rawunit, convUnit);
  73.                     validFramesCount := validFramesCount + 1;
  74.                     step := DM_X_SUCCESS;
  75.                 ELSE
  76.                     invalidFramesCount := invalidFramesCount + 1;
  77.                     step := DM_X_MALFORMED;
  78.                 END_IF
  79.                 done := TRUE;
  80.             END_IF
  81.         END_IF
  82.         IF stepTimer.ET > timeout THEN
  83.             invalidFramesCount := invalidFramesCount + 1;
  84.             step := DM_X_TIMEOUT;
  85.             done := TRUE;
  86.         END_IF
  87. END_CASE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement