05-07-2024 12:51 PM
Developing a modular data acquisition system the would use multiple types of daq hardware. Some of the hardware is NI (cDaq & PXI) and some of it is LabJack (T7). My goal is to design a universal daq program which would allow the use of hardware abstraction to use any type of hardware but I am having trouble implementing my design. The issue I am having is trouble creating an class hierarchy that uses different initialization routines and communication protocol (Ni DAQmx task vs LabJack handle) for the hardware. Does anyone have design patter to solve this issue? Am I going about this is the wrong way?
John
05-07-2024 03:31 PM
John,
This is a problem that I suspect every veteran LabVIEW programmer has struggled with at some point in time, myself included.
Each design I've looked at has trade offs; however, the closest I've come to a true HAL implementation used a JSON file to configure each instrument. A single JSON file included instrument initialization parameters and pointed to the LVClass name. So, startup would go something like this:
In the end, this design worked fairly well... but the resulting configuration JSON became unwieldly to set up as well as drawbacks in the timing/synchronization side of things. It also didn't allow for any type of closed-loop control for each engine, though the FIFO probably could have been abused to allow for some changes.
Now that I've given you my best answer, here's my best advice.
Give up and find a COTS solution from one of the companies out there. Doing a HAL right that is long-term supportable and sustainable is a much, much bigger effort than I realized with my first attempt. Or second attempt. Or third. There are a huge number of little "gotcha's". If you're anything like me it'll become an all-consuming pet project moving from tester to tester until it is such a mess that I barely understand it and any other engineer coming in has zero hope of supporting my code at a future date.
05-07-2024 07:02 PM
My company has done this and we have been pretty successful with some things that are easy to make universal (power supplies and such) but other things are a lot harder. Making DAQs universal is one of those things that was in the "much harder" category.
In the end we ended up with one class that was "Simple DAQ" essentially, that basically didn't do anything that involved precise timing, triggering, or waveforms. It could read or write Boolean values for the DIO channels, and read and write analog values to the analog in and out channels, but only a single value at a time per channel, and always untriggered. We implemented this for DAQmx devices as well as a few other non-NI devices.
For anything that needed to do a complex DAQ task, the HAL basically was a way to wrap a DAQmx reference in a LabVIEW class wire, but when it came time to do the fancy stuff we'd just pull out the DAQmx reference and use it directly. For NI hardware the DAQmx wire is already a HAL for the most part, and for non-NI hardware the effort it would take to allow full use of all NI's DAQmx features but also support other devices transparently was a massive undertaking that we judged would not be worth the effort.
05-07-2024 07:08 PM
Though technically possible, it requires substantial effort, maintenance, and scalability, which are the challenges.
It is easier to fix on to one vendor than try to invest in hardware abstraction.
05-07-2024 09:09 PM
Back (a decade ago) when NI was doing "traveling Road Shows", I attended a one-day event in Rochester that was an early introduction to LVOOP that was all about building a HAL using LVOOP. As I remember, it looked reasonably sensible. I suspect one could find this presentation with a suitable Web search -- it might even have been an NI Week Presentation ...
Bob Schor
05-08-2024 07:16 AM
@BowenM wrote:
Each design I've looked at has trade offs; however, the closest I've come to a true HAL implementation used a JSON file to configure each instrument. A single JSON file included instrument initialization parameters and pointed to the LVClass name.
As of now, I landed at the same place. I have no more to add than what you already posted.
@BowenM wrote:
Now that I've given you my best answer, here's my best advice.
Give up and find a COTS solution from one of the companies out there.
I would invest some time to look into FlexLogger. You can create a plugin to handle the LabJack channels and put it all in a single project. I have only briefly played with FlexLogger (a free "lite" version was just released), but it looks promising.