I am writing a test executive where it needs to scan the bus for support of older (HP/Agilent 856x series) and newer (Agilent 440x and 444x series) spectrum analyzers.
The first frame looks for the newer analyzers with *IDN? then if that fails sets the boolean in the error cluster to TRUE. The next frame then uses the error cluster's boolean to decide whether an older HP analzer is connected instead using ID? query. Disclaimer: the second frame is a clone of the ID query of the 856x Initialize VI. I just want to use what already worked - no reinventing the same wheel?
But, lo and behold, it doesn't work as expected. If I have the frames in this order and connect a HP8563E the GPIB time's out error. This code works with the newer 4407 or 4440 since the *IDN? query passes and the second frame is not executed.
Now, when I move the second frame to become the first frame and run it with HP8563E the query works but will have a GPIB timeout if I have the 4407 or 4440 connected.
Long story short, how do I support both older GPIB ID? and newer IDN? in my code?
I have attached the query VI created with LV 2012.
First of all, this question is better asked in the discussion forums at http://forums.ni.com/, under LabVIEW or Instrument Control.
Caveat: I don't have either class of instrument to test with, so I'm answering somewhat blindly.
You didn't say what timed out, but I'm guessing the first VISA Read, after you've written the invalid command. Since the instrument didn't detect a valid command, it goes into an error state and doesn't return a response. So, you're waiting for 50 bytes to appear that won't be coming. When the VISA Read times out, it passes the error into the next sequence frame, which prevents the other VISA commands from executing.
So, tip #1: remove the error wire going into the second VISA Write. You want to write a new command even though the previous read failed. (Having said that, some older, ill-behaved instruments might end up in a deeper error state from the invalid command, and need to be reset. You'll just have to try this and see if it works.)
You could also try to query for the error, but I'm not sure how to best do this in a device-independent way. Perhaps others have ideas.
#2: Don't fork the VISA Reference wire in the first frame; just wire it out of the first VISA Read, through the sequence border and into VISA Write.
#3: The sequence isn't needed
#4: Don't call VISA Close.
#5: To be more consistent with other APIs, include a VISA Session in and out, and pass the GPIB address from the caller of this function.
Thanks for the fast prompt, Brian.
1. The sequence is only there for clarity some viewers that I am trying to do two things in this state.
2. I am developing a queued state-machine so this example is just part of the "equipment identification" state and I will reopen the VISA sessions later having identified what spectrum analyzer is attached in the system.
3. I added that VISA Close VI just to make sure the handles are closed. See #2. But I will remove it and see what will happen.
4. Is there a difference when I fork the VISA handle vice daisy-chaining from the last caller? The only time that the second sequence will execute is when there is an error from the previous caller - assuming the boolean is set correctly by the VISA read timeout.
Good leads though. I will definitely try them out.
Agree with what Brian said.
Here's another approach. I don't think the errors are important. Just out put the result and a flag that allows you to make decisions upstream. This approach doesn't look for a specific instrument type. The goal is to detect old vs. new and then return the actual ID. Also I suggest you allow editing the GPIB address. You should never hardcode that. Not sure if this was just a sample or the actual code.
This is just one idea of many options.
The condition is on the string array. Right-click on that node.
Also, the point of that is to filter out the strings that are bad responses. So you'll end up with an array with one element, the found ID. The idea is to try both commands and keep the one that worked.
That is really elegant, Michael.
I am currently updating an old linear code written some years ago pre-8.2 to a queued state machine framework. Trying to keep most of the code that already worked for the client. The sample is what I have been playing all day long too seek what would work with all their old and new spectrum analyzers programmatically without getting too deep in VISA low-levels. The manager asks that the operators should not even know about what is or not connected to the test executive. Therein the need to detect both old and new equipment ID.
Yes, this company have a process where only GPIB::18 or GPIB0::18 is for spectrum analyzers. It is set in stone as far as I am concerned.
I managed to re-create your sample VI below:
The VISA Read error cluster's boolean to a conditional tunnel? The only way for me to create a conditional tunnel is with a "last value" and select "conditional". Your example looks different. Can you elaborate more why I need a conditional tunnel for this to work? I don't see the output going anywhere past the for-loop nor the error cluster it is modifying.
Michael's code worked all day without a hitch! It was able to query all three types of spectrum analyzer! The "conditional" tunnel IS the solution to the empty string or "" that you would get when an equipment does not respond to either an ID? or *IDN? query. Now I understand its purpose.
If you have an equipment that doesn't respond then all you get is the boolean is set to FALSE.
Very simple yet elegant. Thank you!