LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Driver Architecture Question

I'm writing drivers for a pressure calibrator and I ran into a design road block. What is the best way to go about creating VIs which can set a configuration parameter as well as read it? For example, in my case I can set pressure units, as well as read what units are currently set on the instrument. Here are a few potential ideas that I've come up with:
 
(Using the units example)
 
1. 2 separate VIs, Get Units.vi and Set Units.vi. (I'm trying to avoid this.)
2. A polymorphic Units.vi where the user can select either get or set, but only one will be shown on the palette.
3. A boolean input for get/set.
4. Including a "Read current units" selection in the enum control that contains all the selectable units. It would then be {Read Current, PSI, kPa, etc.} (I don't like this because the output will be the same enumeration without the "Read Current", and thus have to be a different data type, which seems redundant.)
 
Is there a preferred method to doing this? I'd like to make these as user friendly as possible, because I may submit them to NI. The only available drivers for this particular instrument are severely lacking in functionality.
0 Kudos
Message 1 of 14
(3,380 Views)
I would think something along the lines of #3 but with an enum for your Get/Set.  Have an input terminal with an enum that has 2 values Set and Get that feeds a case structure.  Have an input terminal that takes an enum (probably type def'd) of all of your choices to feed in when you do a Set.  Have the Get case feed out the value through to an output terminal that puts out the enum.
 
Of course feed in and through error signals and any VISA references if needed.  You may need to have a default case inside the Set case that raises an error in the event that try to Set a value but forget to wire up the choice to the input terminal.  That or make that input terminal required (which of course would require it for the Get situation as well), but the constant wired in there would be ignored as it is not needed for the Get case.
 
I've done several communication command type VI's this way.  I like the enum method because you can see on the block diagram what the command is you are trying to do, while for a boolean does a "True" mean "Get" or Set"? 
 
Attached is a sample in LV 8.2.1.
Message 2 of 14
(3,361 Views)

You could do something like this, but I would advise against it for something like this because it's ambigous and a potential source of bugs.

I would suggest creating a get and set VI for each one, just like NI does with its DAQmx Write and DAQmx Read and various other configuration options.

To save yourself work, check out any of the available object oriented implementations - OpenGOOP, dqGOOP, Sciware GOOP, Endevo GOOP, LVOOP (if you're using 8.2) or any others I may have forgot. These will allow you to create your basic functions and you just create a palette of configuration VIs.


___________________
Try to take over the world!
Message 3 of 14
(3,349 Views)

Hi Marc,

      This may be over-kill for your application, but it's a structure that works well for most devices, and might work well for yours.  Ravens Fan mentioned enums lending clarity to code,  I too [really] like enums because of this - but they also make this driver "extensible" with respect to adding new functions without breaking existing code - as long as the function-type is a typedef.  This driver also buffers the VISAResource - encapsulating it in the driver (think "object") - so there are less references to pass and less wires stretching across diagrams.  If the driver needs to "remember" what state it's in, variables can be added to "buffered" - the device-specific "attributes".  The "Enabled" boolean is very useful for debugging in the absence of actual hardware, and IMHO that having all the device-specific syntax in a single place is a good thing.  Smiley Happy

Not that you'll want to, but this structure can be wrapped, made reentrant, and called dynamically, so different devices of the same type can be substituted easily, or multiple identical devices can use exactly the same driver.

Asking "what's the best driver" might be like asking "what's the best beer", try a few and then decide! Smiley Wink

Cheers!

Message Edited by tbd on 07-27-2007 03:25 AM

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
Message 4 of 14
(3,345 Views)
Thanks for the replies.
 
I'll probably go with Ravens Fan's suggestion. I want one VI to do both, and like you said, a boolean isn't very descriptive as to what the VI is doing at first glance on the block diagram.
 
tst: I've used that in the past, but I'd like to stay away from it for instrument drivers that could be used by other people. I want them to be as straight forward as possible. Also, I agree about having two VIs for tasks like reading and writing data. However, I'm talking more about configuration parameters, like units, pressure ranges, modes of operation, etc.
 
tbd: That's an interesting design, but like I said, I want these to be very straight forward and adhere to NI's guidlines for drivers. I don't want to have one VI that has everything in it. It's not so much the "best" way of writing drivers as it is the "preferred" way.
0 Kudos
Message 5 of 14
(3,323 Views)

To some extent an Action Engine structure may be useful. Smiley Wink

While they are often billed as a way to protect data from conflits, they can also control and coordinate hardware devices as well.

You could use different actions to read the values in the various units you desire.

Just my 2 cents Smiley Happy

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 6 of 14
(3,321 Views)
Ben,
 
I was going to use your phrase "action engine" in my reply.  I had that and functional global variable in mind when I was writing it up.  But I took those words out because I wasn't using a loop with uninitialized shift registers which I think are the key distinguishing features (correct me if I'm wrong) of an action engine or FGV.  But setting it up that way could definitely add new features such as an initialize routine where, any other specific parameters (like setting the VISA reference) could be set once and would not have to be wired in on each occurrence of the sub-VI in the main program.
 
-Bill
0 Kudos
Message 7 of 14
(3,314 Views)

I use action engines all over the place, I love them. However, I'm really trying to adhere to the guidelines on this one. One thing that is required is that multiple instruments can be controlled with the drivers, so USRs and global variables should be avoided.

I'm going to use 2 enums in each VI that can read or write a configuration parameter. One for the parameter, and one for the read/write action. I think this will be the most user friendly way to go.

0 Kudos
Message 8 of 14
(3,309 Views)

Bill,

I use the term AE rather than Functional Global, or LV2 global because the same construct (single iteration loop with cases) can be used to "protect" more than just the data in a SR.

Marc,

An AE that uses dynamically instaciated AE templates can do that but .... it does get complicated.

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 9 of 14
(3,295 Views)
Yeah, but since these are just instrument drivers to send commands, I think that's a bit overkill. I appreciate all the ideas, though. Mainly I just wanted to know if there was an NI recommended way of going about the set/get VIs, because I couldn't find anything in the driver guidelines.
0 Kudos
Message 10 of 14
(3,284 Views)