LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Unions like C and ordered structures

In data exchange with PLCs, often I have to define Unions (like in C) that uses different names for same memory area data (i.e. a byte and a named array of 8 bits occupying the same byte in memory), but I understand that it's not available even in LabView 24.

Also, I have to define structures (clusters) with a specific sequence of data (bytes, words, etc) in order to collect properly the data from PLC and then, after any elaboration, send it back to PLC. So, having three elements called WORD1, BYTE1, WORD2, they must be in that exact sequence, as if in an array (but with different element's size)

I can't find something like that, unless collect data in an array, convert to what I need, elaborate, convert back in an array then send to PLC.

0 Kudos
Message 1 of 13
(1,238 Views)

@AndyPF wrote:

Also, I have to define structures (clusters) with a specific sequence of data (bytes, words, etc) in order to collect properly the data from PLC and then, after any elaboration, send it back to PLC. So, having three elements called WORD1, BYTE1, WORD2, they must be in that exact sequence, as if in an array (but with different element's size)


For each element in a cluster, you can define the datatype AND you can define the cluster order.

 


@AndyPF wrote:

In data exchange with PLCs, often I have to define Unions (like in C) that uses different names for same memory area data (i.e. a byte and a named array of 8 bits occupying the same byte in memory), but I understand that it's not available even in LabView 24.


A byte IS a set of 8 bits. Can you be a bit more specific? Maybe attach a simplified version of your code?

0 Kudos
Message 2 of 13
(1,229 Views)

I think you can do what you describe by judicious use of TypeCast (found on the Numeric Palette under "Conversion").  I'm attaching a picture (sorry, but it's so simple you should be able to just "look at the picture" and "see the light".

 

I created a PLC Cluster of an I16 (which I made 23), a U8 (31), and another I16 (-6).  To send them to the PLC, I created a "PLC Instruction" Cluster of 5 U8s (it "matches" the size of the "data being sent".  Cluster 3 shows the resulting 5 bytes "as seen by the PLC", and just to make sure the data are the same, I TypeCast it back to the original "form" of Cluster 1.  Coerce to Type.png

 

Now, a really suspicious person may notice that the second TypeCast uses the input data Cluster as the "Type" input, so maybe it's just copying the data (not just the "type").  Good catch!  So drop a Multiply function below the Cluster 3 indicator, wire Cluster 1 to one side and a numeric "0" to the other (which zeros out all three numeric elements of the Cluster) and wire that to the second TypeCast upper input.  Same result -- TypeCast ignores the data on the upper terminal.

 

Bob Schor

0 Kudos
Message 3 of 13
(1,212 Views)

You said: "For each element in a cluster, you can define the datatype AND you can define the cluster order."

But I need to know how to do that.

 

To be a little more specific, I try to explain:

This is what I mean as Union (C code):

 

typedef union {

 unsigned char  Hi;

 unsigned char  Lo;

} HiLo;

 

struct dato{

  unsigned short w;   // seen as a 16bit word

  HiLo  byte;         // seen as a 2 8bit bytes

} word;

 

So, I can access the data contained in the word variable (total lenght 16bit) in two ways:

 

unsigned char a, b;

word.w = 0x1234;

a = word.byte.Hi;

b = word.byte.Lo;

 

and finally a will contain 0x12, and b will contain 0x34.

 

So, I can access the same memory area as a word (16bit) or a sequence of two bytes (8bit).

Note that all elements are referred by name, not as an array element (non-sense number in case of big data structures)

0 Kudos
Message 4 of 13
(1,169 Views)

Thanks for the clarification.  That's also easy.  The "Union" example is an example (illustrated earlier) of a TypeCast -- seeing a 16-bit quantity as either a 16-bit quantity or two 8-bit quantities.  You need to define a Data Type (which I called HiLo Cluster) as a Cluster of two 8-bit quantities (which I call Hi Byte and Lo Byte), and (ideally) save it as a TypeDef.  You then take a 16-bit Word, run it through a TypeCast with your HiLo Cluster (whose value will be ignored, so it can be (0, 0)) and you'll get out a Cluster with Hi Byte having the bits in the High Byte of Word and Lo Byte being the Low Byte of Word.  [For this demo, I made all the Controls and Indicators use Hex, so "1234" splits into "12" and "34"].

AndiPF Demo.png

 I'm also attaching both the code and the saved TypeDef (although a copy of it is also shown on the front panel of the Demo -- you can tell that it has been "TypeDef-ed", however, by the black triangle in the upper left corner of the image of HiLo TypeDef, above).

 

Bob Schor

Download All
0 Kudos
Message 5 of 13
(1,156 Views)

In LabVIEW, the wire is the variable and your definition of hi,lo also must make assumptions on the byte order (big\little endian).

In the end, everything is "just bits", and if you want to display it, you need an indicator that has it's own copy of the data that gets updated according to the rules of dataflow.

 

You seem to be coming from a strong text programming background and you need to learn a few new things and forget some of the "text habits" in order to embrace the power of LabVIEW. Maybe you can take a step back and describe "what" problem you are trying to solve instead of telling us "how" you want to solve it.

 

altenbach_0-1719760353870.png

 

0 Kudos
Message 6 of 13
(1,152 Views)

Thanks, Bob_Schor and Altenbach.

The solution you proposed are what I was using when I used Labview 8 (about 20 years ago) and Labview 2017 (about 7 year ago). Then I stopper to use it for years.

Now I need again to use it, so I bought a license for Labview 2024. That's why I'm asking if there were some changes about that.

First, sorry for my english, I'm writing from Italy.

 

What I would like to have (and I have in C or in IEC PLC programming, the languages I use more) a strucure o named variables.

I.e., I have a byte of bit entry (PLC inputs) that have names on the machine/plant: 

bit0  Led1

bit1  Led2

bit2  Solenoid1

bit3  Contactor

bit4  Solenoid2

...

These are parts of Output Word, so if I want to switch on the Led2, I have to move a 1 (true) on the relevant bit

 

Output.Led2 = 1;

 

And, if I need to switch all output off (for a safety event), I write a 0x00 in the word:

 

Output.w = 0;

 

So, I'd like to use a simple access to the cluster (like a bundle by name) to access all the items by name, but overlapped in position.

Anyway, I see there's no direct possibility to access data like union, so I will proceed as usual.

 

Thanks a lot

 

 

0 Kudos
Message 7 of 13
(1,141 Views)

All boolean logic will operate bitwise on integers. as an example, here is a malleable VI that lets you easily set/clear/toggle a list of bits (an array of positions).

0 Kudos
Message 8 of 13
(1,136 Views)

I am clearly "answering questions that you are not asking"!  Part of the reason is that you have not provided any LabVIEW code that shows us what LED1, LED2, Solenoid1, Contactor, or Solenoid2 are.  In your latest post, they seem to be "bit positions", 0 through 4, and (I'm guessing, here) will be used to Read or Write a Value (a Boolean?  A U8 as you seem to indicate in your earlier "text" examples?  A U16 or possibly I16?  Show us some code!) somewhere or "make something happen" (which we also don't understand).

 

For reasons that escape me (except that you seem to be coming from a C++ or similar Text-base programming environment, where "tricks" such as having Unions and Structures for communicating with the PLC are necessary.  Am I not correct that PLC commands have a particular "structure" (based on the command) that details (and I'm making stuff up here) a calling sequence something like "Command (U8), Command Parameters (Cluster, basically fixed for the Command), where everything being sent to the PLC is in bytes (trivial for the Command, and "byte-ifiable" for the Cluster defining the Command Parameters)?

 

What I would do (and have done) is write a sub-VI for each Command (I'm thinking about "Do something" Commands that don't return results, but it would be easy to extend this to "give the command" and follow with a "Read the Results" sub-VI).  Note that you don't need to provide the Command (U8) variable -- you "hide" this detail inside the sub-VI.  All you have to do is to parse the Command Parameters into an Array of Bytes, prepend the Command byte, and send the result (as an Array of Bytes) to the PLC.  LabVIEW (on a modern PC) is so fast (and memory is so plentiful) that having a tiny VI specific for each Command, and not worrying about "saving one core location" (I remember early minicomputers where this was an important Programming Consideration!) is definitely the way to go -- it makes your code so much more readable to have a string of 32x32 Icons that say "Initialize PLC", "Move to X", "Move to Y", "Rotate CW" (with parameters that specify variable amounts) and just build the specific command inside each VI.  You build one, test it, fix it, and then copy it (renaming as needed) and make sure each "follows the Rules of the PLC".  If one works, and you "follow the rules", they should all work.

 

Start thinking LabVIEW, Data Flow, and all that!

 

Bob Schor

0 Kudos
Message 9 of 13
(1,122 Views)

Bob, thanks for answer but...

I can't send any code because LabVIEW does not allow me to do what I want to do.

Probably my writing is not clear, I'm sorry for that.

What I described is a generic example, in particular of some bit inside a word (16bit, or U16 if you prefer).

What I want to show is to access data sometimes like bits (but by name, not as elements of an array of 0/1) or instead in a whole word, with a proper name. That's to avoid what we call "magic numbers". A 2 can sometimes indicate a number or the index for my Solenoid1.

One good rule, in any language I used, is always avoid magic numbers and use names. Mainly for future reference.

 

Moreover, I'm not programming a PLC by LabVIEW, but I have to read, operate with and save back some data, and I have to maintain the data structure of the PLC, that's all.

I'll do as usual, reading arrays of data, point the specific data using array functions, at least avoiding magic number using enumerations or text rings.

Be sure, I know how to think in Data Flow, I first used LabVIEW in 1999, I explained at least two times and in topic name that my reference is C programming.

Starting programming in 1980, at the time the memory costraint was a must, and I still try to optimize the memory access, especially if I have to interface with PLCs or MCUs.

 

Sorry, but I still not well understood how to be sure that the sequence and the occupation of each element in a cluster (structure), in order to comply with external data.

Regards

0 Kudos
Message 10 of 13
(1,106 Views)