def test_hislip_shared_lock(hislip_example, resource_manager: pyvisa.ResourceManager): inst1 = resource_manager.open_resource(hislip_example) inst2 = resource_manager.open_resource(hislip_example) inst3 = resource_manager.open_resource(hislip_example) # Lock inst1.lock(requested_key="foo", timeout=0) inst2.lock(requested_key="foo", timeout=1000000000) # Timeout t1 = time() with pytest.raises(pyvisa.VisaIOError) as excinfo: inst3.lock(1000, requested_key="bar") dt = time() - t1 print(f"Timeout took {dt}s") assert dt > 1.0, "Timeout occured too fast" inst1.unlock() inst2.unlock() # inst3 may lock inst3.lock(1000, requested_key="bar") inst1.close() inst2.close() inst3.close()
def test_lock(): register_resources(instruments.resources) rc = ResourceManager(visa_library="@mock") res: Resource = rc.open_resource("MOCK0::mock1::INSTR") res.lock_excl(timeout=0) res.unlock()
def test_lock_timeout(): register_resources(instruments.resources) rc = ResourceManager(visa_library="@mock") res: Resource = rc.open_resource("MOCK0::mock1::INSTR") res.write(":INSTR:CHANNEL1:VOLT 2.3") res.write(":INSTR:CHANNEL1:VOLT 2.3") def blocking_thread(res: Resource, event: Event): with res.lock_context(): event.wait() block_release: Event = Event() blocker: Thread = Thread( target=blocking_thread, args=[res, block_release], ) try: blocker.start() with raises(VisaIOError) as e: with res.lock_context(timeout=0): res.query(":INSTR:CHANNEL1:VOLT?") assert e.value.error_code == StatusCode.error_timeout finally: block_release.set() blocker.join() reply = res.query(":INSTR:CHANNEL1:VOLT?") assert reply == '2.3'
def test_read_stb(vxi11_example, resource_manager: pyvisa.ResourceManager): inst = resource_manager.open_resource(vxi11_example) status = inst.read_stb() assert status == 0 inst.close()
def test_hislip_exclusive_lock(hislip_example, resource_manager: pyvisa.ResourceManager): inst = resource_manager.open_resource(hislip_example) # Lock and unlock inst.lock_excl(25.0) inst.unlock() inst.close()
def test_query(vxi11_example, resource_manager: pyvisa.ResourceManager): inst = resource_manager.open_resource(vxi11_example) inst.read_termination = '' inst.write_termination = '' resp = inst.query("*IDN?").strip() assert resp == "Cyberdyne systems,T800 Model 101,A9012.C,V2.4" inst.close()
class Driver(): """Driver class""" def reset(self): """ Create factory reset""" self.device.write('*RST') self.log.info("Reset to factory settings successfull.") def __init__(self, gpib_address, logger): """Instantiate driver class :gpib_address: GPIB-address of spectrum analyzer, e.g. 'GPIB0::12::INSTR' Can be read out by using rm = pyvisa.ResourceManager() rm.list_resources() :logger: And instance of a LogClient """ # Instantiate log self.log = LogHandler(logger=logger) self.rm = ResourceManager() try: self.device = self.rm.open_resource(gpib_address) device_id = self.device.query('*IDN?') self.log.info(f"Successfully connected to {device_id}.") except VisaIOError: self.log.error(f"Connection to {gpib_address} failed.") # reset to factory settings self.reset() def turn_laser_off(self): """ Power off display """ self.device.write('OUTPut1:STATe 0') # temp control self.device.write('OUTPut2:STATe 0') # diode self.log.info("Laser off.") def turn_laser_on(self): """ Power on display """ self.device.write('OUTPut2:STATe 1') # temp control self.device.write('OUTPut1:STATe 1') # diode self.log.info("Laser on.") def set_current(self, amps): """ Sets current setpoint in mA :amps: """ if not 0 <= amps <= 60: self.log.error( f'Invalid current ({amps}mA). Attenuation must be between 0A and 60mA' ) self.device.write(f'SOURce1:CURRent:LEVel:AMPLitude {amps*1e-3}') self.log.info(f'Current setpoint set to {amps}mA.')
class GPIBBase(AbstractContextManager, metaclass=MetaInstrument): """ Base class for GPIB instruments. It wraps PyVisa's ResourceManager with open resources. ``GPIBBase`` also supports context managemenent (``with`` statement). Parameters ---------- addr : str Instrument address, e.g. 'GPIB::15'. kwargs Keyword arguments are passed to the pyvisa.ResourceManager.open_resource method. """ def __init__(self, addr, **kwargs): self._rm = ResourceManager() self._instrument = self._rm.open_resource(resource_name=addr, **kwargs) def __exit__(self, *exc): self.clear() self.close() super().__exit__(*exc) def clear(self): return self._instrument.clear() def close(self): self._instrument.close() self._rm.close() def write(self, *args, **kwargs): return self._instrument.write(*args, **kwargs) def read(self, *args, **kwargs): return self._instrument.read(*args, **kwargs) def query(self, *args, **kwargs): return self._instrument.query(*args, **kwargs) write.__doc__ = GPIBInstrument.write.__doc__ read.__doc__ = GPIBInstrument.read.__doc__ query.__doc__ = GPIBInstrument.query.__doc__ def wait_for_srq(self, timeout=25000): """ Wait for a serial request (SRQ) or the timeout to expire. Parameters ---------- timeout : int or None, optional The maximum waiting time in milliseconds. None means waiting forever if necessary. Raises ------ pyvisa.error.VisaIOError: if timeout has expired """ return self._instrument.wait_for_srq(timeout)
def test_lock_context(): register_resources(instruments.resources) rc = ResourceManager(visa_library="@mock") res: Resource = rc.open_resource("MOCK0::mock1::INSTR") res.write(":INSTR:CHANNEL1:VOLT 2.3") with res.lock_context(): reply = res.query(":INSTR:CHANNEL1:VOLT?") assert reply == '2.3'
def test_open_resource_unknown_resource_type(self): """Test opening a resource for which no registered class exist. """ rc = ResourceManager._resource_classes old = rc.copy() class FakeResource: def __init__(self, *args): raise RuntimeError() rc[(InterfaceType.unknown, "")] = FakeResource del rc[(InterfaceType.tcpip, "INSTR")] rm = ResourceManager() try: with self.assertLogs(level=logging.DEBUG, logger=logger): with self.assertRaises(RuntimeError): rm.open_resource("TCPIP::192.168.0.1::INSTR") finally: ResourceManager._resource_classes = old
def test_open_resource_unknown_resource_type(self, caplog): """Test opening a resource for which no registered class exist.""" rc = ResourceManager._resource_classes old = rc.copy() class FakeResource: def __init__(self, *args): raise RuntimeError() rc[(InterfaceType.unknown, "")] = FakeResource del rc[(InterfaceType.tcpip, "INSTR")] rm = ResourceManager() try: caplog.clear() with caplog.at_level(level=logging.DEBUG, logger="pyvisa"): with pytest.raises(RuntimeError): rm.open_resource("TCPIP::192.168.0.1::INSTR") assert caplog.records finally: ResourceManager._resource_classes = old
def test_hislip_clear_in_progress(hislip_example, resource_manager: pyvisa.ResourceManager): inst1 = resource_manager.open_resource(hislip_example) inst2 = resource_manager.open_resource(hislip_example) # Lock inst1.lock(requested_key="foo") # Timeout inst1.close() inst2.close()
def test_lock(vxi11_example, resource_manager: pyvisa.ResourceManager): inst1 = resource_manager.open_resource(vxi11_example) inst2 = resource_manager.open_resource(vxi11_example) # Two clients cannot lock at the same time inst1.lock_excl() with pytest.raises(pyvisa.VisaIOError) as excinfo: inst2.lock_excl(timeout=100) # Unlock client1 and check that client2 can lock inst1.unlock() inst2.lock() inst1.close() inst2.close()
def test_trigger(vxi11_example, resource_manager: pyvisa.ResourceManager): inst = resource_manager.open_resource(vxi11_example) status = inst.read_stb() assert status & 0x40 == 0 inst.assert_trigger() status = inst.read_stb() assert status & 0x40 != 0, "Failed to trigger?" inst.clear() status = inst.read_stb() assert status & 0x40 == 0 inst.close()
def __init__(self): resource_manager = ResourceManager('@py') try: self.inst = resource_manager.open_resource( resource_manager.list_resources()[0]) except: print("Could not find") self.test = True return if "ok" in self.inst.query("$BD:0,CMD:MON,PAR:BDNAME").lower(): print("Successfully connected to CAEN psu") else: sys.exit(ERROR_BOARD_NOT_FOUND)
def find_visa(): # Return the first VISA address which maps to a Rigol DS1000Z. RIGOL_IDN_REGEX = "^RIGOL TECHNOLOGIES,DS1[01][057]4Z(-S)?( Plus)?,.+$" visa_manager = ResourceManager() for visa_name in visa_manager.list_resources(): try: visa_resource = visa_manager.open_resource(visa_name) match = search(RIGOL_IDN_REGEX, visa_resource.query("*IDN?")) if match: return visa_name except VisaIOError: pass finally: visa_resource.close()
class TestFilter2(BaseTestCase): def setUp(self): """Create a ResourceManager with the default backend library. """ self.rm = ResourceManager() def tearDown(self): """Close the ResourceManager. """ self.rm.close() def _test_filter2(self, expr, *correct): resources = self.rm.list_resources(expr.split("{")[0]) ok = tuple(resources[n] for n in correct) filtered = rname.filter2( resources, expr, lambda rsc: self.rm.open_resource(rsc) ) self.assertSequenceEqual(filtered, ok) def test_filter2_optional_clause_with_connection(self): self._test_filter2( "?*::INSTR{VI_ATTR_TERMCHAR_EN == 1 && VI_ATTR_TERMCHAR == 0}" ) # Linefeed \n is 10 self._test_filter2("TCPIP::?*::INSTR{VI_ATTR_TERMCHAR == 10}") # test handling error in the evaluation of the attribute def broken_get_visa_attribute(self, name): raise Exception() old = Resource.get_visa_attribute Resource.get_visa_attribute = broken_get_visa_attribute # Using any other log level will cause the test to fail for no apparent # good reason with self.assertLogs(level=logging.DEBUG, logger=logger): try: self._test_filter2("TCPIP::?*::INSTR{VI_ATTR_TERMCHAR == 10}") finally: Resource.get_visa_attribute = old
def test_non_blocking_read(): """ Make sure the the non blocking read is fast. """ register_resources(instruments.resources) rc = ResourceManager(visa_library="@mock") res: MockResource = rc.open_resource("MOCK0::mock5::INSTR") meas_time = Mocker5.meas_time start_time = time.time() res.write(":instr:channel1:volt 12") end_time = time.time() elapsted = end_time - start_time assert elapsted < meas_time/2 # clear the STB reg voltage = res.write("*CLS") # kick off reading start_time = time.time() res.write(":inStrument:channel1:MEAS") end_time = time.time() elapsted = end_time - start_time assert elapsted < meas_time/2 # Make sure time out happens with pytest.raises(VisaIOError) as e: res.wait_for_srq(0) assert e.value.error_code == StatusCode.error_timeout # Wait for event interrupt start_time = time.time() res.wait_for_srq() end_time = time.time() elapsted = end_time - start_time assert elapsted > meas_time/2 start_time = time.time() voltage = res.query(":inStrument:channel1:REAd?") end_time = time.time() elapsted = end_time - start_time assert elapsted < meas_time/2 assert voltage == "12.0"
def test_blocking_read(): """ Make sure the the measurement takes a while to complete and that other operations are fast. """ register_resources(instruments.resources) rc = ResourceManager(visa_library="@mock") res: MockResource = rc.open_resource("MOCK0::mock5::INSTR") meas_time = Mocker5.meas_time start_time = time.time() res.write(":instr:channel1:volt 12") end_time = time.time() elapsted = end_time - start_time assert elapsted < meas_time/2 start_time = time.time() voltage = res.query(":inStrument:channel1:vOlT?") end_time = time.time() elapsted = end_time - start_time assert elapsted > meas_time/2 assert voltage == "12.0"
class TestFilter2(BaseTestCase): def setup_method(self): """Create a ResourceManager with the default backend library.""" self.rm = ResourceManager() def teardown_method(self): """Close the ResourceManager.""" self.rm.close() def _test_filter2(self, expr, *correct): resources = self.rm.list_resources(expr.split("{")[0]) ok = tuple(resources[n] for n in correct) filtered = rname.filter2(resources, expr, lambda rsc: self.rm.open_resource(rsc)) assert filtered == ok def test_filter2_optional_clause_with_connection(self, caplog, monkeypatch): self._test_filter2( "?*::INSTR{VI_ATTR_TERMCHAR_EN == 1 && VI_ATTR_TERMCHAR == 0}") # Linefeed \n is 10 self._test_filter2("TCPIP::?*::INSTR{VI_ATTR_TERMCHAR == 10}") # test handling error in the evaluation of the attribute def broken_get_visa_attribute(self, name): raise Exception() monkeypatch.setattr(Resource, "get_visa_attribute", broken_get_visa_attribute) # Using any other log level will cause the test to fail for no apparent # good reason caplog.clear() with caplog.at_level(logging.DEBUG, logger="pyvisa"): self._test_filter2("TCPIP::?*::INSTR{VI_ATTR_TERMCHAR == 10}") assert caplog.records
class Driver(): """Driver class for GPIB controlled Agilent EE405 Spectrum analyser""" def reset(self): """ Create factory reset""" self.device.write('*RST') self.log.info("Reset to factory settings successfull.") def __init__(self, gpib_address, logger): """Instantiate driver class :gpib_address: GPIB-address of spectrum analyzer, e.g. 'GPIB0::12::INSTR' Can be read out by using rm = pyvisa.ResourceManager() rm.list_resources() :logger: And instance of a LogClient """ # Instantiate log self.log = LogHandler(logger=logger) self.rm = ResourceManager() try: self.device = self.rm.open_resource(gpib_address) device_id = self.device.query('*IDN?') self.log.info(f"Successfully connected to {device_id}.") except VisaIOError: self.log.error(f"Connection to {gpib_address} failed.") # reset to factory settings self.reset() def display_off(self): """ Power off display """ self.device.write(':DISPlay:ENABle OFF') self.log.info("Display off.") def display_on(self): """ Power on display """ self.device.write(':DISPlay:ENABle ON') self.log.info("Display on.") def set_attenuation(self, db): """ Set input attenuation :db: Target attenuation in dB, must be between 0 and 75 """ if not 0 <= db <= 75: self.log.error( f'Invalid attenuation ({db}dB). Attenuation must be between 0dB and 75dB' ) self.device.write(f'POW:ATT {int(db)}dB') self.log.info(f'Input attenuation set to {db}dB.') def set_reference_level(self, db): """Set reference level :db: Target reference level in dB """ self.device.write(f':DISPlay:WINDow:TRACe:Y:RLEVel {int(db)}') self.log.info(f'Reference level set to {db}dB.') def set_center_frequency(self, center_frequency): """ Set center frequency of trace. :center_frequency: Frequency in Hz (from 0 to 13.3 GHz) """ if not 0 <= center_frequency <= 13.2 * 1e9: self.log.error( f'Invalid center frequency ({center_frequency} Hz). Must be within 0 and 13.2 GHz' ) self.device.write(f':SENSe:FREQuency:CENTer {center_frequency}') self.log.info(f'Center frequency set to {center_frequency} Hz') def set_frequency_span(self, frequency_span): """ Set frequency span of trace. :frequency_span: Frequency span in Hz (from 0 to 13.3 GHz) """ if not 0 <= frequency_span <= 13.2 * 1e9: self.log.error( f'Invalid frequency span ({frequency_span} Hz). Must be within 0 and 13.2 GHz' ) self.device.write(f':SENSe:FREQuency:SPAN {frequency_span}') self.log.info(f'Frequency span set {frequency_span} Hz') def toggle_cont(self, target_state): """Switch between single shot and continuous acquisition mode :target_state: Index of targe stat. 1 for continuous mode, 0 for single shot mode. """ self.device.write(f'INIT:CONT {target_state}') def get_frequency_array(self): """Constructs array of frequencies associated with trace points""" # Sweep start frequency. start_freq = float(self.device.query(':SENSe:FREQuency:STARt?')) # Sweep end frequency. end_freq = float(self.device.query(':SENSe:FREQuency:STOP?')) # Number of sweep points. num_sweep_points = int(self.device.query('SENSE:SWEEP:POINTS?')) # Array containing frequencies of each sweep point. frequencies = np.linspace(start_freq, end_freq, num_sweep_points) return frequencies def read_trace(self): """ Read and return trace Retruns array trace contaning frequencies (in Hz) of data points in trace[:,0] and power levels (in dBm) in trace[:,1] """ # Set to single shot mode. self.toggle_cont(0) # Trigger a sweep and wait for sweep to complete. self.device.write('INIT:IMM;*WAI') # Specify units in dBm. self.device.write('UNIT:POW DBM') # Specify data format as ASCII. self.device.write('FORM:DATA ASC') # Trigger a sweep and wait for sweep to complete. self.device.write('INIT:IMM;*WAI') # Query trace data dbm_measurement = self.device.query_ascii_values('TRAC:DATA? TRACE1') # Return to continuos monitoring mode self.toggle_cont(1) # Read frequency axis frequencies = self.get_frequency_array() # Combine trace data trace = np.stack((frequencies, dbm_measurement), axis=-1) return trace def acquire_background_spectrum(self, num_points=100): """Acquires an average background trace. :num_traces: How many traces to sample. :nocheck: Boolean indicating if user confirmation that no input signal is present will be omitted. """ traces = [] self.display_off() for i in range(num_points): traces.append(self.read_trace()) self.display_on() noise_average = np.average(np.asarray(traces)[:, :, 1], 0) noise_trace = np.array([traces[0][:, 0], noise_average]) self.noise_trace = np.transpose(noise_trace) def get_background(self): try: noise_trace = self.noise_trace return noise_trace except AttributeError: error_msg = 'No background acquired. Run acquire_background_spectrum() to acquire background.' self.log.warn(error_msg) return error_msg
class Driver: BOARDS = 8 def __init__(self, address=None, logger=None): """Instantiate driver class. :address: Address of the device, e.g. 'ASRL3::INSTR' Can be read out by using rm = pyvisa.ResourceManager() rm.list_resources() :logger: An instance of a LogClient. """ # Instantiate log self.log = LogHandler(logger=logger) self.addr = address self.rm = ResourceManager() try: self.device = self.rm.open_resource(self.addr) self.log.info(f"Successfully connected to {self.device}.") # Configure device grammar self.device.write_termination = ';' except VisaIOError: self.log.error(f"Connection to {self.addr} failed.") raise def measure_voltage(self, board, channel): """ Measures the current voltage on a particular channel of a particular board :param board: (int) integer between 0 and 7 (assuming 8 boards) :param channel: (int) integer between 0 and 3 :return: (float) voltage in volts (into open-loop) """ # Only proceed if we can correctly set the current board and channel if self._set_board(board) + self._set_channel(channel): self.log.warn( f'Did not measure the voltage for board {board} channel {channel}' ) return float(-777) return bitval_to_value(int(self.device.query('v').split()[-1]), bits=12, min=0, max=10) def set_high_voltage(self, board, channel, voltage): """ Sets a channel's high voltage :param board: (int) integer between 0 and 7 (assuming 8 boards) :param channel: (int) integer between 0 and 3 :param voltage: (float) voltage in V between 0 and 10 (into open-loop) :return: (int) 0 if successful """ # Only proceed if we can correctly set the current board and channel if self._set_board(board) + self._set_channel(channel): self.log.warn( f'Did not measure the voltage for board {board} channel {channel}' ) return float(-777) return self._set_high_voltage(voltage) def set_low_voltage(self, board, channel, voltage): """ Sets a channel's low voltage :param board: (int) integer between 0 and 7 (assuming 8 boards) :param channel: (int) integer between 0 and 3 :param voltage: (float) voltage in V between 0 and 10 (into open-loop) :return: (int) 0 if successful """ # Only proceed if we can correctly set the current board and channel if self._set_board(board) + self._set_channel(channel): self.log.warn( f'Did not measure the voltage for board {board} channel {channel}' ) return float(-777) return self._set_low_voltage(voltage) def get_high_voltage(self, board, channel): """ Gets a channel's high voltage :param board: (int) integer between 0 and 7 (assuming 8 boards) :param channel: (int) integer between 0 and 3 :return: (float) voltage in V from 0 to 10 """ # Only proceed if we can correctly set the current board and channel if self._set_board(board) + self._set_channel(channel): self.log.warn( f'Did not measure the voltage for board {board} channel {channel}' ) return float(-777) return bitval_to_value(int(self.device.query('h').split()[-1]), bits=16, min=0, max=10) def get_low_voltage(self, board, channel): """ Gets a channel's low voltage :param board: (int) integer between 0 and 7 (assuming 8 boards) :param channel: (int) integer between 0 and 3 :return: (float) voltage in V from 0 to 10 """ # Only proceed if we can correctly set the current board and channel if self._set_board(board) + self._set_channel(channel): self.log.warn( f'Did not measure the voltage for board {board} channel {channel}' ) return float(-777) return bitval_to_value(int(self.device.query('l').split()[-1]), bits=16, min=0, max=10) def save(self): """ Saves current state of low/high for all channels to non-volatile memory :return: (int) 0 if successful """ # This fails randomly due to nondeterministic response, which we need to handle read = 0 while read < 10: self.device.write('S') try: self.device.read() read = 11 except VisaIOError: read += 1 except UnicodeDecodeError: read += 1 if read > 10: self.log.info('Saved current DIO breakout settings successfully') return 0 else: self.log.warn('Failed to save DIO breakout settings.' 'Connection may be corrupted.') return 1 def override(self, board, channel, state=True): """ Overrides HDAWG output :param board: (int) integer between 0 and 7 (assuming 8 boards) :param channel: (int) integer between 0 and 3 :param state: (bool) whether or not to force hi or lo :return: (int) 0 if successful """ if self._set_board(board) + self._set_channel(channel): self.log.warn(f'Did not override board {board} channel {channel}') return float(-777) self.device.write(f'F {1 if state else 0}') if int(self.device.query('b').rstrip()[-1]) != board: self.log.warn( f'Error in overriding board {board} channel {channel}') return float(-1) self.log.info(f'Board {board} channel {channel} in override mode') return 0 def disable_override(self, board, channel): """ Disables the override :param board: (int) integer between 0 and 7 (assuming 8 boards) :param channel: (int) integer between 0 and 3 :return: (int) 0 if successful """ if self._set_board(board) + self._set_channel(channel): self.log.warn( f'Did not disable override for board {board} channel {channel}' ) return float(-777) self.device.write('F -1') if int(self.device.query('b').rstrip()[-1]) != board: self.log.warn( f'Error in disabling override for board {board} channel {channel}' ) return float(-1) self.log.info( f'Board {board} channel {channel} override has been disabled') return 0 def close(self): """ Closes the connection to the device """ self.device.close() self.log.info(f'Closed connection to device at {self.addr}') # Technical methods (not to be exposed) def _set_board(self, board): """ Sets the current board (to update) :param board: (int) integer between 0 and 7 (assuming 8 boards) :return: (int) 0 if successful """ board = int(board) # Check within bounds if board < 0 or board > self.BOARDS - 1: self.log.warn( f'Board to set must be an integer between 0 and {self.BOARDS-1}' ) return 1 self.device.write(f'B {board}') # Check successful write (and clear the buffer) if int(self.device.query('b').rstrip()[-1]) != board: self.log.warn(f'Failed to set current board to {board}') return 2 return 0 def _set_channel(self, channel): """ Sets the current channel (to update) :param channel: (int) integer between 0 and 3 :return: (int) 0 if successful """ channel = int(channel) # Check within bounds if channel < 0 or channel > 3: self.log.warn(f'Channel to set must be an integer between 0 and 3') return 1 self.device.write(f'C {channel}') # Check successful write (and clear the buffer) if int(self.device.query('c').rstrip()[-1]) != channel: self.log.warn(f'Failed to set current channel to {channel}') return 2 return 0 def _set_high_voltage(self, voltage): """ Sets the current channel's high voltage :param voltage: (float) voltage in V between 0 and 10 (into open-loop) :return: (int) 0 if successful """ voltage = float(voltage) # Check within bounds if voltage < 0 or voltage > 10: self.log.warn(f'Can only set voltage between 0 and 10 V') return 1 bitval = value_to_bitval(voltage, bits=16, min=0, max=10) self.device.write(f'H {bitval}') # Check successful write (and clear the buffer) if int(self.device.query('h').split()[-1]) != bitval: self.log.warn(f'Failed to set high voltage to {voltage} V') return 2 return 0 def _set_low_voltage(self, voltage): """ Sets the current channel's low voltage :param voltage: (float) voltage in V between 0 and 10 (into open-loop) :return: (int) 0 if successful """ voltage = float(voltage) # Check within bounds if voltage < 0 or voltage > 10: self.log.warn(f'Can only set voltage between 0 and 10 V') return 1 bitval = value_to_bitval(voltage, bits=16, min=0, max=10) self.device.write(f'L {bitval}') # Check successful write (and clear the buffer) if int(self.device.query('l').split()[-1]) != bitval: self.log.warn(f'Failed to set low voltage to {voltage} V') return 2 return 0
def test_trigger(hislip_example, resource_manager: pyvisa.ResourceManager): inst = resource_manager.open_resource(hislip_example) inst.assert_trigger() inst.close()
class TestResourceManager(unittest.TestCase): """Test the pyvisa ResourceManager. """ def setUp(self): """Create a ResourceManager with the default backend library. """ self.rm = ResourceManager() def tearDown(self): """Close the ResourceManager. """ self.rm.close() del rm gc.collect() def test_lifecycle(self): """Test creation and closing of the resource manager. """ self.assertIsNotNone(self.rm.session) self.assertIsNotNone(self.rm.visalib) self.assertIs(self.rm, self.rm.visalib.resource_manager) self.assertFalse(self.rm.list_opened_resources()) self.assertIs(self.rm.visalib, ResourceManager(self.rm.visalib).visalib) self.rm.close() with self.assertRaises(InvalidSession): self.rm.session self.assertIsNone(self.rm.visalib.resource_manager) def test_cleanup_on_del(self): """Test that deleting the rm does clean the VISA session """ # The test seems to assert what it should even though the coverage report # seems wrong rm = highlevel.ResourceManager() with self.assertLogs(level=logging.DEBUG) as log: del rm gc.collect() self.assertIn('Closing ResourceManager', log.output) def test_resource_manager_unicity(self): """Test the resource manager is unique per backend as expected. """ new_rm = ResourceManager() self.assertIs(self.rm, new_rm) self.assertEqual(self.rm.session, new_rm.session) def test_str(self): """Test computing the string representation of the resource manager """ self.assertRegex(str(self.rm), r"Resource Manager of .*") self.rm.close() self.assertRegex(str(self.rm), r"Resource Manager of .*") def test_repr(self): """Test computing the repr of the resource manager """ self.assertRegex(repr(self.rm), r"<ResourceManager\(<.*>\)>") self.rm.close() self.assertRegex(repr(self.rm), r"<ResourceManager\(<.*>\)>") def test_last_status(self): """Test accessing the status of the last operation. """ self.assertEqual(self.rm.last_status, StatusCode.success) # Access the generic last status through the visalib self.assertEqual(self.rm.last_status, self.rm.visalib.last_status) # Test accessing the status for an invalid session with self.assertRaises(errors.Error) as cm: self.rm.visalib.get_last_status_in_session("_nonexisting_") self.assertIn("The session", cm.exception.args[0]) def test_list_resource(self): """Test listing the available resources. """ # Default settings self.assertSequenceEqual( sorted(self.rm.list_resources()), sorted([ str(ResourceName.from_string(v)) for v in RESOURCE_ADDRESSES.values() if v.endswith("INSTR") ])) # All resources self.assertSequenceEqual( sorted(self.rm.list_resources("?*")), sorted([ str(ResourceName.from_string(v)) for v in RESOURCE_ADDRESSES.values() ])) def test_accessing_resource_infos(self): """Test accessing resource infos. """ rname = list(RESOURCE_ADDRESSES.values())[0] rinfo_ext = self.rm.resource_info(rname) rinfo = self.rm.resource_info(rname, extended=False) rname = ResourceName().from_string(rname) self.assertEqual(rinfo_ext.interface_type, getattr(InterfaceType, rname.interface_type.lower())) self.assertEqual(rinfo_ext.interface_board_number, int(rname.board)) self.assertEqual(rinfo_ext.resource_class, rname.resource_class) self.assertEqual(rinfo_ext.resource_name, str(rname)) self.assertEqual(rinfo.interface_type, getattr(InterfaceType, rname.interface_type.lower())) self.assertEqual(rinfo.interface_board_number, int(rname.board)) def test_listing_resource_infos(self): """Test listing resource infos. """ infos = self.rm.list_resources_info() for rname, rinfo_ext in infos.items(): rname = ResourceName().from_string(rname) self.assertEqual( rinfo_ext.interface_type, getattr(InterfaceType, rname.interface_type.lower())) self.assertEqual(rinfo_ext.interface_board_number, int(rname.board)) self.assertEqual(rinfo_ext.resource_class, rname.resource_class) self.assertEqual(rinfo_ext.resource_name, str(rname)) def test_opening_resource(self): """Test opening and closing resources. """ rname = list(RESOURCE_ADDRESSES.values())[0] rsc = self.rm.open_resource(rname, timeout=1234) # Check the resource is listed as opened and the attributes are right. self.assertIn(rsc, self.rm.list_opened_resources()) self.assertEqual(rsc.timeout, 1234) # Close the rm to check that we close all resources. self.rm.close() self.assertFalse(self.rm.list_opened_resources()) with self.assertRaises(InvalidSession): rsc.session def test_opening_resource_bad_open_timeout(self): """Test opening a resource with a non integer open_timeout. """ rname = list(RESOURCE_ADDRESSES.values())[0] with self.assertRaises(ValueError) as cm: rsc = self.rm.open_resource(rname, open_timeout="") self.assertIn("integer (or compatible type)", str(cm.exception)) def test_opening_resource_with_lock(self): """Test opening a locked resource """ rname = list(RESOURCE_ADDRESSES.values())[0] rsc = self.rm.open_resource(rname, access_mode=AccessModes.exclusive_lock) self.assertEqual(len(self.rm.list_opened_resources()), 1) # Timeout when accessing a locked resource with self.assertRaises(VisaIOError): self.rm.open_resource(rname, access_mode=AccessModes.exclusive_lock) self.assertEqual(len(self.rm.list_opened_resources()), 1) # Success to access an unlocked resource. rsc.unlock() rsc2 = self.rm.open_resource(rname, access_mode=AccessModes.exclusive_lock) self.assertEqual(len(self.rm.list_opened_resources()), 2) def test_opening_resource_specific_class(self): """Test opening a resource requesting a specific class. """ rname = list(RESOURCE_ADDRESSES.values())[0] with self.assertRaises(TypeError): rsc = self.rm.open_resource(rname, resource_pyclass=object) self.assertEqual(len(self.rm.list_opened_resources()), 0) def test_open_resource_unknown_resource_type(self): """Test opening a resource for which no registered class exist. """ rc = highlevel.ResourceManager._resource_classes old = rc.copy() class FakeResource: def __init__(self, *args): raise RuntimeError() rc[(constants.InterfaceType.unknown, "")] = FakeResource rm = highlevel.ResourceManager() try: with self.assertLogs(level=logging.WARNING): highlevel.ResourceManager.open_resource( "TCPIP::192.168.0.1::INSTR") self.assertIs( highlevel.ResourceManager._resource_classes[( constants.InterfaceType.tcpip, "INSTR")], object) finally: highlevel.ResourceManager._resource_classes = old def test_opening_resource_unknown_attribute(self): """Test opening a resource and attempting to set an unknown attr. """ rname = list(RESOURCE_ADDRESSES.values())[0] with self.assertRaises(ValueError): rsc = self.rm.open_resource(rname, unknown_attribute=None) self.assertEqual(len(self.rm.list_opened_resources()), 0) def test_get_instrument(self): """Check that we get the expected deprecation warning. """ rname = list(RESOURCE_ADDRESSES.values())[0] with self.assertWarns(FutureWarning): rsc = self.rm.get_instrument(rname)
class Driver(): POWER_RANGE = [-120, 30] # acceptable power range in dBm POWER_PRECISION = 2 # number of digits of precision for power FREQ_RANGE = [1e7, 2e10] # acceptable frequency range in Hz def __init__(self, gpib_address, logger): """ Instantiate driver class, connects to device :param gpib_address: GPIB-address of the device, can be found with pyvisa.ResourceManager.list_resources() :param logger: instance of LogClient """ self.log = LogHandler(logger=logger) self.rm = ResourceManager() try: self.device = self.rm.open_resource(gpib_address) self.device.read_termination = '\n' self.device_id = self.device.query('*IDN?') self.log.info(f'Successfully connected to {self.device_id}') except VisaIOError: self.log.error(f'Connection to {gpib_address} failed') raise def set_power(self, power): """ Sets power of MW source :param power: (float) output power to set in dBm """ power = round(power, self.POWER_PRECISION) # Check for valid range if power < self.POWER_RANGE[0] or power > self.POWER_RANGE[1]: self.log.warn( f'Warning, power outside acceptable range {self.POWER_RANGE}. ' f'Output power was not updated.') # Set power else: self.device.write(f'POW {power}') self.log.info(f'Set MW power to {power}') def set_freq(self, freq): """ Sets power of MW source :param freq: (float) output frequency in Hz """ freq = int(round(freq)) # Check for valid range if freq < self.FREQ_RANGE[0] or freq > self.FREQ_RANGE[1]: self.log.warn( f'Warning, frequency outside acceptable range {self.FREQ_RANGE}. ' f'Output frequency was not updated.') # Set freq else: self.device.write(f'FREQ {freq}') self.log.info(f'Set MW freq to {freq}') def output_on(self): """ Turn output on """ self.device.write('OUTP ON') self.log.info('MW output turned on') def output_off(self): """ Turn output off """ self.device.write('OUTP OFF') self.log.info('MW output turned off')
import pyvisa from pyvisa import ResourceManager m = ResourceManager() resources_list = m.list_resources() print(resources_list) inst = m.open_resource(resources_list[1]) print("eae") a = inst.write_raw(b"*IDN?") f = inst.read_raw() print(a) inst.close()
task.write(1, 2) task.write(3, 2) else: task.write(0, 2) task.write(2, 2) # Cycle the register clock to load the parallel register. task.write(4, 2) task.write(0, 2) # Delay for 700 ms to account for relay bounce. sleep(0.70) # Utilize the Keysight E5063A ENA to collect an S11 measurement. resource_manager = ResourceManager() ENA5063 = resource_manager.open_resource("ENA5063") ENA5063.write(':INITiate1:CONTinuous %d' % (1)) ENA5063.write(':CALCulate1:PARameter1:DEFine %s' % ('S11')) ENA5063.write(':CALCulate1:PARameter1:SELect') ENA5063.write(':TRIGger:SEQuence:SOURce %s' % ('MANual')) ENA5063.write(':TRIGger:SEQuence:SINGle') ENA5063.write('*OPC') ENA5063.write(':INITiate1:CONTinuous %d' % (0)) ENA5063.write(':CALCulate1:SELected:FORMat %s' % ('MLOGarithmic')) ENA5063.write(':FORMat:DATA %s' % ('REAL')) ENA5063.write(':FORMat:BORDer %s' % ('SWAPped')) measurement = ENA5063.query_binary_values( ':CALCulate1:SELected:DATA:FDATa?', 'd', False) ENA5063.close() resource_manager.close()
class Driver: def __init__(self, gpib_address=None, logger=None): """Instantiate driver class. :gpib_address: GPIB-address of the scope, e.g. 'GPIB0::12::INSTR' Can be read out by using rm = pyvisa.ResourceManager() rm.list_resources() :logger: An instance of a LogClient. """ # Instantiate log. self.log = LogHandler(logger=logger) self.rm = ResourceManager() try: self.device = self.rm.open_resource(gpib_address) device_id = self.device.query('*IDN?') self.log.info(f"Successfully connected to {device_id}.") # We set a more forgiving timeout of 10s (default: 2s). # self.device.timeout = 10000 except VisaIOError: self.log.error(f"Connection to {gpib_address} failed.") def get_power(self, channel): """ Returns the current power in watts on a desired channel :param channel: (int) channel to read power of (either 1 or 2) :return: (float) power in watts """ power = self.device.query(f':POW{channel}:VAL?') return float(power) def get_wavelength(self, channel): """ Returns the current wavelength in nm for the desired channel :param channel: (int) channel to read wavelength of :return: (int) wavelength """ wavelength = self.device.query(f':WAVEL{channel}:VAL?') return int(float(wavelength)) def get_range(self, channel): """ Returns the current power range for the channel :param channel: (int) channel to read range of :return: (str) range """ pr = self.device.query(f':PRANGE{channel}?') return pr def set_wavelength(self, channel, wavelength): """ Sets the wavelength :param channel: (int) channel to set wavelength of """ self.device.write(f':WAVEL{channel}:VAL {wavelength}') def set_range(self, channel, p_range): """ Sets the range :param channel: (int) channel to set range of :param p_range: (str) range string identifier, can be anything in 'AUTO', 'R1NW', 'R10NW', 'R100NW', 'R1UW', 'R10UW', 'R100UW', 'R1MW', 'R10MW', 'R100MW', 'R1W', 'R10W', 'R100W', 'R1KW' """ self.device.write(f':PRANGE{channel} {p_range}')
class Driver(): def reset(self): """ Create factory reset""" self.device.write('FAC;WAIT') self.log.info("Reset to factory settings successfull.") def __init__(self, gpib_address, logger): """Instantiate driver class. :gpib_address: GPIB-address of the scope, e.g. 'GPIB0::12::INSTR' Can be read out by using rm = pyvisa.ResourceManager() rm.list_resources() :logger: And instance of a LogClient. """ # Instantiate log. self.log = LogHandler(logger=logger) self.rm = ResourceManager() try: self.device = self.rm.open_resource(gpib_address) device_id = self.device.query('*IDN?') self.log.info(f"Successfully connected to {device_id}.") except VisaIOError: self.log.error(f"Connection to {gpib_address} failed.") # We set a more forgiving timeout of 10s (default: 2s). self.device.timeout = 10000 # Reset to factory settings. self.reset() # Set all attenuations to 1x. for channel in CHANNEL_LIST: self.set_channel_attenuation(channel, 1) def get_trigger_source(self): """ Return Trigger source.""" # Query trigger source. res = self.device.query('TRIG:MAI:EDGE:SOU?') # Tidy up response using regex. trig_channel = re.compile( ':TRIGGER:MAIN:EDGE:SOURCE[ ]([^\\n]+)' ).match(res).group(1) return trig_channel def set_trigger_source(self, trigger_source): """ Set trigger source.""" if trigger_source not in TRIGGER_SOURCE_LIST: self.log.error( f"'{trigger_source}' no found, available trigger sources are {TRIGGER_SOURCE_LIST}.'" ) # Set trigger source. self.device.write(f'TRIG:MAI:EDGE:SOU {trigger_source}') def set_timing_scale(self, scale): """ Set the time base. This defines the available display window, as 10 divisions are displayed. :scale: Time per division (in s) """ self.device.write(":HORIZONTAL:MAIN:SCALE {:e}".format(scale)) def extract_params(self, command, value): """ Uses regex to extract float values from return values. :command: The command used to query, without the final '?' :value: The return value of a query. """ value = float(re.compile( f'{command}[ ]([0-9\.\+Ee-]+)' ).match(value).group(1)) return value def get_timing_scale(self): """ Get time base in secs per division.""" command = ":HORIZONTAL:MAIN:SCALE" timing_res = self.device.query(f"{command}?") timing_res = self.extract_params(command, timing_res) return timing_res def set_single_run_acq(self): """Set acquisition mode to single run.""" self.device.write('acquire:stopafter sequence') def acquire_single_run(self): """ Run single acquisition.""" self.device.write('acquire:state on') def _check_channel(self, channel): """ CHeck if channel is in CHANNEL list.""" if channel not in CHANNEL_LIST: self.log.error( f"The channel '{channel}' is not available, available channels are {CHANNEL_LIST}." ) def unitize_trace(self, trace, trace_preamble): """Transform unitless trace to trace with units, constructs time array. :trace: (np.array) Unitless array as provided by oscilloscope. :trace_preamble: (string) Waveform preamble. Returns trace, a np.array in correct units, ts, the time array in seconds, and y_unit, the unit of the Y-axis. """ # Overcharged regex extracting all relevant paramters. wave_pre_regex = 'NR_PT (?P<n_points>[0-9\.\+Ee-]+).+XINCR (?P<x_incr>[0-9\.\+Ee-]+).+PT_OFF (?P<pt_off>[0-9\.\+Ee-]+).+XZERO (?P<x_zero>[0-9\.\+Ee-]+).+XUNIT "(?P<x_unit>[^"]+).+YMULT (?P<y_mult>[0-9\.\+Ee-]+).+YZERO (?P<y_zero>[0-9\.\+Ee-]+).+YOFF (?P<y_off>[0-9\.\+Ee-]+).+YUNIT "(?P<y_unit>[^"]+)' wave_pre_matches = re.search(wave_pre_regex, trace_preamble) # Adjust trace as shown in the coding manual 2-255. trace = ( trace - float(wave_pre_matches['y_off']) ) * \ float(wave_pre_matches['y_mult']) + \ float(wave_pre_matches['y_zero']) # Construct timing array as shown in the coding manual 2-250. ts = float(wave_pre_matches['x_zero']) + \ ( np.arange(int(wave_pre_matches['n_points'])) - int(wave_pre_matches['pt_off']) ) * float(wave_pre_matches['x_incr']) x_unit = wave_pre_matches['x_unit'] y_unit = wave_pre_matches['y_unit'] # Construct trace dictionary. trace_dict = { 'trace': trace, 'ts': ts, 'x_unit': x_unit, 'y_unit': y_unit } return trace_dict def read_out_trace(self, channel, curve_res=1): """ Read out trace :channel: Channel to read out (must be in CHANNEL_LIST). :curve_res: Bit resolution for returned data. If 1, value range is from -127 to 127, if 2, the value range is from -32768 to 32768. Returns np.array of sample points (in unit of Voltage divisions) and corresponding array of times (in seconds). """ self._check_channel(channel) # Enable trace. self.show_trace(channel) # Run acquisition. self.acquire_single_run() if curve_res not in [1, 2]: self.log.error("The bit resolution of the curve data must be either 1 or 2.") # Set curve data to desired bit. self.device.write(f'DATa:WIDth {curve_res}') # Set trace we want to look at. self.device.write(f'DATa:SOUrce {channel}') # Set encoding. self.device.write('data:encdg ascii') # Read out trace. res = self.device.query('curve?') # Tidy up curve. raw_curve = res.replace(':CURVE', '').replace(' ', '').replace('\n', '') # Transform in numpy array. trace = np.fromstring(raw_curve, dtype=int, sep=',') # Read wave preamble. wave_pre = self.device.query('WFMPre?') # Transform units of trace. trace_dict = self.unitize_trace(trace, wave_pre) return trace_dict def show_trace(self, channel): """Display trace. Required for trace readout. """ self._check_channel(channel) self.device.write(f'SELect:{channel} 1') def hide_trace(self, channel): """Hide trace.""" self._check_channel(channel) self.device.write(f'SELect:{channel} 0') def _check_channel_attenuation(self, attenuation): """Check if attenuation is within option set.""" if attenuation not in ATTENUATIONS: self.log.error( f"The attenuation '{attenuation}x' is not available, available attenuations are {ATTENUATIONS}." ) def get_channel_attenuation(self, channel): """Get the attenuation of the channel. :channel: (str) Channel, possible values see CHANNEL_LIST. """ # Check if channel and attenuation is valid. self._check_channel(channel) # Get attenuation. command = f":{channel}:PROBE" attenuation = self.device.query(f"{command}?") # Extract float. attenuation = self.extract_params(command, attenuation) return attenuation def set_channel_attenuation(self, channel, attenuation): """Set the attenuation of the channel. This setting will scale the y-axis unit accordingly :channel: (str) Channel, possible values see CHANNEL_LIST. :attenuation: (int) Attenuation, possible values see ATTENUATIONS. """ # Check if channel and attenuation is valid. self._check_channel(channel) self._check_channel_attenuation(attenuation) # Set attenuation. self.device.write(f'{channel}:PRObe {attenuation}') def get_channel_scale(self, channel): """ Return vertical scale of channel. :channel: (str) Channel, possible values see CHANNEL_LIST. """ self._check_channel(channel) command = f":{channel}:SCALE" scale = self.device.query(f"{command}?") # Extract float. scale = self.extract_params(command, scale) return scale def set_channel_scale(self, channel, range): """ Return vertical scale of channel. :channel: (str) Channel, possible values see CHANNEL_LIST. :range: (float) Vertical range, in Volt/vertical division. Corresponds to 'Scale' turning knob. Must be between 5 mv/div and 5 V/div. """ self._check_channel(channel) if not (5e-3 <= range <= 5): self.log.error('Range must be between 5 mv/div and 5 V/div.') # Set scale. self.device.write(f'{channel}:SCAle {range}') def get_channel_pos(self, channel): """Get vertical position of channel trace. :channel: (str) Channel, possible values see CHANNEL_LIST. """ self._check_channel(channel) command = f":{channel}:POSITION" pos = self.device.query(f"{command}?") # Extract float. pos = self.extract_params(command, pos) return pos def set_channel_pos(self, channel, pos): """Set vertical position of channel trace. :channel: (str) Channel, possible values see CHANNEL_LIST. :pos: (str) Vertical postion, in divs above center graticule. The maximum and minimum value of pos depends on the channel scale. """ self._check_channel(channel) self.device.write(f'{channel}:POS {pos}') def get_horizontal_position(self): """Get the horizontal position of the traces. The return value in seconds is the difference between the trigger point ant the center graticule. """ command = ":HORIZONTAL:MAIN:POSITION" hor_pos = self.device.query(f"{command}?") hor_pos = self.extract_params(command, hor_pos) return hor_pos def set_horizontal_position(self, hor_pos): """Set the horizontal position of the traces. The return value in seconds is the difference between the trigger point ant the center graticule. :hor_pos: (float) Horizontal position in s. """ command = ":HORIZONTAL:MAIN:POSITION" self.device.write(f"{command} {hor_pos}") def trig_level_to_fifty(self): """Set main trigger level to 50%""" self.device.write('TRIGger:MAIn SETLEVel') def get_trigger_level(self): """Get trigger level.""" trig_level = self.device.query(':TRIGGER:MAIN:LEVEL?') trig_level = self.extract_params(':TRIGGER:MAIN:LEVEL', trig_level) return trig_level def set_trigger_level(self, trigger_level): """Set trigger level. :trigger_level: (float) Trigger level in Volts. """ self.device.write(f':TRIGGER:MAIN:LEVEL {trigger_level}')
class DAQ_0DViewer_Keithley_Pico(DAQ_Viewer_base): """ ==================== ======================== **Attributes** **Type** *data_grabed_signal* instance of pyqtSignal *VISA_rm* ResourceManager *com_ports* *params* dictionnary list *keithley* *settings* ==================== ======================== """ data_grabed_signal=pyqtSignal(list) ##checking VISA ressources from pyvisa import ResourceManager VISA_rm=ResourceManager() com_ports=list(VISA_rm.list_resources()) # import serial.tools.list_ports; # com_ports=[comport.device for comport in serial.tools.list_ports.comports()] params= comon_parameters+[ {'title': 'VISA:','name': 'VISA_ressources', 'type': 'list', 'values': com_ports }, {'title': 'Keithley Type:','name': 'keithley_type', 'type': 'list', 'values': DAQ_0DViewer_Keithley_Pico_type.names()}, {'title': 'Id:', 'name': 'id', 'type': 'text', 'value': "" }, {'title': 'Timeout (ms):', 'name': 'timeout', 'type': 'int', 'value': 10000, 'default': 10000, 'min': 2000 }, {'title': 'Configuration:', 'name': 'config', 'type': 'group', 'children':[ {'title': 'Meas. type:', 'name': 'meas_type', 'type': 'list', 'value': 'CURR', 'default': 'CURR', 'values': ['CURR','VOLT','RES','CHAR'] }, ] }, ] def __init__(self,parent=None,params_state=None): super(DAQ_0DViewer_Keithley_Pico,self).__init__(parent,params_state) from visa import ResourceManager self.VISA_rm=ResourceManager() self.controller=None def ini_detector(self, controller=None): """ Initialisation procedure of the detector. Returns ------- The initialized status. See Also -------- daq_utils.ThreadCommand """ self.status.update(edict(initialized=False,info="",x_axis=None,y_axis=None,controller=None)) try: if self.settings.child(('controller_status')).value()=="Slave": if controller is None: raise Exception('no controller has been defined externally while this detector is a slave one') else: self.controller=controller else: self.controller=self.VISA_rm.open_resource(self.settings.child(('VISA_ressources')).value(), read_termination='\r') self.controller.timeout=self.settings.child(('timeout')).value() self.controller.write("*rst; status:preset; *cls;") txt=self.controller.query('*IDN?') self.settings.child(('id')).setValue(txt) self.controller.write('CONF:'+self.settings.child('config','meas_type').value()) self.controller.write(':FORM:ELEM READ;DATA ASC;') self.controller.write('ARM:SOUR IMM;') self.controller.write('ARM:COUNt 1;') self.controller.write('TRIG:SOUR IMM;') #%% data=self.controller.query_ascii_values('READ?') self.status.initialized=True self.status.controller=self.controller return self.status except Exception as e: self.emit_status(ThreadCommand('Update_Status',[getLineInfo()+ str(e),'log'])) self.status.info=getLineInfo()+ str(e) self.status.initialized=False return self.status def commit_settings(self, param): """ Activate the parameters changes in the hardware. =============== ================================= ============================ **Parameters** **Type** **Description** *param* instance of pyqtgraph.parameter The parameter to be checked. =============== ================================= ============================ See Also -------- daq_utils.ThreadCommand """ try: if param.name()=='timeout': self.controller.timeout=self.settings.child(('timeout')).value() elif param.name()=='meas_type': self.controller.write('CONF:'+param.value()) except Exception as e: self.emit_status(ThreadCommand('Update_Status',[getLineInfo()+ str(e),'log'])) def close(self): """ close the current instance of Keithley viewer. """ self.controller.close() def grab_data(self, Naverage=1, **kwargs): """ | Start new acquisition. | grab the current values with keithley profile procedure. | Send the data_grabed_signal once done. =============== ======== =============================================== **Parameters** **Type** **Description** *Naverage* int Number of values to average =============== ======== =============================================== """ data_tot=[] self.controller.write('ARM:SOUR IMM;') self.controller.write('ARM:COUNt 1;') self.controller.write('TRIG:SOUR IMM;') self.controller.write('TRIG:COUN {:};'.format(Naverage)) data_tot=self.controller.query_ascii_values('READ?') #for ind in range(Naverage): # data_tot.append(self.controller.query_ascii_values('READ?')[0]) data_tot=[np.array([np.mean(np.array(data_tot))])] self.data_grabed_signal.emit([DataFromPlugins(name='Keithley',data=data_tot, dim='Data0D')]) def stop(self): """ not implemented? """ return ""