I have a question, maybe easy for you, but I cannot solve it and maybe you can help. I have a sensor that provides me the data in an array of 16 bytes. I need to take the 4 first bytes and save it in an INT value which is a distance value, so I have in the four first bytes [0,0,1,181,..] which is 437 mm that my sensor is displaying I need these 437 into a variable (INT I suppose). How can I do it easily?
Thanks for your help!
Use CAA Memory PackBytesToDword function: https://help.codesys.com/webapp/s6roH8o4mLnj5nlRX9QvTFobNAo%2FPackBytesToDword;product=CAA_Memory;version=22.214.171.124
optionally followed by a DWORD_TO_DINT cast if you have a signed value in two's complement.
Also, INT is two bytes. You want DINT (4 bytes).
Hi, can you re-share the link. This one seems to be inactive at the moment.
Here you are: https://help.codesys.com/webapp/JMeheH6MvY4aZSJh5TgzrbLOrZE%2FPackBytesToDword;product=CAA%20Memory;version=126.96.36.199
It is just the Codesys WebHelp, you could have searched for PackBytesToDword.
You should recheck your coefficients, because 2^16 is not 4096 and 2^24 is not 65536.
Or just use the PackBytesToDWord function which is more explicative in source code.
Probably the easiest and most efficient way is to use pointer. Just create a pointer to DWORD since it's 4 bytes. For example:
// create variable
pdwValue : POINTER TO DWORD;
// map variable to memory address
pdwValue := ADR(Application.GVL_IO_LINK.Port1_inputs);
// dereference pointer to get value and operate on it directly
IF (pdwValue^ > 500) THEN
// do something
// less efficient way would be to copy value to another variable
myValue := pdwValue^;
This works only if you have a big endian machine.
The easiest way would be using the dedicated functions from CAA Memory.
Oh good catch! I didn't notice the system endianess. Typically, I would avoid adding additional libraries just to use a single function.
Let's get back to the basics where packing bytes is simply bit shifting. In this case, the output could be computed via (assuming receiving system is little endian):
dwOutput := SHL(Application.GVL_IO_LINK.Port1_inputs, 24) + SHL(Application.GVL_IO_LINK.Port1_inputs, 16) + SHL(Application.GVL_IO_LINK.Port1_inputs, 8) + Application.GVL_IO_LINK.Port1_inputs;
Bit shifting is the equivalent of multiplying by orders of 2 (e.g. shift left by 1 means multiply by 2).
The focus is on the readability, almost everyone can roll a (de)serialization code.
A library function which is already made and does everything right and aptly named is way better than something that would be copypasted all over the place and quickly gets messy.
Besides that, your code is broken on 16-bit processors. Yes, they still exist, run Codesys and continue to be deployed.
Log in to post a comment.