07-18-2024 03:46 AM
I am stuck with the following scenario and I am sure that you also ran into it. Let's assume I have two different sensors to read the voltage from every 10 ms.
I could do this with 2 distinct voltmeters, but also using a multichannel voltmeter or an oscilloscope.
How would could I design my HAL, that my multi channel device mimics 2 distinct single channel devices.
For this assume the following actions for reading the sensors:
init voltmeter1
init voltmeter2
start voltmeter1
start voltmeter2
read voltage voltmeter1
read voltage voltmeter2
read voltage voltmeter1
read voltage voltmeter2
...
stop voltmeter1
stop voltmeter2
But actually there is just e.g. a multichannel oscilloscope in the background. Who ran also into this?
07-18-2024 09:01 AM
I don't think you can do that without any by reference (or global) resource.
The simplest would be to make a multi channel device and make it put it's data in a global (functional global, queue (named, bleh), etc.).
Better would be to make a multi channel device, and give it a method to get a reference to the data (e.g. queue (not a named one!), DVR). Fake single channel devices then need to get a hold on this reference, e.g. with a set method. This depends on how you instantiate your devices...
If instantiation is done with strings, it would be hard to avoid some named global. It can be done though. For instance, all devices could have a 'publish' method, that's always called. The published resources are collected in a map[name vs resource]. All devices also (optionally) implement a subscribe method, that can get a reference to shared data (any kind, better put it in a class so you can change and\or extend) by name.
Of course you might have to somehow make the first single channel device 'spawn' a multi device... Or at least make sure it's there.
07-18-2024 10:07 AM
What I figured out during my last major overhaul of my HAL is that I need 2 types of classes: device and instrument. The way I defined them is the device is the full equipment (ex DMM, power supply mainframe) and the instrument is a measurement part of the device (ex a channel on the DMM, a power supply module). I have my HAL call into the instrument (I use a map lookup so I can name my instruments). The instrument has a DVR to the device to handle the communications.
This is kind of a mess at the middle layer, but it makes things quite easy at the application and instrument driver layers.
07-18-2024 03:28 PM
I added my physical device object as private data to a GOOP4 DVR class. I haven't tested it, but this should give me a proper physical device ref.
Then I created 'Virtual Instruments', which hold a name, a channel and a ref to the initialized physical device.
From there on I could treat the Virtual Instruments, as they would be physicals, BUT I am aware that some physical devices are not able to
check their running status. So I can't avoid starting, stopping ... the physical device more than once.
So then I thought about having some kind of 'Instrument Manager' , which would handle Start/Stop/Destroy by having a Mapping between virtual and physical devices.
Maybe a Factory Pattern could produce something generic for initialization, but so far this is nuts.
07-18-2024 10:02 PM
@Quiztus2 wrote:Maybe a Factory Pattern could produce something generic for initialization, but so far this is nuts.
And hence a universal HAL is complex and always involves some tradeoffs.
07-19-2024 07:23 AM
@santo_13 wrote:
@Quiztus2 wrote:Maybe a Factory Pattern could produce something generic for initialization, but so far this is nuts.
And hence a universal HAL is complex and always involves some tradeoffs.
The tradeoff is your sanity 😂.
Iff a universal HAL was feasible, there would be at least one already. 🦄
Even if there is one, it will be so complex people won't understand, use or like it...
Make a HAL that fits your needs, or maybe a tiny bit more (anticipating the future). That is hard enough...
07-19-2024 07:31 AM
@Quiztus2 wrote:
Maybe a Factory Pattern could produce something generic for initialization, but so far this is nuts.
Welcome to the fun that is creating a HAL. All you are doing is moving complication around. You make the HAL itself complex in the hopes of simplifying the interfaces between the application and the instrument.
07-19-2024 07:05 PM - edited 07-19-2024 07:08 PM
You could do something like have the "multi-channel" device create two instances that each act like an independent channel
But under the hood share a common resource (possibly with something like a DVR to prevent concurrent access). This would let you preserve substantial parts of code designed for single channels. For closing refs, you could use ref counting within whatever shared data (I know I made 2 channels with names 0 and 1, I should only close the HW ref when both have closed).
07-20-2024 02:02 AM
I like the ref counting
07-22-2024 01:35 PM - edited 07-22-2024 01:36 PM
For the sake of completeness. This is what I came finally up with. I added a class which manages the physical instruments and a mapping between targets(sensors or actuators).