LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Access waveform data passed into a DLL

Solved!
Go to solution

Hi, 

 

I'm working on a LabVIEW application that processes 32 channels of analog inputs, continuous data streams, at 2MS/s each channel. This application has a DLL embedded to improve the large array handling performance in LabVIEW. I originally fed the DLL with a 2D double array returned by DAQmx Read VI, and that worked well on a high performance embedded controller. However, the new requirement is, I need to process the timestamps as well from each AI Read call, and therefore I need to feed the DLL with the waveform data returned from DAQmx Read. The waveform output data contains the timestamps I need.

 

The problem is, I don't see an easy way to access the waveform data inside the DLL (developed using Visual Studio C++). The waveform data type appears to be a C++ class, and that sounds like I need to add considerable amount of code to be able to retrieve the data inside of the waveform class.

 

My question is, does LabVIEW naturally support the waveform data access in a DLL and whether there're sample code? I understand, I can alternatively process the waveform data outside of the DLL and feed the DLL with the array component in the waveform data. However, I have concerns as to whether the performance will be considerably affected.

 

Thanks!

 

Donghui Yin

0 Kudos
Message 1 of 7
(3,281 Views)
The waveform data type is nothing more than a cluster with a start time (t0), a time increment (dt), and a y array. You can use the Get Waveform Components function and pass each separately to your dll.

I'm wondering whether your concerns about array handling in a LabVIEW is simply not understanding LabVIEW, if you are not familiar with the basic data types.
0 Kudos
Message 2 of 7
(3,275 Views)

Thanks for your reply.

 

What you suggested is exactly what I did for a simpler 2-channel configuration. However, that implementation (i.e. use Get function to retrieve the timestamp and the array components) doesn't work for the 32-channel configuration, as the amount of data acquired in one second is enormous: 2MS x 8 bytes/sample x 32 = 512 MB (i.e. faster than the PCI/PXI bus can handle).

 

Added to this amount data involved is the need to construct a 2D array (dbl) from an array of wavefrom data so that I can feed the DLL elegantly with one input. As far as I know, LabVIEW is not efficient in handling large arrays, and that was my motivation to interface the DLL with an array of waveforms and process the waveform datatype within the DLL using C/C++.

 

Regarding the interfacing to an external code (DLL), NI documentation has this note:

 

"Note Waveforms, digital waveforms, and digital tables can be passed through shared
libraries but accessing the data inside the shared libraries is not supported at this time"

 

from "Using External Code in LabVIEW" manual on Page 2-7 (http://www.ni.com/pdf/manuals/370109b.pdf)

 

This is the question I'd like to have you or NI Support to provide additional information, as that will help me to decide whether I should find an alternative way to obtain timestamps.

 

Thanks again.

0 Kudos
Message 3 of 7
(3,248 Views)
So, according to your math, your acquisition won't work from the very beginning since the data is too large to transfer from the pci/pxi bus. You are saying that you have a device that just doesn't work so that is a silly argument.

LabVIEW memory management can be very efficient but it doesn't sound like you even tried and you haven't said what sort of processing you need to do to the data.
0 Kudos
Message 4 of 7
(3,239 Views)

Sorry for the incomplete design details. If you're interested, I used PXIe cards, not PXI. Hence I don't have a PXI bandwidth issue. The particular help I need at this time is the the notes from "Using External Code in LabVIEW" manual on Page 2-7:

 

"Note Waveforms, digital waveforms, and digital tables can be passed through shared 
libraries but accessing the data inside the shared libraries is not supported at this time"

 

Thanks.

0 Kudos
Message 5 of 7
(3,235 Views)
Solution
Accepted by doy

@doy wrote:

Sorry for the incomplete design details. If you're interested, I used PXIe cards, not PXI. Hence I don't have a PXI bandwidth issue. The particular help I need at this time is the the notes from "Using External Code in LabVIEW" manual on Page 2-7:

 

"Note Waveforms, digital waveforms, and digital tables can be passed through shared 
libraries but accessing the data inside the shared libraries is not supported at this time"

 

Thanks.


I think the text is pretty clear! There exists no documented API to access the interna of Waveform data inside an external code module. The datatype generated by the Call Library Node for such a parameter is HWAVE or something, indicating it is an opaque handle whose implementation details are private to LabVIEW. Since there is no documented API to access the interna of this datatype there is simply no way to access it.

 

And I haven't seen any exported functions in the LabVIEW executable that I could easily connect with the Waveform dataype. Even if I had, we still wouldn't know the prototype (aka parameter list and types) of these functions.

 

Your only viable solution is to work with supported datatypes. Either passing the C array data pointer to your C code, or optionally the LabVIEW native datatype (array handles). Anything else would require reverse engineering by disassembly, both a very time consuming as well as legally questionable approach. And whatever you would find out that way I would be very hesitant to use in anything that smells, walks or crawls like a real world application, since you can not be sure that your findings will work for all and every situation. Also it is likely that your findings will depend on certain attributes that might change between LabVIEW versions.

 

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 7
(3,228 Views)

as the amount of data acquired in one second is enormous: 2MS x 8 bytes/sample x 32 = 512 MB (i.e. faster than the PCI/PXI bus can handle).

It is a comon mistake to use waveform of double type for large data!

 

Use a waveform of native data type instead. Mostly, int16. And do scaling as late as possible. For this I added a cluster (as variant) to the waveform attribute containing scale and offset for later displaying. Calculate with the native data type and scale/offset struct until your data amount has decreased, then you can safely convert to a double (or better single) type waveform.

 

For even more performance, take the data as one single int16 array and keep the interleaves. That way, data from the PCI/PCIe/USB card is not needed to de-interleave inside LabVIEWs get_data node, which is time-consuming and (IMHO) single-threaded. Create an array of structs that desribes first_index and add_index for each signal. (You must find right values yourself by try&error, sorry. It depends on your A/D card arrangement.) Make calculations using this descriptor, peeking each value using that information out of that int16 array using loops, and make these loops multi-threaded according to your processor count and processing amount. (Never copy that huge array! Treat it as read-only.) As you don't twiddle with waveforms anymore for ultra-fast data access, you can put these calculation steps into a DLL.

 

I did that way for investigating a tool-machine 6-axis controller (2 phases of voltage and current each), its power supply (3 phases of voltage and current), the output of position measurement devices, and some extra power consumers (2 phases of current each). The first calculation step calculated power values, distortion, position precision and linearity etc. out of input samples, with 200000 samples at 2 MSa/s reducing sample rate down to 1 kSa/s resp. 100 samples per channel and packet. (The number of channels increased due to the multiple calculated outputs.) That output can then easily converted to a single or double waveform array for further processing or logging into a file.

 

0 Kudos
Message 7 of 7
(2,914 Views)