LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmx Hardware Abstraction Layer

Morning all,

 

I started working on a DAQmx HAL this morning, and immediately I came across a pretty big roadblock... DAQmx Read and Write are polymorphic VIs containing like 30 options a piece, but dynamic dispatch VIs, which form the foundation of HALs, can't be polymorphic. The only two resolutions that I can think of are (1) enumerate all the VIs in the HAL and the palette set end up containing all ~30 Read VIs and ~30 Write VIs, or (2) make the Read and Write HAL VIs with variant outputs and inputs respectively, and an enum input for what data type VI to use, and convert the variant based on that input.

 

Has anyone attempted a HAL for the DAQmx functions and gained insight they could tell me, or does anyone have a 3rd way of resolving this? The two current options I've laid out both sound pretty nasty.

Redhawk
Test Engineer at Moog Inc.

Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.

0 Kudos
Message 1 of 10
(1,315 Views)

Tough one.  To a fairly large extent, the DAQmx API already *is* trying to be a HAL.  The places you're finding excess complexity seem like the same places NI probably couldn't figure out a clean way to reduce it either, given the strong datatyping inherent to LabVIEW.

 

I haven't tried this, but might there be a VIM possibility for Reads where a dummy input establishes the datatype to be returned in the output?

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 2 of 10
(1,298 Views)

I would agree with Kevin, DAQmx at the core by itself a huge HAL and that is how it can support hundreds of DAQ products over the years with a wide variety of task types.

 

I wouldn't even attempt at converting the whole DAQmx to a HAL as there are very large VI base to convert and once cannot test just every task type, property, device etc., without a large investment comparable to re-developing DAQmx itself. You can succeed if you limit yourself to a couple of task types and a bunch of commonly used APIs.

Santhosh
Soliton Technologies

New to the forum? Please read community guidelines and how to ask smart questions

Only two ways to appreciate someone who spent their free time to reply/answer your question - give them Kudos or mark their reply as the answer/solution.

Finding it hard to source NI hardware? Try NI Trading Post
0 Kudos
Message 3 of 10
(1,288 Views)

@Kevin_Price wrote:

Tough one.  To a fairly large extent, the DAQmx API already *is* trying to be a HAL.  The places you're finding excess complexity seem like the same places NI probably couldn't figure out a clean way to reduce it either, given the strong datatyping inherent to LabVIEW.

 

I haven't tried this, but might there be a VIM possibility for Reads where a dummy input establishes the datatype to be returned in the output?

 

 

-Kevin P


Unfortunately, dynamic dispatch VIs can't be inlined, and so VIMs aren't a possibility either.

Redhawk
Test Engineer at Moog Inc.

Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.

0 Kudos
Message 4 of 10
(1,281 Views)

@santo_13 wrote:

I would agree with Kevin, DAQmx at the core by itself a huge HAL and that is how it can support hundreds of DAQ products over the years with a wide variety of task types.

 

I wouldn't even attempt at converting the whole DAQmx to a HAL as there are very large VI base to convert and once cannot test just every task type, property, device etc., without a large investment comparable to re-developing DAQmx itself. You can succeed if you limit yourself to a couple of task types and a bunch of commonly used APIs.


Yeah it seems like a monumental effort to get to the desired result of a simulated interface. Not sure if the gains outweigh the development costs at this point. I'd definitely ignore any task types I don't use anywhere, if I end up carrying on with this.

 

Thanks to both of y'all for the input!

Redhawk
Test Engineer at Moog Inc.

Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.

0 Kudos
Message 5 of 10
(1,278 Views)

What's your end goal with making a HAL? Just to make the whole thing object oriented? Or do you need to combine it with other data input devices? I've done HAL's that include DAQmx as options before, but the HAL abstracts the usage of the device, not the function of the device.

 

For example, I had some really corner case serial transmission stuff once that needed some very particular timing, so I used DAQmx to bit-bang the serial transmission packets. I made that into a HAL so I could transmit serial stuff using either normal VISA (for when I didn't need hardware timing) or DAQmx (for when I did need hardware timing), but the HAL was "serial transmitter", not "digital output device". (I also made a simulated output device that just wrote the serial stream to a file, which was super useful for debugging).

0 Kudos
Message 6 of 10
(1,232 Views)

My end goal would be a choice of hardware or simulation class so that in general, apps that use DAQs can be ran/tested without the constraint of actually needing the DAQ plugged up. There wouldn't be any other hardware involved besides actual NI DAQs.

Redhawk
Test Engineer at Moog Inc.

Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.

0 Kudos
Message 7 of 10
(1,228 Views)

Ah, then in that case I'd recommend using a simulated DAQmx device unless you need to have some control over the simulated inputs and outputs, in which case you'll need to make your own.

 

I once made a HAL for a DAQmx voltage input and output that let me launch a debug window in which I could control the simulated voltages, but it was hardly a general use thing. Again, it was more like a "Position input HAL" than a "Voltage reader HAL". (To be clear, the simulated inputs didn't use DAQmx at all, it just returned controllable position data).

 

You may also want to throw a kudo on this Idea Exchange entry from... 12 years ago, or this one from 13 years ago :(. Maybe it'll get implemented one of these days!

 

Last, you may be able to use/modify this example: https://forums.ni.com/t5/LabVIEW-Development-Best/Measurement-Abstraction-Plugin-Framework-with-Opti...

 

I haven't used it myself, but it looks like it might accomplish some of what you want to do. This would be something of a reverse way to accomplish your goal. As I understand it, that framework lets you create abstract measurement "things", then you can implement specific DAQmx functions for the ones you actually need. That would let you build up your library over time with DAQmx read functions you actually use instead of having to generate literally all of them out of the gate. Since you'd otherwise have to implement the DAQmx functionality anyway, it shouldn't add much time once you've learned the framework. (Hopefully you're familiar with the Actor Framework as well).

Message 8 of 10
(1,196 Views)

@santo_13 wrote:

You can succeed if you limit yourself to a couple of task types and a bunch of commonly used APIs.


For me, this is a key point.

Since you mentioned wanting to have a DAQmx / simulated source of data, I'd say it might be amenable to a "MyDevice.lvclass" parent and children "MyHardwareDevice.lvclass", "MySimulatedDevice.lvclass", where the interface/'abstract' class (MyDevice) has a set of VIs (API) that matches what you need, not really what the hardware device (DAQmx) offers.

 

So maybe you want to read it in a specific way, have a Read.vi that outputs a 1D array of doubles (or a waveform, or whatever you need) and use the appropriate polymorphic form in the hardware, and then generate in the simulated case. Ignore all of the other DAQmx Read options. You don't get a generic reprogrammable/'configurable in any way for any output type' DAQ device, but you do get a "My Awesome XYZ Specific Measurement" with simulated or real data sources.


GCentral
Message 9 of 10
(1,168 Views)

@FireFist-Redhawk wrote:

Morning all,

 

I started working on a DAQmx HAL this morning, and immediately I came across a pretty big roadblock... DAQmx Read and Write are polymorphic VIs containing like 30 options a piece, but dynamic dispatch VIs, which form the foundation of HALs, can't be polymorphic. The only two resolutions that I can think of are (1) enumerate all the VIs in the HAL and the palette set end up containing all ~30 Read VIs and ~30 Write VIs, or (2) make the Read and Write HAL VIs with variant outputs and inputs respectively, and an enum input for what data type VI to use, and convert the variant based on that input.

 

Has anyone attempted a HAL for the DAQmx functions and gained insight they could tell me, or does anyone have a 3rd way of resolving this? The two current options I've laid out both sound pretty nasty.


Option 3 - Add one more layer. Static dispatch VIs can call dynamic dispatch VIs, so if you create a static wrapper around each dynamic VI then you can use those in your polymorphic VI.

 

Example attached, saved to LV2019 format. I only created two instance VIs, but it should give the idea.

 

Some optional things in this example:

 

  • The static instance VIs are marked private, which restricts users to only using the polymorphic VI. This was just to demonstrate that the access scope of the instance VIs can be more restrictive than the poly VI if desired. For example, this could allow you to expose the dynamic dispatch VIs themselves while keeping the static wrappers hidden if you wanted to.
  • The dynamic dispatch VIs are marked "Descendants must override". This enforces each child having a matching dynamic dispatch VI for the wrapper to call.
Message 10 of 10
(1,149 Views)