From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Correctly "unbundle" a CAN Frame Array ?

Solved!
Go to solution

Hi,

 

in my VI (attached) I receive two CAN Frames every 100 ms (ID 0x44C and 0x451 / 1100 and 1105). My program is working but there has to be a more elegant way to access all the payloads with a single CASE structure. This is how it looks:

 

mw42_0-1575449613213.png

 

Any advice please?

0 Kudos
Message 1 of 9
(5,129 Views)

Of course there is!

Can you attach some typical data coming out of point "3." (temporarily create an indicator there, run the VI until it has data. Stop the VI and, disconnect the indicator and turn it into a diagram constant, for example)

 

There are quite a few things wrong.

  • Array to cluster is just plain silly and a detour. Not sure why you would create a 9 element cluster if there are only two array elements.
  • Autoindex on a two iteration FOR loop and process the two array elements.
  • What is the probability that both IDs are the same. Whatever writes to the terminal or local variable of same wins.
  • I doubt you need any local variables or coercion dots.
  • Your representations seem all wrong. "Speed" and "drehzahl" are seemingly 16 bits and "tiefe" 32 bits. How big are the blue U8 arrays? You can probably just typecast it to the right final outputs. 
0 Kudos
Message 2 of 9
(5,114 Views)

Sample data from "3." (this is just simulated payload, the final values will be different)

mw42_0-1575459586436.png

 

Edit: I changed my code to this and it seems to be working

mw42_0-1575461921278.png

 

Edit 2:

According to my representations: I was given the information that I would receive two CAN frames, and that the payload from ID 1100 consisted of "DINT Bytes 0 to 3", "INT Bytes 4+5" and so on... I do not object to this maybe being not reasonable, but I do think I did this to specification (or at least I hope I did 🙂

Edit 3: I thought about it and you are right, I have no idea why 4 Bytes should be represented as a I64, makes no sense. I'm going to get some information about this, maybe I have been misinformed...

0 Kudos
Message 3 of 9
(5,094 Views)
Solution
Accepted by mw42

As I said, all you need is a typecast and correct representations. Same result, no pink, infinitely more efficient!

 

(Please check if these could be signed integers and modify as needed).

 

altenbach_0-1575478415470.png

Message 4 of 9
(5,058 Views)

Thank you, I really learned something !

 

It is working as expected with Typecast 🙂

0 Kudos
Message 5 of 9
(5,011 Views)

@mw42 wrote:

It is working as expected with Typecast 🙂


Do note that Typecast assumes the data is in a Big Endian format.  If the data is actually Little Endian, then you might have to mess around with Byte Array To String and Unflatten From String as they have an input to set the byte order.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 6 of 9
(4,993 Views)

If the endianness was wrong, wouldn't reversing the array and the order of the elements also work?


GCentral
0 Kudos
Message 7 of 9
(4,978 Views)

Yes, I initially did not mention potential byte order complications because the problem was obviously big endian, but for the general reader in the future it is worth mentioning.

 

Reversing the array and reordering the elements will only work if the array is really the correct size. hopefully it is. 😉

0 Kudos
Message 8 of 9
(4,976 Views)

When dealing with CAN there is a standard for knowing how to convert from raw data to scaled engineering units and back.  In most applications there is a DBC file which is a database that states how data should be interpreted.  It says things like:

 

For a frame with ID 0x123, the speed is these bits, and it is this endian, scaled with this value and with this offset.

 

Various other information can be stored there too.  The idea is that if there is a change and values are scaled differently than they were, or new signals are made added or changed.  Then all of this information can be stored in the DBC and it can be loaded.  Then if you want to read data you don't need to have hardcoded scaling constants like what we see here.  NI along with Vector both make tools for creating this database.

 

Now obviously this more generic scaling solution will be much slower than doing some kind of scaling like is shown here, but it is more flexible and an industry standard.  If you want to know more about signal scaling checkout my LabVIEW implementation of Frame and Signal scaling, and more in my CAN blog part 5.

 

Oh and if you are using XNet you can load the database on the hardware, and perform a normal read function which will return the values in engineering units, with the hardware doing the actual scaling.  Search the Help >> Find Examples for more.

0 Kudos
Message 9 of 9
(4,952 Views)