t-onoz / slave

A lightweight python package, designed to simplify instrument control.
GNU General Public License v3.0
1 stars 2 forks source link

Timeout errors on hardware controlled sweeps #2

Open JesterEE opened 7 years ago

JesterEE commented 7 years ago

I found that when measuring using the internal hardware measurement sweep triggering, it is quite easy to run into VISA timeout errors when using the pyvisa interface as the VISA backend. Here is the code that I run to set-up and execute a instrument controlled sweep:

smu = slave.agilent.b2900.B2900(slave.transport.Visa('GPIB0::20::INSTR'))  # Timeout defaults to 10s
smu.setup.sweep_source('voltage', 0, 1, 11)
smu.setup.triggering(delay=1)
smu.triggering.initiate()
smu.triggering.wait_idle()

>>> slave.transport.Visa.Timeout: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed.

To get around this, following the pyvisa documentation, I set the timeout when a B2900 object is instantiated:

smu = slave.agilent.b2900.B2900(slave.transport.Visa('GPIB0::20::INSTR', timeout=float('+inf')))

This must be done on instantiation as I have not found a way to access the base pyvisa instance of for the B2900 driver to add the timeout attribute. Maybe the transport instance for the driver (e.g. the pyvisa instance for the SMU) should be linked to the B2900 class as an attribute in the future so users can peak at the lower levels of infrastructure.

However, I'd prefer not to do this since setting an infinite timeout can hang the measurement if something else actually goes wrong. I could set this to a more realistic value given the measurement I am running ... but it would be better if the driver did that for the user when the current timeout is set too low for the measurement.

This last bit is an "enhancement request", but it may be hard to implement since the instrument doesn't report how long the sweep will take. Rather, users of the driver should just be aware this is an open issue and the work-around above has proven simple and useful.

t-onoz commented 7 years ago

Thanks for your feedback. I understand the issue but as you know implementing this would be really tough as there is no simple standard for calculating how long the measurement takes.

Maybe the best practice is to estimate the duration beforehand and manually sleep for that time, like I did in the example script (iv_differentTemps.py):

smu = slave.agilent.b2900.B2900(slave.transport.Visa('GPIB0::20::INSTR'))  # Timeout defaults to 10s
smu.setup.sweep_source('voltage', 0, 1, 11)
smu.setup.triggering(delay=1)
smu.triggering.initiate()
smu.wait_to_continue() 
time.sleep(estimated_time)
data = smu.fetch_array()

Or to repeat smu.triggering.wait_idle() several times until the Timeout exception is not raised.