07-11-2025 12:26 PM
I went away from the Perform() approach. It returned VAR and so it was easy to create edit time bugs with incompatible types from the application point of view. I switched to interfaces like IReadVoltage, defining methods like IReadVoltage Scalar (returning double and timestamp) and IReadVoltage WDT. This makes developing applications much easier for people using your design not being CLA.
07-11-2025 02:35 PM
We have several "types" of instrument in the LVOOP hierarchy that we implemented at my company.
They tend to fall in these categories:
If you intend to use mostly NI DAQs but occasional other devices, then that last "Semi-specialty" category is what I would implement the equivalent of. Leave all the setup stuff in "raw" DAQmx, but then when it comes time to extract the measurement, you can abstract it to things like "Get waveform from channel" or something along those lines, where you input a generic channel ID nonspecific to hardware and it outputs a waveform, including the units and timing data so you can create generic handlers for the output as needed.
07-13-2025 04:58 AM
@mcduff wrote:
That is what I do. I have one non-reentrant part that scans for all instruments and makes a map of device information, model, sampling rate, etc. I use the instrument alias as the key. The user enters the parameters for an Analog Input acquisition, and this non-entrant VI configures all the task parameters in the map. Once the task is configured and committed, it is sent to a reentrant VI that starts the task. This reentrant VI allows one to change the display, analysis, etc of the running task. Thus multiple devices can run at once.
I do not know if this is the correct way, but it works.
Thank you very much for your feedback! It seems that I was on the right track.
07-13-2025 05:04 AM
@Quiztus2 wrote:
I went away from the Perform() approach. It returned VAR and so it was easy to create edit time bugs with incompatible types from the application point of view. I switched to interfaces like IReadVoltage, defining methods like IReadVoltage Scalar (returning double and timestamp) and IReadVoltage WDT. This makes developing applications much easier for people using your design not being CLA.
Yeah, I have had a negative experience with using VARs, which is why I thought it would be better to store acquisition data within the classes. Good to know that my decision wasn't a bad idea after all! 🙂
07-14-2025 03:02 AM
@Shatoshi wrote:
@Quiztus2 wrote:
I went away from the Perform() approach. It returned VAR and so it was easy to create edit time bugs with incompatible types from the application point of view. I switched to interfaces like IReadVoltage, defining methods like IReadVoltage Scalar (returning double and timestamp) and IReadVoltage WDT. This makes developing applications much easier for people using your design not being CLA.
Yeah, I have had a negative experience with using VARs, which is why I thought it would be better to store acquisition data within the classes. Good to know that my decision wasn't a bad idea after all! 🙂
Can you share a class diagram regarding acquisition data. How did you make the data accessible?
07-14-2025 03:40 AM
I'm still working on it and as soon as I have a working solution, I will share it with you 🙂
07-14-2025 04:05 AM
Very often there's no need, or not even a real benefit, to putting all HW in a class hierarchy (HAL).
HALs can be really powerful, but only if the application's HW setup needs to be highly configurable
If you're not ever going to use polymorphism on the devices, there's no gain in a class hierarchy. If it's hard to 'make up' a class hierarchy, maybe you shouldn't.
Even if you're planning on doing "polymorphic magic", an interface could do that. With an interface, you can make just a few methods polymorphic and you won't have to loose your sanity thinking about a full HAL.
When making a HAL, chances are you un into multiple inheritance issues pretty fast. And other messy things like same methods returning different data types, etc..
I'd advice you to at least consider how simple things could be if you simply make a class for each device and use it in your application. Each class should of course use a library (a class) to do all the reusable things.
07-17-2025 02:16 AM - edited 07-17-2025 02:22 AM
Hello, wiebe@CARYA!
wiebe@CARYA wrote:
Very often there's no need, or not even a real benefit, to putting all HW in a class hierarchy (HAL).
HALs can be really powerful, but only if the application's HW setup needs to be highly configurable
If you're not ever going to use polymorphism on the devices, there's no gain in a class hierarchy. If it's hard to 'make up' a class hierarchy, maybe you shouldn't.
Even if you're planning on doing "polymorphic magic", an interface could do that. With an interface, you can make just a few methods polymorphic and you won't have to loose your sanity thinking about a full HAL.
When making a HAL, chances are you un into multiple inheritance issues pretty fast. And other messy things like same methods returning different data types, etc..
I'd advice you to at least consider how simple things could be if you simply make a class for each device and use it in your application. Each class should of course use a library (a class) to do all the reusable things.
I am simply trying to implement a light abstraction rather than a complex HAL for the DAQ part. I completely agree with what Kyle97330 mentioned according common devices part.
This went fine and works great for common devices like power supplies and multimeters. Things like setting max volts/amps, toggling output channels on and off, doing single measurements, all very easy to do generically and in a way that obscures the exact connection method and the commands sent.
Although after some research on the forum, I feel that it would be better to try the NI QMH pattern but with AMC (https://forums.ni.com/t5/Reference-Design-Content/Asynchronous-Message-Communication-AMC-Library/ta-...) or even the DQMH framework to achieve my goals. What do you think about that?
07-17-2025 02:37 AM
I would favor decoupling my hardware abstraction from any framework. Measurement abstraction layer could be coupled to a framework like DQMH,AF or whatever.
07-18-2025 04:43 AM
@Quiztus2 wrote:
I would favor decoupling my hardware abstraction from any framework. Measurement abstraction layer could be coupled to a framework like DQMH,AF or whatever.
I feel the same.
A HAL\HAL light\Set of drivers should have little to do with your architecture.
Of course you can facilitate your HAL\HAL light\Set of drivers to work conveniently in your architecture, but that should be mostly boilerplates around the driver hierarchy, nothing too invasive.