Example #1
0
class Uart():
    def __init__(self, path, baud=115200, read_timeout=1):
        self.impl = Serial(port=path, baudrate=baud, exclusive=True)
        self.read_timeout = read_timeout
        self.impl.reset_input_buffer()
        self.impl.reset_output_buffer()

    def __enter__(self, *args):
        self.impl.__enter__()
        return self

    def __exit__(self, *args):
        self.impl.__exit__()

    ''' Read data into buffer, return buffer '''

    def read(self):
        # Wait for data to be available
        self.impl.timeout = self.read_timeout
        self.impl.read(0)
        # Read as much data as is available in the buffer
        self.impl.timeout = 0
        return self.impl.read(self.impl.inWaiting())

    ''' Write data from buffer '''

    def write(self, data):
        self.impl.write(data)
Example #2
0
class Strip(object):
    def __init__(self,length,port):
        self._disp_length = length
        self._s = Serial(port, 115200*4, timeout=0.5)
        self._bar = [[0, 0, 0]]*self._disp_length
        self._commit()

    def blink(self, index, duration=0.1, dutycycle=0.5, color=None):
        assert duration >= 0
        self.set_bit(index, color)
        time.sleep(duration*dutycycle)
        self.clear_bit(index)
        time.sleep(duration*(1 - dutycycle))

    def wink(self, index, duration=0.1, dutycycle=0.5):
        assert duration >= 0
        color = self._bar[index - 1]
        self.clear_bit(index)
        time.sleep(duration*dutycycle)
        self.set_bit(index, color)
        time.sleep(duration*(1 - dutycycle))

    def set_bit(self, index, color):
        """Color is a tuple (R,G,B) where R, G, and B are numbers within [0,1]. Index starts from zero."""
        assert index >= 0 and index <= self._disp_length - 1, 'index should be within [0,length-1]'
        self._bar[index] = color
        self._commit()

    def clear_bit(self, index):
        assert index >= 0 and index <= self._disp_length - 1, 'index should be within [0,length-1]'
        self.set_bit(index, [0,0,0])

    def set_all(self, pixels):
        assert len(pixels) >= len(self._bar)
        assert len(pixels[0]) == 3
        assert pixels[0][0] >= 0 and pixels[0][0] <= 1
        self._bar = list(pixels[0:self._disp_length])
        self._commit()

    def _commit(self):
        write_led_strip(self._s, self._bar)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self._s.__exit__()

    def __del__(self):
        self._s.__del__()
Example #3
0
class MeerstetterTEC_USB(MeerstetterTEC):
    """
    Discrete implementation of the MeerstetterTEC class on an USB based interface
    """
    def __init__(self,
                 port,
                 timeout=1,
                 baudrate=57600,
                 tec_address=0,
                 check_crc=True):
        super().__init__(tec_address=tec_address, check_crc=check_crc)

        self.port = port
        self.timeout = timeout
        self.baudrate = baudrate

        self.ser = Serial(
            port=self.port,
            timeout=self.timeout,
            baudrate=self.baudrate,
        )

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.ser.__exit__(exc_type, exc_val, exc_tb)

    def __enter__(self):
        return self

    def stop(self):
        self.ser.flush()
        self.ser.close()

    def _sendAndReceive(self, frame):
        byte_arr = frame + b'\r'

        #clear all remaining buffers
        self.ser.reset_output_buffer()
        self.ser.reset_input_buffer()

        #send and flush
        self.ser.write(byte_arr)
        self.ser.flush()

        #read all in
        answer_arr = self.ser.read_until(terminator=b'\r')
        return answer_arr[0:-1]
Example #4
0
class Duck:
    def __init__(self, *serial_device_parameters):
        self.serial_device = Serial(*serial_device_parameters)
        init_serial(self.serial_device)

    def __enter__(self):
        self.serial_device.__enter__()
        return self

    def __exit__(self, *exp):
        self.serial_device.__exit__(*exp)

    def run(self, op="NOP", verbose=False, read=True):
        run_operation(self.serial_device, op, verbose, read)

    def buffer_ramp(self, dac_channel, adc_channel, begin_voltage, end_voltage,
                    number_of_steps, delay_in_microsecs):
        return _buffer_ramp(self.serial_device, dac_channel, adc_channel,
                            begin_voltage, end_voltage, number_of_steps,
                            delay_in_microsecs)
Example #5
0
class MeCom:
    """
    Main class. Import this one:
    from qao.devices.mecom import MeCom

    For a usage example see __main__
    """
    SEQUENCE_COUNTER = 1

    def __init__(self, serialport="/dev/ttyUSB0", timeout=1, baudrate=57600):
        """
        Initialize communication with serial port.
        :param serialport: str
        :param timeout: int
        """
        # initialize serial connection
        self.ser = Serial(port=serialport,
                          timeout=timeout,
                          write_timeout=timeout,
                          baudrate=baudrate)

        # start protocol thread
        # self.protocol = ReaderThread(serial_instance=self.ser, protocol_factory=MePacket)
        # self.receiver = self.protocol.__enter__()

        # initialize parameters
        self.PARAMETERS = ParameterList()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.ser.__exit__(exc_type, exc_val, exc_tb)

    def __enter__(self):
        return self

    def stop(self):
        self.ser.flush()
        self.ser.close()

    def _find_parameter(self, parameter_name, parameter_id):
        """
        Return Parameter() with either name or id given.
        :param parameter_name: str
        :param parameter_id: int
        :return: Parameter
        """
        return self.PARAMETERS.get_by_name(parameter_name) if parameter_name is not None\
            else self.PARAMETERS.get_by_id(parameter_id)

    def _inc(self):
        self.SEQUENCE_COUNTER += 1

    @staticmethod
    def _raise(query):
        """
        If DeviceError is received, raise!
        :param query: VR or VS
        :return:
        """
        # did we encounter an error?
        if type(query.RESPONSE) is DeviceError:
            code, description, symbol = query.RESPONSE.error()
            raise ResponseException("device {} raised {}".format(
                query.RESPONSE.ADDRESS, description))

    def _read(self, size):
        """
        Read n=size bytes from serial, if <n bytes are received (serial.read() return because of timeout), raise a timeout.
        """
        recv = self.ser.read(size=size)
        if len(recv) < size:
            raise ResponseTimeout("timeout while communication via serial")
        else:
            return recv

    def _execute(self, query):
        # clear buffers
        self.ser.reset_output_buffer()
        self.ser.reset_input_buffer()

        # send query
        self.ser.write(query.compose())
        # print(query.compose())

        # flush write cache
        self.ser.flush()

        # initialize response and carriage return
        cr = "\r".encode()
        response_frame = b''
        response_byte = self._read(
            size=1
        )  # read one byte at a time, timeout is set on instance level

        # read until stop byte
        while response_byte != cr:
            response_frame += response_byte
            response_byte = self._read(size=1)

        # strip source byte (! or #, but for a response always !)
        response_frame = response_frame[1:]

        # print(response_frame)
        query.set_response(response_frame)

        # did we encounter an error?
        self._raise(query)

        return query

    def _get(self, parameter_name=None, parameter_id=None, *args, **kwargs):
        """
        Get a query object for a VR command.
        :param parameter_name:
        :param parameter_id:
        :param args:
        :param kwargs:
        :return:
        """
        assert parameter_name is not None or parameter_id is not None

        # search in DataFrame returns a dict
        parameter = self._find_parameter(parameter_name, parameter_id)

        # execute query
        vr = self._execute(
            VR(parameter=parameter,
               sequence=self.SEQUENCE_COUNTER,
               *args,
               **kwargs))

        # increment sequence counter
        self._inc()
        # print(vr.PAYLOAD)
        # print(vr.RESPONSE.PAYLOAD)
        # return the query with response
        return vr

    def _set(self,
             value,
             parameter_name=None,
             parameter_id=None,
             *args,
             **kwargs):
        """
        Get a query object for a VS command.
        :param value:
        :param parameter_name:
        :param parameter_id:
        :param args:
        :param kwargs:
        :return:
        """
        assert parameter_name is not None or parameter_id is not None

        # search in DataFrame returns a dict
        parameter = self._find_parameter(parameter_name, parameter_id)

        # execute query
        vs = self._execute(
            VS(value=value,
               parameter=parameter,
               sequence=self.SEQUENCE_COUNTER,
               *args,
               **kwargs))

        # increment sequence counter
        self._inc()

        # return the query with response
        return vs

    def reset(self, *args, **kwargs):
        """
        Send the RS command to the device.
        :param args:
        :param kwargs:
        :return:
        """
        # execute query
        rs = self._execute(RS(sequence=self.SEQUENCE_COUNTER, *args, **kwargs))
        # increment sequence counter
        self._inc()

        # return the query with response
        return rs

    def get_parameter(self,
                      parameter_name=None,
                      parameter_id=None,
                      *args,
                      **kwargs):
        """
        Get the value of a parameter given by name or id.
        Returns a list of success and value.
        :param parameter_name:
        :param parameter_id:
        :param args:
        :param kwargs:
        :return: int or float
        """
        # get the query object
        vr = self._get(parameter_id=parameter_id,
                       parameter_name=parameter_name,
                       *args,
                       **kwargs)

        return vr.RESPONSE.PAYLOAD[0]

    def set_parameter(self,
                      value,
                      parameter_name=None,
                      parameter_id=None,
                      *args,
                      **kwargs):
        """
        Set the new value of a parameter given by name or id.
        Performs an immediate get_parameter to check success.
        Returns success and new value.
        :param value:
        :param parameter_name:
        :param parameter_id:
        :param args:
        :param kwargs:
        :return: bool
        """
        # get the query object
        vs = self._set(value=value,
                       parameter_id=parameter_id,
                       parameter_name=parameter_name,
                       *args,
                       **kwargs)

        # check if value setting has succeeded
        value_set = self.get_parameter(parameter_id=parameter_id,
                                       parameter_name=parameter_name,
                                       *args,
                                       **kwargs)

        # return True if the values are equal
        return value == value_set

    # returns device address
    identify = partialmethod(get_parameter, parameter_name="Device Address")
    """
    Returns success and device address as int.
    """

    def status(self, *args, **kwargs):
        """
        Get the device status.
        Returns success and status as readable str.
        :param args:
        :param kwargs:
        :return: [bool, str]
        """
        # query device status
        status_id = self.get_parameter(parameter_name="Device Status",
                                       *args,
                                       **kwargs)

        if status_id == 0:
            status_name = "Init"
        elif status_id == 1:
            status_name = "Ready"
        elif status_id == 2:
            status_name = "Run"
        elif status_id == 3:
            status_name = "Error"
        elif status_id == 4:
            status_name = "Bootloader"
        elif status_id == 5:
            status_name = "Device will Reset within next 200ms"
        else:
            status_name = "Unknown"

        # return address and status
        return status_name

    # enable or disable auto saving to flash
    enable_autosave = partialmethod(set_parameter,
                                    value=0,
                                    parameter_name="Save Data to Flash")
    disable_autosave = partialmethod(set_parameter,
                                     value=1,
                                     parameter_name="Save Data to Flash")

    def write_to_flash(self, *args, **kwargs):
        """
        Write parameters to flash.
        :param args:
        :param kwargs:
        :return: bool
        """
        self.enable_autosave()
        timer_start = time.time()

        # value 0 means "All Parameters are saved to Flash"
        while self.get_parameter(parameter_name="Flash Status") != 0:
            # check for timeout
            if time.time() - timer_start > 10:
                raise ResponseTimeout("writing to flash timed out!")
            time.sleep(0.5)

        self.disable_autosave()

        return True
Example #6
0
class TEC_Serial(TEC):
    """
    Discrete implementation of the TEC class on an USB based interface
    """
    def __init__(self,
                 port,
                 timeout=1,
                 baudrate=57600,
                 tec_address=0,
                 check_crc=True):
        super().__init__(tec_address=tec_address, check_crc=check_crc)

        self.port = port
        self.timeout = timeout
        self.baudrate = baudrate

        self.ser = Serial(
            port=self.port,
            timeout=self.timeout,
            baudrate=self.baudrate,
        )
        self.ser.flush()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.ser.__exit__(exc_type, exc_val, exc_tb)

    def __enter__(self):
        return self

    def stop(self):
        self.ser.flush()
        self.ser.close()

    def _send_and_receive(self, frame):
        byte_arr = frame + b'\r'

        #clear all remaining buffers
        self.ser.reset_output_buffer()
        self.ser.reset_input_buffer()

        #send and flush
        self.ser.write(byte_arr)
        self.ser.flush()

        #read all in
        answer_arr = self.ser.read_until(b'\r')
        return answer_arr[0:-1]

    def _send_and_ignore_receive(self, frame):
        byte_arr = frame + b'\r'

        #clear all remaining buffers
        self.ser.reset_output_buffer()
        self.ser.reset_input_buffer()

        #send and flush
        self.ser.write(byte_arr)
        self.ser.flush()

        #wait for first answer and discard if tec_address is not 255
        if self.tec_address != 255:
            self.ser.read()
            self.ser.flush()

    def _speed_changed(self, speed):
        self.baudrate = speed
        self.ser.baudrate = speed