PA-Paul Posted May 20, 2009 Report Share Posted May 20, 2009 Hi All, I'm developing some software to control a measurement system comprising of (amongst other things) a tuneable laser. The slight problem I have is that I want the same software to be compatible with different lasers (at present I have 3 different lasers I may want to use with the system). I wanted to use a plugin type architecture, so that I can simply select which type of laser is currently connected and everything will work happily. I've started to implement this by having a set of "actions" that I want the laser to perform (such as switch on/off, set wavelength etc etc.) and having a generic VI for each action which calls the appropriate driver depending on which laser is being used, and this works to an extent. The problem is that I need to perform a rapid sweep of the laser channels, which is typically achieved by running the "set wavelength" vi in a loop with an incrementing input to the wavelength value. Doing this with the "plugin" type VIs takes much much longer than if the driver is "hard written" into the application. I presume this is because of the continual opening and closing of the VI reference, is there a way round this? Is the plugin architecture really the way to go in this case? Any thoughts would be greatly appreciated Cheers Paul Quote Link to comment
gb119 Posted May 20, 2009 Report Share Posted May 20, 2009 QUOTE (Ic3Knight @ May 19 2009, 02:40 PM) Hi All,I'm developing some software to control a measurement system comprising of (amongst other things) a tuneable laser. The slight problem I have is that I want the same software to be compatible with different lasers (at present I have 3 different lasers I may want to use with the system). I wanted to use a plugin type architecture, so that I can simply select which type of laser is currently connected and everything will work happily. I've started to implement this by having a set of "actions" that I want the laser to perform (such as switch on/off, set wavelength etc etc.) and having a generic VI for each action which calls the appropriate driver depending on which laser is being used, and this works to an extent. The problem is that I need to perform a rapid sweep of the laser channels, which is typically achieved by running the "set wavelength" vi in a loop with an incrementing input to the wavelength value. Doing this with the "plugin" type VIs takes much much longer than if the driver is "hard written" into the application. I presume this is because of the continual opening and closing of the VI reference, is there a way round this? Is the plugin architecture really the way to go in this case? LabVIEW Classes are a really neat way to handle this sort of thing. Write a base class that defines the generic functions you want to do - e.g. set wavelength, turn on/off laser etc. These are implemented as dynamic dispatch method vis. The method vis in this class don't actually do anything at all - they are just defining the interface to a general laser. Then write child classes for each type of laser you want use that provide methods that override the dynamic dispatch vis for the parent 'generic laser' class. In your main program you write everything using the generic laser class vi's but at some point have some code that selects the correct child class for whichever laser you are using on that experiment. This can be as simple as a case structure with a class constant in each case, alternatively you can also use the node that generates a default value from a class file to load the child class from disc at runtime. I use this sort of architechture for working with my instruments - I have a very generic "instrument" class that provides vi's that wrap VISA functions but with additional debugging code that I can turn on and off, a layer of classes that define APIs for different type of instruments - e.g. source meters, temperature controllers, lockins, magnet powersupplies and then a layer of classes that implement the interface for specific instruments (or even combinations of instruments). This is sort of reinventing the wheel in that it duplicates IVI drivers, but (a) I know exactly what commands are being sent to the instrument and (b) I get to design the interface layer. Quote Link to comment
PA-Paul Posted May 20, 2009 Author Report Share Posted May 20, 2009 Thanks for the hint. My only minor issue being that I've never worked with classes at all and don't really know where to start... I'm a physicist by training and a LabVIEW coder by need (although I enjoy it too, which helps!). Are there any tutorials/resources which explain how to use/write classes? this is something which may also prove useful for another project I'm about to start on, which involves writing control software for a measurement system which will have motion controllers, function generators, scopes etc etc which may also be different "system to system". But if its something that's going to take months to learn how to do properly, I may have to find a simpler solution for the short term. any advice greatly welcomed! Cheers Paul Quote Link to comment
ShaunR Posted May 20, 2009 Report Share Posted May 20, 2009 QUOTE (Gavin Burnell @ May 19 2009, 04:57 PM) I use this sort of architechture for working with my instruments - I have a very generic "instrument" class that provides vi's that wrap VISA functions but with additional debugging code that I can turn on and off, a layer of classes that define APIs for different type of instruments - e.g. source meters, temperature controllers, lockins, magnet powersupplies and then a layer of classes that implement the interface for specific instruments (or even combinations of instruments). This is sort of reinventing the wheel in that it duplicates IVI drivers, but (a) I know exactly what commands are being sent to the instrument and (b) I get to design the interface layer. This is exactly what I was trying (rather failing) to describe on the "Exterfaces" thread. Quote Link to comment
PA-Paul Posted May 20, 2009 Author Report Share Posted May 20, 2009 I was just wondering... how does the "classes" approach lend itself to application building and distributing (i.e. generating exe files etc)? One of the reasons we're looking at using the "call by ref" plugin approach is that we want a top level architecture which (in the case of the new project I'm about to start work on, rather than the tuneable laser I mentioned above) would allow us to add support for new/specific hardware (function generators etc) further down the line and simply provide end users with a new "driver" set for the hardware they're using. If I were to use the classes approach, would I have to include the "drivers" for every type of hardware that might be used? Or could I just supply the ones most appropriate for the specific configuration? Cheers for the info! Paul Quote Link to comment
Daklu Posted May 20, 2009 Report Share Posted May 20, 2009 QUOTE (ShaunR @ May 19 2009, 10:23 AM) This is exactly what I was trying (rather failing) to describe on the "Exterfaces" thread. Not true... you did a fine job explaining... *ahem*... polyconfigurism. :laugh: QUOTE (Ic3Knight @ May 19 2009, 11:48 AM) Thanks for the hint. My only minor issue being that I've never worked with classes at all and don't really know where to start... If you're under a tight deadline, stick with what you know. You will spend a lot of extra time learning the ins and outs of Labview classes. (Moreso if you're not familiar with OOP concepts at all.) You will also spend extra time trying to design a class hierarchy that works. On my first significant OOP project I had to do major rewrites at least twice and lots of in-between refactoring. That's the cost of learning when you don't have an experienced developer to bounce ideas off of. QUOTE (Ic3Knight @ May 19 2009, 11:48 AM) I was just wondering... how does the "classes" approach lend itself to application building and distributing (i.e. generating exe files etc)? Classes compile into executables just fine. It takes extra work to make classes available to other programming languages via a dll though. QUOTE (Ic3Knight @ May 19 2009, 11:48 AM) If I were to use the classes approach, would I have to include the "drivers" for every type of hardware that might be used? Or could I just supply the ones most appropriate for the specific configuration? You only have to supply the drivers for the instruments that are used on that specific test station. If you change instruments you need to make sure the correct drivers are available for that instrument. QUOTE (Ic3Knight @ May 19 2009, 11:48 AM) One of the reasons we're looking at using the "call by ref" plugin approach is that we want a top level architecture which (in the case of the new project I'm about to start work on, rather than the tuneable laser I mentioned above) would allow us to add support for new/specific hardware (function generators etc) further down the line and simply provide end users with a new "driver" set for the hardware they're using. Here are some blunders I made tidbits I learned from my last project that I believe are good rules for those learning LVOOP: Don't try to make a general class hierarchy that will be universally usable across projects. Focus on a class hierarchy that works for this application. In time, if you find you're using the same classes over and over again then you can consider releasing them as internal shared code. Decide what your instrument class' methods should be based on what the application needs, not on what the instrument can do. For example, if your application only ever needs the function generator to output a square waveform at 10 kHz, your Function Generator class doesn't need Set Waveform or Set Frequency methods. You can setup the instrument when you Open it. Hardware-based class hierarchies can easily get very complicated so figure out what combinations of instruments are likely to be used. For example, suppose your application uses 3 multimeters to do measurements so you implemented a Multimeter class in your code. Down the road they decide they want to replace the multimeters with 2 ammeters and a voltmeter to reduce cost. Can your application handle that? Conversely, suppose you write the application with an Ammeter class and a Voltmeter class, but later want to be able to swap in multimeters. How does that fit in your framework? If all your instruments used string-based commands, you might want to take a look at the 'configuration file based polymorphism emulation' architecture ShaunR talks about in the Exterfaces thread. (He doesn't like it when I call it 'polyconfigurism.' ) Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.