How am I able to check which devices I'm interfacing with?

754 views Asked by At

I work at a microwave technology company and part of my job is developing software to interface with the devices we use using Python, specifically PyVISA. I'm currently trying to write a program that interfaces with several different types of devices that have different command structures, so before executing the code, I want to be able to check which type of device is connected (all use GPIB addresses). How can I go about doing this? Right now I've been trying to send identity commands using nested try/except blocks as shown below because the different devices have different identify commands:

import pyvisa as visa

address = "GPIB0::6::INSTR"
rm = visa.ResourceManager()
device = rm.open_resource(address)

try:
    device.write("*IDN?")
    identity = device.read()
except visa.errors.VisaIOError:
    try:
        device.write("I")
        device.write("STB?")
        identity = device.read()
    except visa.errors.VisaIOError:
        try:
            device.write("ID?")
            identity = device.read()
        except visa.errors.VisaIOError:
            identity = "Unknown"

print(identity)

The device I'm testing the code with requires the device.write("ID?") version of this command, however instead of returning the identity, it's returning the numerical error code. Is there a better way to implement this?

1

There are 1 answers

0
grey_ranger On

I would remove the try/except block and see exactly where the device is failing. Since you are getting a numerical error code, I'm betting the error flow is as follows:

  1. The script sends *IDN?
  2. The device doesn't recognize this command and goes into an error state.
  3. The script sends I
  4. The device is already in an error state and doesn't respond.
  5. The script queries STB?
  6. The device reports the error it logged earlier.
  7. The script interprets this response as the device name, even though it's the answer to the Status Byte query.

I find it's often better to write the identity function specifically for each device. For example: def identity_dev1() for a device that needs *IDN? and def identity_dev2() for a device that needs I and so on.

If you want a monolithic function that can do all of the above, you'll have to change the way you handle the status byte. Here's an example:

import pyvisa as visa

address = "GPIB0::6::INSTR"
rm = visa.ResourceManager()
device = rm.open_resource(address)

identity = None
try:
    device.write("*IDN?")
    identity = device.read()
except visa.errors.VisaIOError:
    device.write("*RST") # get rid of the error state and try something else
if not identity:
    try:
        device.write("ID?")
        identity = device.read()
    except visa.errors.VisaIOError:
        device.write("*RST") # get rid of error state
if not identity:
    identity = "Unknown"

In general it's better to not do extra try/except behavior over GPIB communication. Trying the wrong command takes extra time and can put the instrument in an error state. In the code above, I use the *RST command to leave the error state, but this isn't guaranteed to work on all tools. print(identity)