def measure(self,
                func=None,
                disp2=None,
                multiple_results=False,
                trigger=True,
                **mode_params):
        """
        func
        - L Inductance
        - C Capacitance
        - R Resistance
        - Z Impedance
        - ESR Equivalent Series Resistance

        returns a namedtuple of the results from the meter.
        usage:
        >>>lcr = lcr.open()
        >>>result = lcr.measure(func='C', multiple_results=True)
        result.Rs #Resistance Series
        result.Cs #Capacitance Series
        result.Rp #Resistance Parallel
        result.Cp #Capacitance Parallel
        result.Z #Impedance
        result.TH #Phase
        result.F #Frequency
        result.D #
        result.Q #

        >>>result = lcr.measure(func='L', multiple_results=True)
        result.Rs #Resistance Series
        result.Ls #Inductance Series
        result.Rp #Resistance Parallel
        result.Lp #Inductance Parallel
        result.Z #Impedance
        result.TH #Phase
        result.F #Frequency
        result.D #
        result.Q #
        >>>result.Cs
        None

        # Getting a single result back
        >>>result = lcr.measure(func='ESR')
        >>>print(result)
        9.3888e-08
        >>>result.Rs
        AttributeError
        """
        if disp2 is not None:
            if disp2.upper() not in ["TH", "Q", "D"]:
                raise ParameterError(
                    "Display 2 must be either 'TH', 'Q' or 'D'")
            self._write("DISP2 {}".format(disp2))
        if func is not None:
            if func.upper() not in ["L", "C", "R", "Z", "ESR"]:
                raise ParameterError(
                    "Func must be either 'L', 'C', 'R', 'Z' or 'ESR'")
            self._write("FUNC {}".format(func))

        return self._read_measurement(multiple_results)
 def range(self, val):
     rng = unit_scale(str(val))
     if not rng == round(rng, -int(floor(log10(rng)))):
         raise ParameterError()
     if str(rng)[0] != "2":
         raise ParameterError()
     if not 2000e-9 <= rng <= 200e6:
         raise ParameterError()
     self._range = val
     self._write("RANG {}".format(unit_convert(rng, 2, 2000)))
Exemple #3
0
 def update(self, measured_value):
     if self._updated_value == 0.0:
         raise ParameterError(
             "Cannot apply a scalar value to 0.0 because it will always return 0.0"
         )
     self._updated_value *= self._set_point / measured_value
     return self._updated_value
Exemple #4
0
 def output_ch1(self, val):
     if val not in [True, False]:
         raise ParameterError("{} not True or False".format(val))
     state = "OFF"
     if val:
         state = "ON"
     self._write("OUTP CH1,{}".format(state))
Exemple #5
0
    def create_buffered_write(self, ident, frequency, *dio_ranges):
        """
        Sets up the ranges to synchronize when writing to output at a specified frequency.
        This will force each write to the output for this ident to contain the amount of samples specified.
        eg.
        >>>daq = DaqMx()
        # Setup output @ 100Hz, 3 samples on port0 line 7 and 9
        >>>daq.create_buffered_write("MyOutput", 100, (0, 7, 7), (0, 9, 9))
        3 samples over 2 lines is 6 data values.
        >>>daq["MyOutput"] = [0 ,0, 1, 1, 0, 1]
        it is interleaved so it is written [line7, line9, line7, line9, line7, line9]
        Requires ports that enable buffered writes.
        In the X-Series daq this is port 0
        This disables reading from the output port for these pins.

        :param ident
        The identification used to access this message
        :param frequency
        The sample frequency for writing
        :type frequency integer or float
        :param io_ranges
        :type (port, line_start, line_end)
        :param samples
        The amount of samples that are required for each digital output write
        """
        if ident in self.tasks:
            raise ParameterError("Ident {} already used".format(ident))
        do_channel, data_length = self._build_digital_task_string(*dio_ranges)
        self.tasks[ident] = BufferedWrite(task_string=do_channel, io_length=data_length, frequency=frequency)
Exemple #6
0
 def __init__(self, initial_state):
     self._set_point = 0.0
     try:
         self._updated_value = float(initial_state)
     except ValueError as e:
         raise ParameterError(
             "initial_state found {}. Must be a non-zero number".format(
                 initial_state)) from e
Exemple #7
0
 def output_ch2(self, val):
     if val not in [True, False]:
         raise ParameterError(
             "Unknown output {} value for CH2\nPlease select True or False".
             format(val))
     if val:
         self._write("OUTP:CH2 ON")
     else:
         self._write("OUTP:CH2 OFF")
Exemple #8
0
 def frequency(self, val):
     if val not in [100, 120, 1e3, 10e3, "100", "120", "1k", "10k"]:
         raise ParameterError("Frequency must be either '100', '120', '1k' or '10k'")
     self._frequency = val
     try:
         val = unit_convert(val, 1, 200)
     except TypeError:
         pass
     self._write("FREQ {}".format(val))
Exemple #9
0
def mode_builder(search_dict, repl_kwargs, *args, **kwargs):
    """
    [] indicates an optional parameter. If no argument is given on the level that has an optional argument then it
    can still be parsed.
    If no [] arguments exist and no fitting arguments fit the current pattern then Parameter error will be raised
    :param args:
     These are arguments that don't require an additional argument, identified by : prefix
     eg. voltage
    :param kwargs:
     These are arguments identified by key name and require an additional parameter, identified by {}
     eg. {range} would be called as kwarg range=1
    :return:
    """
    # Search primary parameters
    # Each level of the mode config can contain only one match otherwise fail
    matches = [
        x for x in match_params(args, kwargs, search_dict, repl_kwargs) if x
    ]
    if len(matches) > 1:
        req_matches = []
        for match in matches:
            if '[' not in match:
                req_matches.append(match)
        if len(req_matches) > 1:
            raise ParameterError("Conflicting parameters: \n{}".format(
                '\n'.join(matches)))
        matches = req_matches

    if len(matches) == 0:
        # No further recursion
        if required_params(search_dict):
            raise ParameterError("Missing a required key \n{}".format(
                '\n'.join(search_dict)))
        return ''
    ret_string = matches[0]
    # Match the next parameter
    ret_string += mode_builder(search_dict[matches[0]], repl_kwargs, *args,
                               **kwargs)

    # Remove the optional '[]' markers
    ret_string = re.sub('[[\]]', '', ret_string)
    kwargs = sanitise_kwargs(kwargs, repl_kwargs)
    ret_string = ret_string.format(**kwargs)
    return ret_string
Exemple #10
0
def bits(n, num_bytes=1, num_bits=None, order="MSB"):
    if num_bits is None:
        num_bits = num_bytes * 8
    if n >= 1 << num_bits:
        raise ParameterError(
            "Number {} doesn't fit in {} number of bytes".format(n, num_bytes))
    if order.upper() in "MSB":
        b = 1 << num_bits
        while b > 1:
            b >>= 1
            yield bool(b & n)
    elif order.upper() in "LSB":
        target = 1 << num_bits
        b = 1
        while b < target:
            yield bool(b & n)
            b <<= 1
    else:
        raise ParameterError(
            "Unknown order {} please choose MSB or LSB".format(order))
Exemple #11
0
 def output_sync(self, val):
     time.sleep(0.5)
     if val not in [True, False]:
         raise ParameterError(
             "Unknown output {} value for SYNC\nPlease select True or False"
             .format(val))
     self._output_sync = val
     if self._output_sync:
         self._write("OUTP:SYNC ON")
     else:
         self._write("OUTP:SYNC OFF")
Exemple #12
0
 def __init__(self, initial_state):
     self._set_point = 0.0
     try:
         self._updated_value = float(initial_state)
     except ValueError as e:
         raise ParameterError(
             "initial_state found {}. Must be a number".format(
                 initial_state)) from e
     self._error_scalar = None
     self._error = None
     self._damp_factor = 0.8
Exemple #13
0
 def mode(self, value):
     """
     Creates the variable to set the mode configuration of the DMM
     param value: The string associated with the mode being set up
     raise: ParameterError if mode trying to be set is not valid
     """
     self._write("*rst")
     time.sleep(0.05)
     # do we need to set the default filter here?
     if value not in self._modes:
         raise ParameterError("Unknown mode {} for DMM".format(value))
     self._mode = value
Exemple #14
0
 def _write(self, data):
     """
     Writes data to the DMM
     raise: ParameterError if called with no data string
     """
     if data:
         if isinstance(data, str):
             self.instrument.write(data)
             time.sleep(0.05)
         else:
             for itm in data:
                 self.instrument.write(itm)
             time.sleep(0.05)
     else:
         raise ParameterError("Missing data in instrument write")
Exemple #15
0
 def _write(self, data):
     try:
         if data:
             if isinstance(data, str):
                 self.instrument.write(data)
                 time.sleep(self.write_delay)
             else:
                 for itm in data:
                     self.instrument.write(itm)
                     time.sleep(self.write_delay)
             # self._is_error()
         else:
             raise ParameterError("Missing data in instrument write")
     except VisaIOError as e:
         # TODO Write to log
         raise InstrumentError("Unknown IO error from read operation") from e
Exemple #16
0
 def create_digital_input(self, ident, *dio_ranges):
     """
     :param dio_ranges
     each dio_range is a tuple of ('port', 'range_start', 'range_end') or an IORange instance.
     A digital output is created in the order of the dio_ranges and can be accessed by the ident key.
     >>>daq = DaqMx()
     >>>rng_1 = IORange(0, 7, 9)  # Port 0 line 7 to line 9
     >>>rng_2 = IORange(0, 11,11) # Port 0 line 11
     >>>daq.create_digital_input("MyOut", rng_1, rng_2)
     >>>print(daq["MyOut"])  # Tie Port 0 line 8 and line 11 high
     >>>[0, 1, 0, 1]
     """
     if ident in self.tasks:
         raise ParameterError("Ident {} already used".format(ident))
     task_string, data_length = self._build_digital_task_string(*dio_ranges)
     self.tasks[ident] = DigitalIn(task_string, io_length=data_length)
Exemple #17
0
 def _write(self, data):
     """
     The DG1022 cannot respond to visa commands as quickly as some other devices
     A 100ms delay was found to be reliable for most commands with the exception of the *IDN?
     identification command. An extra 100ms should be allowed for explicit calls to *IDN?
     Note:
     The 6000 number for the sleep is derived from trial and error. The write calls don't seem to block at the rate
     they write. By allowing 166uS delay for each byte of data then the Funcgen doesn't choke on the next call. A
     flat 100ms is added to allow processing time.
     This is especially important for commands that write large amounts of data such as user arbitrary forms.
     """
     if data:
         if isinstance(data, str):
             data = data.split('\r\n')
         for itm in data:
             self.instrument.write(itm)
             time.sleep(0.1 + len(itm) / 6000)
     else:
         raise ParameterError("Missing data in instrument write")
     self._is_error()
Exemple #18
0
 def remote(self, val):
     if val not in [True, False]:
         raise ParameterError("remote must be True or False")
Exemple #19
0
 def remote(self, val):
     if val not in [True, False]:
         raise ParameterError("remote must be True or False")
     self.communicate(0x20, (val, 1))
     self._remote = val
Exemple #20
0
 def output_ch1(self, val):
     if val not in [True, False]:
         raise ParameterError("{} not True or False".format(val))
     self.communicate(0x21, (val, 1))
     self._output_ch1 = val