LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 
Reply

Advice for data transmission from LabVIEW to C (or Python, etc)

Solved!
Go to solution

We are designing a LabVIEW application from where I would like to send data to external applications written in C or other text language. So some text coder colleagues could test raw measurement data in parallel time by time. The data to be sent usually consist of maximum 1 million integer values, type U16. The natural choice would be TCP or udp protocol to be used. The C code would be run occasionally on the same computer (localhost) or on another one being in the same LAN.

I have read several posts dealing with similar questions but I could not come to a final conclusion yet, what would be the best approach in my case.

I wonder if udp protocol could fulfill my needs as I know that pocket losses are very unlikely in a simple LAN network. But an udp datagram is limited in size (50000 bytes or so), so I would need several packages to send. So maybe I would go for the TCP protocol. Another question comes to my mind is which side should be the server and which side the client, or does it really matter? Finally I wonder what would be the best way to format the data to be sent. I have to dig into some C code examples, to see how to deal (buffer size settings, data parsing from string, etc.) with incoming TCP data, so I do the LabVIEW side code in the required way.

 

Maybe some of you had to build such system before, so could give me some hints and good advise...

Thanks!

 

 

 

0 Kudos
Message 1 of 12
(1,566 Views)

Of course, this is also a question of speed requirement. I mean, the folks using their C application do not necessarily need to get the data that fast, at least I do not see any reason for that. So the simple and easy solution is just to create a data file from LV, which can be read from the external programs...

Still, I am still interested in "best practices" for such communication task. I might need to program something like this another time...

0 Kudos
Message 2 of 12
(1,498 Views)

hi,

how about creating shared dll from LabVIEW and call it from C ,

I have never done that but have seen simple examples.

bharath_p
LV2011
Message 3 of 12
(1,489 Views)

@bharathp10 wrote:

hi,

how about creating shared dll from LabVIEW and call it from C ,

I have never done that but have seen simple examples.


That is unfortunately not an easy and straightforward solution. A DLL gets always loaded into the process memory and therefore two applications loading the same DLL still see both their own copy of the DLL in memory, without any sharing of static variables in between them. While you can create shared memory files in such a DLL, that would be somewhat advanced programmering and unless you need real high speed sharing between applications most likely way to much overkill. Besides this can only work on the same computer.

 

TCP/IP would be always may choice for something like this unless there are specific reasons to go for something else.

Rolf Kalbermatter
Averna BV
LabVIEW ArchitectLabVIEW ChampionLabVIEW Instructor
0 Kudos
Message 4 of 12
(1,481 Views)

But normally a dll is used once for all applications, which use it?

 

Therefore, one approach would be, to create a dll in C and access it from LabView and C and store the data in the dll.

0 Kudos
Message 5 of 12
(1,465 Views)

hi LabViewTinkerer,

I don't know how to store data in dll.

I thought by creating functions in shared dll using LabVIEW for accessing  data as an alternate option to TCP,UDP or logging , . But it seems over complicated as explained by rolfk.

bharath_p
LV2011
0 Kudos
Message 6 of 12
(1,457 Views)

@LabViewTinkerer wrote:

But normally a dll is used once for all applications, which use it?

Yes the same DLL is loaded into physical memory and then mapped into the process, but...

 

Therefore, one approach would be, to create a dll in C and access it from LabView and C and store the data in the dll.


A DLL consists of so called data and code space.

The code space is loaded into one memory space and then set to read-only. This is then mapped into each process which loads the DLL.

The data space is however copied for each process in its own memory space and then mapped into the process. The static variables that a DLL uses are therefore not visible between processes as each process has its own copy of that memory. There are ways to mark static variables to be sharable so that the compiler assigns them to a shared data space instead but that is compiler specific and adds extra problems about protecting such memory from concurrent access by two or more processes. You do not want one process to read that memory while another process is busy modifying it, so you would have to add mutex protection or something like that to that variable access. All in al I don't think this is worth the hassle.

Rolf Kalbermatter
Averna BV
LabVIEW ArchitectLabVIEW ChampionLabVIEW Instructor
Message 7 of 12
(1,451 Views)
Solution
Accepted by topic author Blokk
01-29-2018 07:46 AM

I would go with a basic TCP stream. If all you are sending is an array of U16 integers than it is very straightforward. You can simply flatten it to a string and mark the "Append length" to true. The receiving side would read the length and then read length * 2 bytes of data. If you may need to have different data packets prepend a data ID to your data transmission. Clusters of basic data types flatten to string pretty nicely and map to C structs pretty closely if you need some additional data in your packets. Just remember that a LabVIEW string will end up being a 4 byte length followed by the actual characters. The C structure definition should define the string as a length and character array. You will need to determine the maximum data length and should limit the LabVIEW code to strings of the maximum length.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 8 of 12
(1,421 Views)
Solution
Accepted by topic author Blokk
01-29-2018 08:35 AM

While I won't disagree with the TCP/IP advice, I'll offer a possible alternative *if* you can accept the risk of slightly lossy data.

 

I recently put together a data server based on UDP multicasting.  Being a connectionless protocol, I didn't need to deal with the listening, timeouts, error-checking, and reconnection stuff.  The server just blasts its data and any client can come in and subscribe at any time, including more than one at a time.  It's surprisingly light on resources in our usage where only "localhost" clients connect.

 

My practice was to have the server put a u64 "packet #" into the header so clients would at least *know* if they missed a packet.  The default limit for a UDP buffer is fairly small when configuring in LabVIEW -- these utilities were very helpful to make the buffer larger.  Maybe there's a newer .NET equivalent somewhere, but I found the linked ones to work fine under Win 7 x64 and Win 10 x64.

 

 

-Kevin P

Message 9 of 12
(1,407 Views)

I'd use UDP here (and I have in the past in somewhat similar situations), but I'd like to mention that the LabVIEW-built DLL approach can work too if you use VI Server. This gets around the shared memory issue and the DLL doesn't even need to be on the same computer as the application. The DLL that you'll build in LabVIEW needs to include a functional global variable, and methods to read or write it as appropriate. Then, your LabVIEW application opens a VI Server connection to that functional global and reads and writes to it by reference. Of course you could put the functional global on the LabVIEW application side, and let your DLL establish the VI Server connection if for some reason that's easier.

Message 10 of 12
(1,362 Views)