Search code examples
pythonsessioncomtypes

Access an IVI session from another program


I'm using Python comtypes to get measurement device readings with IVI. Since opening a session with the device is time consuming, and I need to read the value hundreds of times, I'm trying to keep the session "alive" on a program that keeps running - while polling on the results as needed.

Can it be done?

The code I'm using now (both creating the IVI object AND reading):

import argparse
from comtypes.client import CreateObject

# reading the command line arguments
parser = argparse.ArgumentParser(description='Read the DCV from M918x PXI DMM')
parser.add_argument('--VISA_ADDRESS', default='PXI9::13::0::INSTR', help='get from Keysight connection expert or NI-MAX', type=str)

args, unknown = parser.parse_known_args()             # command line arguments parsed
visa_address = args.VISA_ADDRESS        # 'PXI9::13::0::INSTR'

# Creating the object - notice the ".1"
IVI_COM_AgM918x = CreateObject("AgM918x.AgM918x.1")

# Initialize the instrument
IVI_COM_AgM918x.Initialize(visa_address, False, False, "")

# Take a DC voltage measurement with a range of 30V and a resolution of 0.01V
retval = IVI_COM_AgM918x.DCVoltage.Measure(200.0, 0.01, True)
print(retval)

# Close the instrument session
IVI_COM_AgM918x.Close()

I mean to run a program once, with the session opening:

# Creating the object - notice the ".1"
IVI_COM_AgM918x = CreateObject("AgM918x.AgM918x.1")
    
# Initialize the instrument
IVI_COM_AgM918x.Initialize(visa_address, False, False, "")

then, whenever I need a read:

# Take a DC voltage measurement with a range of 30V and a resolution of 0.01V
retval = IVI_COM_AgM918x.DCVoltage.Measure(200.0, 0.01, True)
print(retval)

Once finished, I will close the session and kill the first program.

  1. Is this the best way to do it?
  2. How to do it?

Solution

  • Create a Separate Class for the IVI Device: Instead of writing the code to manage the IVI session directly in your main script, it's a good idea to encapsulate the IVI device functionality in a separate class. This makes the code more organized and easier to manage.

    import argparse
    from comtypes.client import CreateObject
    
    class IVIDevice:
        def __init__(self, visa_address):
            self.visa_address = visa_address
            self.IVI_COM_AgM918x = CreateObject("AgM918x.AgM918x.1")
            self.IVI_COM_AgM918x.Initialize(self.visa_address, False, False, "")
    
        def read_voltage(self, range, resolution):
            retval = self.IVI_COM_AgM918x.DCVoltage.Measure(range, resolution, True)
            return retval
    
        def close(self):
            self.IVI_COM_AgM918x.Close()
    

    Use a Loop for Multiple Readings: You can create a loop to read the device values multiple times. This way, you can control the number of readings and easily reuse the same session.

    def main():
        parser = argparse.ArgumentParser(description='Read the DCV from M918x PXI DMM')
        parser.add_argument('--VISA_ADDRESS', default='PXI9::13::0::INSTR', help='get from Keysight connection expert or NI-MAX', type=str)
        args, unknown = parser.parse_known_args()
        visa_address = args.VISA_ADDRESS
    
        device = IVIDevice(visa_address)
    
        try:
            num_readings = 10  # Adjust the number of readings as needed
            for _ in range(num_readings):
                retval = device.read_voltage(200.0, 0.01)
                print(retval)
        finally:
            device.close()
    
    if __name__ == "__main__":
        main()
    

    Exception Handling: Ensure you handle exceptions properly, especially when working with external devices. Optimize the Measurement Rate: Keep in mind that reading the device hundreds of times might take a considerable amount of time.