08-19-2022 09:08 AM - edited 08-19-2022 09:12 AM
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.
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.
08-19-2022 09:22 AM
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
08-19-2022 09:39 AM
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.
08-19-2022 09:47 AM
@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.
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.
08-19-2022 09:51 AM
@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!
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.
08-19-2022 10:39 AM
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).
08-19-2022 10:49 AM
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.
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.
08-19-2022 11:23 AM
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).
08-19-2022 02:02 PM
@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.
08-19-2022 03:58 PM
@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: