Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
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'
Ejemplo n.º 4
0
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()
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
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.')
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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'
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
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()
Ejemplo n.º 14
0
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()
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
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()
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
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"
Ejemplo n.º 19
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"
Ejemplo n.º 20
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
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
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
Ejemplo n.º 23
0
def test_trigger(hislip_example, resource_manager: pyvisa.ResourceManager):
    inst = resource_manager.open_resource(hislip_example)

    inst.assert_trigger()

    inst.close()
Ejemplo n.º 24
0
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)
Ejemplo n.º 25
0
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')
Ejemplo n.º 26
0
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()
Ejemplo n.º 28
0
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}')
Ejemplo n.º 29
0
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}')
Ejemplo n.º 30
0
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 ""