Skip to content

Commit 5b7ca69

Browse files
authored
Merge pull request #167 from sandialabs/drivers
Drivers
2 parents 4d82d79 + 9b20984 commit 5b7ca69

26 files changed

+1133
-273
lines changed

drivers_test_notebooks/demo_test_notebook.ipynb

Lines changed: 114 additions & 78 deletions
Large diffs are not rendered by default.

drivers_test_notebooks/keithley2260b_test_notebook.ipynb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,10 @@
106106
"name": "stdout",
107107
"output_type": "stream",
108108
"text": [
109+
"dict_keys(['instrument', 'debug', 'max_current', 'min_current', 'max_current_trigger_ampliutde', 'min_current_trigger_ampliutde', 'max_over_current_level', 'min_over_current_level', 'max_current_rising_slew_rate', 'min_current_rising_slew_rate', 'max_current_falling_slew_rate', 'min_current_falling_slew_rate', 'max_resistance', 'min_resistance', 'max_voltage', 'min_voltage', 'max_voltage_trigger_ampliutde', 'min_voltage_trigger_ampliutde', 'max_over_voltage_level', 'min_over_voltage_level', 'max_voltage_rising_slew_rate', 'min_voltage_rising_slew_rate', 'max_voltage_falling_slew_rate', 'min_voltage_falling_slew_rate', 'black_list_for_testing', '_output_on_delay_settings', '_output_off_delay_settings', '_output_mode_settings', '_output_settings', '_output_trigger_state_settings', '_smoothing_settings', '_current_settings', '_curret_trigger_amplitude_settings', '_over_current_level_settings', '_current_protection_state_settings', '_current_rising_slew_rate_settings', '_current_falling_slew_rate_settings', '_resistance_settings', '_voltage_settings', '_voltage_trigger_amplitude_settings', '_over_voltage_level_settings', '_voltage_rising_slew_rate_settings', '_voltage_falling_slew_rate_settings', '_transient_trigger_source_settings', '_output_trigger_source_settings', '_output_on_delay', '_output_off_delay', '_output_mode', '_output', '_output_trigger_state', '_smoothing', '_current', '_curret_trigger_amplitude', '_over_current_level', '_current_protection_state', '_current_rising_slew_rate', '_current_falling_slew_rate', '_resistance', '_voltage', '_voltage_trigger_amplitude', '_over_voltage_level', '_voltage_rising_slew_rate', '_voltage_falling_slew_rate', '_transient_trigger_source', '_output_trigger_source'])\n",
109110
"Initial state for the Keithley2260B was: [('output_on_delay', 0.0), ('output_off_delay', 0.0), ('output_mode', 'CVHS'), ('output', 'off'), ('output_trigger_state', 'off'), ('smoothing', 'low'), ('current', 0.0), ('curret_trigger_amplitude', 0.0), ('over_current_level', 29.7), ('current_protection_state', 'off'), ('current_rising_slew_rate', 0.01), ('current_falling_slew_rate', 0.01), ('resistance', 0.01), ('voltage', 0.0), ('voltage_trigger_amplitude', 0.0), ('over_voltage_level', 8.0), ('voltage_rising_slew_rate', 0.1), ('voltage_falling_slew_rate', 0.1), ('transient_trigger_source', 'BUS'), ('output_trigger_source', 'BUS')]\n",
110111
"These blacklisted settings and their corresponding values were not reset: [('_current', 0.0), ('_voltage', 0.0)]\n",
112+
"dict_keys(['instrument', 'debug', 'max_current', 'min_current', 'max_current_trigger_ampliutde', 'min_current_trigger_ampliutde', 'max_over_current_level', 'min_over_current_level', 'max_current_rising_slew_rate', 'min_current_rising_slew_rate', 'max_current_falling_slew_rate', 'min_current_falling_slew_rate', 'max_resistance', 'min_resistance', 'max_voltage', 'min_voltage', 'max_voltage_trigger_ampliutde', 'min_voltage_trigger_ampliutde', 'max_over_voltage_level', 'min_over_voltage_level', 'max_voltage_rising_slew_rate', 'min_voltage_rising_slew_rate', 'max_voltage_falling_slew_rate', 'min_voltage_falling_slew_rate', 'black_list_for_testing', '_output_on_delay_settings', '_output_off_delay_settings', '_output_mode_settings', '_output_settings', '_output_trigger_state_settings', '_smoothing_settings', '_current_settings', '_curret_trigger_amplitude_settings', '_over_current_level_settings', '_current_protection_state_settings', '_current_rising_slew_rate_settings', '_current_falling_slew_rate_settings', '_resistance_settings', '_voltage_settings', '_voltage_trigger_amplitude_settings', '_over_voltage_level_settings', '_voltage_rising_slew_rate_settings', '_voltage_falling_slew_rate_settings', '_transient_trigger_source_settings', '_output_trigger_source_settings', '_output_on_delay', '_output_off_delay', '_output_mode', '_output', '_output_trigger_state', '_smoothing', '_current', '_curret_trigger_amplitude', '_over_current_level', '_current_protection_state', '_current_rising_slew_rate', '_current_falling_slew_rate', '_resistance', '_voltage', '_voltage_trigger_amplitude', '_over_voltage_level', '_voltage_rising_slew_rate', '_voltage_falling_slew_rate', '_transient_trigger_source', '_output_trigger_source'])\n",
111113
"Reset state for the Keithley2260B was: [('output_on_delay', 0.0), ('output_off_delay', 0.0), ('output_mode', 'CVHS'), ('output', 'off'), ('output_trigger_state', 'off'), ('smoothing', 'low'), ('current', 0.0), ('curret_trigger_amplitude', 0.0), ('over_current_level', 29.7), ('current_protection_state', 'off'), ('current_rising_slew_rate', 0.01), ('current_falling_slew_rate', 0.01), ('resistance', 0.01), ('voltage', 0.0), ('voltage_trigger_amplitude', 0.0), ('over_voltage_level', 8.0), ('voltage_rising_slew_rate', 0.1), ('voltage_falling_slew_rate', 0.1), ('transient_trigger_source', 'BUS'), ('output_trigger_source', 'BUS')]\n",
112114
"Beginning tests for: Keithley2260B\n",
113115
"11 range properties found and tested out of 20 total settings found.\n",

drivers_test_notebooks/srs830_test_notebook.ipynb

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@
2222
"\n",
2323
"import pyscan as ps\n",
2424
"from pyscan.drivers.testing.auto_test_driver import test_driver\n",
25-
"from pyvisa import ResourceManager, VisaIOError\n",
26-
"from time import sleep"
25+
"from pyvisa import ResourceManager, VisaIOError"
2726
]
2827
},
2928
{
@@ -34,11 +33,20 @@
3433
},
3534
"outputs": [
3635
{
37-
"name": "stdout",
38-
"output_type": "stream",
39-
"text": [
40-
"GPIB0::8::INSTR Stanford_Research_Systems,SR830,s/n86813,ver1.07 \n",
41-
"\n"
36+
"ename": "VisaIOError",
37+
"evalue": "VI_ERROR_RSRC_BUSY (-1073807246): The resource is valid, but VISA cannot currently access it.",
38+
"output_type": "error",
39+
"traceback": [
40+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
41+
"\u001b[1;31mVisaIOError\u001b[0m Traceback (most recent call last)",
42+
"Cell \u001b[1;32mIn[2], line 6\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[38;5;66;03m# print(rs)\u001b[39;00m\n\u001b[0;32m 5\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m r \u001b[38;5;129;01min\u001b[39;00m rs:\n\u001b[1;32m----> 6\u001b[0m res \u001b[38;5;241m=\u001b[39m rm\u001b[38;5;241m.\u001b[39mopen_resource(r)\n\u001b[0;32m 7\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m: \n\u001b[0;32m 8\u001b[0m name \u001b[38;5;241m=\u001b[39m res\u001b[38;5;241m.\u001b[39mquery(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m*IDN?\u001b[39m\u001b[38;5;124m'\u001b[39m)\n",
43+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\pyvisa\\highlevel.py:3292\u001b[0m, in \u001b[0;36mResourceManager.open_resource\u001b[1;34m(self, resource_name, access_mode, open_timeout, resource_pyclass, **kwargs)\u001b[0m\n\u001b[0;32m 3286\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m present:\n\u001b[0;32m 3287\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[0;32m 3288\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[38;5;124m is not a valid attribute for type \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 3289\u001b[0m \u001b[38;5;241m%\u001b[39m (key, res\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m)\n\u001b[0;32m 3290\u001b[0m )\n\u001b[1;32m-> 3292\u001b[0m res\u001b[38;5;241m.\u001b[39mopen(access_mode, open_timeout)\n\u001b[0;32m 3294\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m key, value \u001b[38;5;129;01min\u001b[39;00m kwargs\u001b[38;5;241m.\u001b[39mitems():\n\u001b[0;32m 3295\u001b[0m \u001b[38;5;28msetattr\u001b[39m(res, key, value)\n",
44+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\pyvisa\\resources\\resource.py:281\u001b[0m, in \u001b[0;36mResource.open\u001b[1;34m(self, access_mode, open_timeout)\u001b[0m\n\u001b[0;32m 277\u001b[0m logger\u001b[38;5;241m.\u001b[39mdebug(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m - opening ...\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_resource_name, extra\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_logging_extra)\n\u001b[0;32m 278\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_resource_manager\u001b[38;5;241m.\u001b[39mignore_warning(\n\u001b[0;32m 279\u001b[0m constants\u001b[38;5;241m.\u001b[39mStatusCode\u001b[38;5;241m.\u001b[39msuccess_device_not_present\n\u001b[0;32m 280\u001b[0m ):\n\u001b[1;32m--> 281\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msession, status \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_resource_manager\u001b[38;5;241m.\u001b[39mopen_bare_resource(\n\u001b[0;32m 282\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_resource_name, access_mode, open_timeout\n\u001b[0;32m 283\u001b[0m )\n\u001b[0;32m 285\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m status \u001b[38;5;241m==\u001b[39m constants\u001b[38;5;241m.\u001b[39mStatusCode\u001b[38;5;241m.\u001b[39msuccess_device_not_present:\n\u001b[0;32m 286\u001b[0m \u001b[38;5;66;03m# The device was not ready when we opened the session.\u001b[39;00m\n\u001b[0;32m 287\u001b[0m \u001b[38;5;66;03m# Now it gets five seconds more to become ready.\u001b[39;00m\n\u001b[0;32m 288\u001b[0m \u001b[38;5;66;03m# Every 0.1 seconds we probe it with viClear.\u001b[39;00m\n\u001b[0;32m 289\u001b[0m start_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n",
45+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\pyvisa\\highlevel.py:3217\u001b[0m, in \u001b[0;36mResourceManager.open_bare_resource\u001b[1;34m(self, resource_name, access_mode, open_timeout)\u001b[0m\n\u001b[0;32m 3188\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mopen_bare_resource\u001b[39m(\n\u001b[0;32m 3189\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m 3190\u001b[0m resource_name: \u001b[38;5;28mstr\u001b[39m,\n\u001b[0;32m 3191\u001b[0m access_mode: constants\u001b[38;5;241m.\u001b[39mAccessModes \u001b[38;5;241m=\u001b[39m constants\u001b[38;5;241m.\u001b[39mAccessModes\u001b[38;5;241m.\u001b[39mno_lock,\n\u001b[0;32m 3192\u001b[0m open_timeout: \u001b[38;5;28mint\u001b[39m \u001b[38;5;241m=\u001b[39m constants\u001b[38;5;241m.\u001b[39mVI_TMO_IMMEDIATE,\n\u001b[0;32m 3193\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Tuple[VISASession, StatusCode]:\n\u001b[0;32m 3194\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Open the specified resource without wrapping into a class.\u001b[39;00m\n\u001b[0;32m 3195\u001b[0m \n\u001b[0;32m 3196\u001b[0m \u001b[38;5;124;03m Parameters\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 3215\u001b[0m \n\u001b[0;32m 3216\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m-> 3217\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mvisalib\u001b[38;5;241m.\u001b[39mopen(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msession, resource_name, access_mode, open_timeout)\n",
46+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\pyvisa\\ctwrapper\\functions.py:1850\u001b[0m, in \u001b[0;36mopen\u001b[1;34m(library, session, resource_name, access_mode, open_timeout)\u001b[0m\n\u001b[0;32m 1846\u001b[0m out_session \u001b[38;5;241m=\u001b[39m ViSession()\n\u001b[0;32m 1848\u001b[0m \u001b[38;5;66;03m# [ViSession, ViRsrc, ViAccessMode, ViUInt32, ViPSession]\u001b[39;00m\n\u001b[0;32m 1849\u001b[0m \u001b[38;5;66;03m# ViRsrc converts from (str, unicode, bytes) to bytes\u001b[39;00m\n\u001b[1;32m-> 1850\u001b[0m ret \u001b[38;5;241m=\u001b[39m library\u001b[38;5;241m.\u001b[39mviOpen(\n\u001b[0;32m 1851\u001b[0m session, resource_name, access_mode, open_timeout, byref(out_session)\n\u001b[0;32m 1852\u001b[0m )\n\u001b[0;32m 1853\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m out_session\u001b[38;5;241m.\u001b[39mvalue, ret\n",
47+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\pyvisa\\ctwrapper\\highlevel.py:226\u001b[0m, in \u001b[0;36mIVIVisaLibrary._return_handler\u001b[1;34m(self, ret_value, func, arguments)\u001b[0m\n\u001b[0;32m 223\u001b[0m \u001b[38;5;66;03m# Set session back to a safe value\u001b[39;00m\n\u001b[0;32m 224\u001b[0m session \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m--> 226\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandle_return_value(session, ret_value)\n",
48+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\pyvisa\\highlevel.py:251\u001b[0m, in \u001b[0;36mVisaLibraryBase.handle_return_value\u001b[1;34m(self, session, status_code)\u001b[0m\n\u001b[0;32m 248\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_last_status_in_session[session] \u001b[38;5;241m=\u001b[39m rv\n\u001b[0;32m 250\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m rv \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m--> 251\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m errors\u001b[38;5;241m.\u001b[39mVisaIOError(rv)\n\u001b[0;32m 253\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m rv \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39missue_warning_on:\n\u001b[0;32m 254\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m session \u001b[38;5;129;01mand\u001b[39;00m rv \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ignore_warning_in_session[session]:\n",
49+
"\u001b[1;31mVisaIOError\u001b[0m: VI_ERROR_RSRC_BUSY (-1073807246): The resource is valid, but VISA cannot currently access it."
4250
]
4351
}
4452
],

pyscan/drivers/instrument_driver.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ def __init__(self, instrument, debug=False):
3838
else:
3939
self.instrument = instrument
4040

41+
try:
42+
inst_str = str(type(self.instrument))
43+
self._driver_class = inst_str.split("'")[1].split(".")[-1]
44+
except Exception:
45+
pass
46+
4147
self.debug = debug
4248

4349
self._instrument_driver_version = '0.2.0'
@@ -186,7 +192,7 @@ def get_instrument_property(self, obj, settings, debug=False):
186192

187193
if not obj.debug:
188194
value = obj.query(settings['query_string'])
189-
assert type(value) is str, ".query method for instrument {} did not return string".format(obj)
195+
assert isinstance(value, str), ".query method for instrument {} did not return string".format(obj)
190196
value = value.strip("\n")
191197

192198
if ('values' in settings) and ('indexed_' not in settings) and ('dict_' not in settings):
@@ -265,9 +271,15 @@ def set_range_property(self, obj, new_value, settings):
265271

266272
assert len(rng) == 2, "range setting requires 2 values"
267273
for val in rng:
268-
assert (type(val) is int) or (type(val) is float), "range settings must be integers or floats"
274+
assert (isinstance(val, int)) or (isinstance(val, float)), "range settings must be integers or floats"
269275
err_string = "range values must be integers or floats"
270-
assert (type(new_value) is int) or (type(new_value) is float) or (type(new_value) is np.float64), err_string
276+
assert (
277+
isinstance(
278+
new_value, int)) or (
279+
isinstance(
280+
new_value, float)) or (
281+
isinstance(
282+
new_value, np.float64)), err_string
271283

272284
if rng[0] <= new_value <= rng[1]:
273285
if not self.debug:
@@ -277,7 +289,8 @@ def set_range_property(self, obj, new_value, settings):
277289
setattr(obj, '_' + settings['name'],
278290
settings['write_string'].format(new_value))
279291
else:
280-
assert False, "Range error: {} must be between {} and {}".format(settings['name'], rng[0], rng[1])
292+
assert False, "Range error: {} must be between {} and {}, cannot be {}".format(
293+
settings['name'], rng[0], rng[1], new_value)
281294

282295
def set_indexed_values_property(self, obj, new_value, settings):
283296
'''
@@ -301,7 +314,7 @@ def set_indexed_values_property(self, obj, new_value, settings):
301314

302315
values = settings['indexed_values']
303316

304-
if (type(new_value) is int) or (type(new_value) is float) or (type(new_value) is str):
317+
if (isinstance(new_value, int)) or (isinstance(new_value, float)) or (isinstance(new_value, str)):
305318
pass
306319
else:
307320
assert False

0 commit comments

Comments
 (0)