0

I'm trying to send a 32-Bit Real across a CAN communications (IFM) but the CAN comms only accepts a 16-Bit value.

If the value I'm trying to send goes above 255, it resets back to 0 and continues in that pattern. I therefore need to split the 32-Bit Real value in to two 16-Bit values and then reassemble on the other side of the comms.

I just can't seem to get my head around how to do it in structured text.

Any help would be appreciated

LBPLC
  • 1,570
  • 3
  • 27
  • 51

2 Answers2

1

First. I have no experience with CAN and I don't know which FBs you use to send them. But if it resets over 255 it seems like you can only send 8bit-values (bytes) instead of 16bit.

Second. I would suggest an UNION Solution (REAL_BYTE_SIZE = 4):

The variables in an UNION share the same memory. Therefore they can be interpreted in different ways

TYPE U_RealForCanBus :
UNION
rValue : REAL;
arrbyBytes : ARRAY[1..REAL_BYTE_SIZE] OF BYTE;
END_UNION
END_TYPE

If you declare a

uRealToSendOverCan : U_RealForCanBus;

you can set uRealToSendOverCan.rValue and read uRealToSendOverCan.arrbyBytes

Or you could just do MEMCPY if you don't want the variables to share the memory:

rValue : REAL;

arrbyToSend : ARRAY[1..REAL_BYTE_SIZE] OF BYTE;


MEMCPY(ADR(arrbyToSend ),ADR(rValue),REAL_BYTE_SIZE);

Or you can always use a pointer to interpret the memory in a different way:

rValue : REAL;

parrbyToSend : POINTER TO ARRAY[1..REAL_BYTE_SIZE] OF BYTE;


parrbyToSend := ARD(rValue); //Initialize pointer

parrbyToSend^[2] ... //Second Byte of rValue
Felix Keil
  • 2,344
  • 1
  • 25
  • 27
  • I get the error: `MEMCPY is no function` when trying to use this, I guess I don't have the library for it? - Update, I do, but in Structured Text it doesn't like using it – LBPLC Sep 14 '15 at 08:07
  • It may be worth mentioning that I'm using Codesys 2.3, UNION is not available – LBPLC Sep 14 '15 at 08:16
  • I don't know what the problem is with MEMCPY at your side, but another idea is to use a pointer to interpret the variable different. I edited the answer therefore – Felix Keil Sep 14 '15 at 12:50
1

I know I am a little late to the party but wanted to add this as a solution.

VAR
  rRealVar  :   REAL;
  awWordArray   :   ARRAY[0..1] OF WORD;
  pTemp     :   POINTER TO REAL;
  pTemp2        :   POINTER TO REAL;
END_VAR

// Get a pointer to the REAL variable
pTemp := ADR(rRealVar);

// Get a pointer to the ARRAY base
pTemp2 := ADR(awWordArray);

// Assign the value of the REAL variable into the ARRAY base
pTemp2^ := pTemp^;

(* Index 0 := Bits 15-0
   Index 1 := Bits 31-16

This is similar to Felix Keil's answer but it makes use of 2 pointer variables and a word array to retrieve the information directly.

mrsargent
  • 2,267
  • 3
  • 19
  • 36