예제 #1
0
 def test_open_close(self):
     for id in (1, '/dev/i2c-alias'):
         bus = SMBus()
         self.assertIsNone(bus.fd)
         bus.open(id)
         self.assertIsNotNone(bus.fd)
         bus.close()
         self.assertIsNone(bus.fd)
예제 #2
0
class AntennaDeployer(Device):
    BUS_NUMBER = 1
    PRIMARY_ADDRESS = 0x31
    SECONDARY_ADDRESS = 0x32
    EXPECTED_BYTES = {
        AntennaDeployerCommand.SYSTEM_RESET: 0,
        AntennaDeployerCommand.WATCHDOG_RESET: 0,

        AntennaDeployerCommand.ARM_ANTS: 0,
        AntennaDeployerCommand.DISARM_ANTS: 0,

        AntennaDeployerCommand.DEPLOY_1: 0,
        AntennaDeployerCommand.DEPLOY_2: 0,
        AntennaDeployerCommand.DEPLOY_3: 0,
        AntennaDeployerCommand.DEPLOY_4: 0,

        AntennaDeployerCommand.AUTO_DEPLOY: 0,
        AntennaDeployerCommand.CANCEL_DEPLOY: 0,

        AntennaDeployerCommand.DEPLOY_1_OVERRIDE: 0,
        AntennaDeployerCommand.DEPLOY_2_OVERRIDE: 0,
        AntennaDeployerCommand.DEPLOY_3_OVERRIDE: 0,
        AntennaDeployerCommand.DEPLOY_4_OVERRIDE: 0,

        AntennaDeployerCommand.GET_TEMP: 2,
        AntennaDeployerCommand.GET_STATUS: 2,

        AntennaDeployerCommand.GET_COUNT_1: 1,
        AntennaDeployerCommand.GET_COUNT_2: 1,
        AntennaDeployerCommand.GET_COUNT_3: 1,
        AntennaDeployerCommand.GET_COUNT_4: 1,

        AntennaDeployerCommand.GET_UPTIME_1: 2,
        AntennaDeployerCommand.GET_UPTIME_2: 2,
        AntennaDeployerCommand.GET_UPTIME_3: 2,
        AntennaDeployerCommand.GET_UPTIME_4: 2,
    }

    def __init__(self):
        super().__init__("AntennaDeployer")
        self.bus = SMBus()

    def write(self, command: AntennaDeployerCommand, parameter: int) -> bool or None:
        """
        Wrapper for SMBus write word data
        :param command: (AntennaDeployerCommand) The antenna deployer command to run
        :param parameter: (int) The parameter to pass in to the command (usually 0x00)
        :return: (bool or None) success
        """
        if type(command) != AntennaDeployerCommand:
            return

        try:
            self.bus.open(self.BUS_NUMBER)
            self.bus.write_word_data(self.PRIMARY_ADDRESS, command.value, parameter)
            self.bus.close()
        except:
            return False

        return True

    def read(self, command: AntennaDeployerCommand) -> bytes or None:
        """
        Wrapper for SMBus to read from AntennaDeployer
        :param command: (AntennaDeployerCommand) The antenna deployer command to run
        :return: (ctypes.LP_c_char, bool) buffer, success
        """
        if type(command) != AntennaDeployerCommand:
            return

        success = self.write(command, 0x00)
        if not success:
            return None, False

        time.sleep(0.5)
        try:
            i2c_obj = i2c_msg.read(self.PRIMARY_ADDRESS, self.EXPECTED_BYTES[command])
            self.bus.open(self.BUS_NUMBER)
            self.bus.i2c_rdwr(i2c_obj)
            self.bus.close()
            return i2c_obj.buf, True
        except:
            return None, False

    def functional(self):
        """
        :return: (bool) i2c file opened by SMBus
        """
        return self.bus.fd is not None

    def reset(self):
        """
        Resets the Microcontroller on the ISIS Antenna Deployer
        :return: (bool) no error
        """
        try:
            self.bus.open(self.BUS_NUMBER)
            self.write(AntennaDeployerCommand.SYSTEM_RESET, 0x00)
            self.bus.close()
            return True
        except:
            return False

    def disable(self):
        """
        Disarms the ISIS Antenna Deployer
        """
        try:
            self.bus.open(self.BUS_NUMBER)
            self.write(AntennaDeployerCommand.DISARM_ANTS, 0x00)
            self.bus.close()
            return True
        except:
            return False

    def enable(self):
        """
        Arms the ISIS Antenna Deployer
        """
        try:
            self.bus.open(self.BUS_NUMBER)
            self.write(AntennaDeployerCommand.ARM_ANTS, 0x00)
            self.bus.close()
            return True
        except:
            return False
Signal processing
'''

t = np.arange(0, N / Fbit, 1 / Fs)  # time to send all bits
m = np.zeros(0)
for bit in data_in:
    if bit == 0:
        m = np.hstack((m, np.multiply(np.ones(int(Fs / Fbit)), Fc - Fdev)))
    else:
        m = np.hstack((m, np.multiply(np.ones(int(Fs / Fbit)), Fc + Fdev)))

y = np.zeros(0)
y = A * np.cos(2 * np.pi * np.multiply(m, t)) + zero_line
'''
Signal sending
'''

port = SMBus(bus=i2c_folder)
port.open(i2c_folder)
time_point = 0
input('Press Enter to start')
GPIO.output('P8_7', GPIO.HIGH)  # Trigger line high
for i in y:
    i = int(i)
    while time.time() - time_point < DAC_T:  # Time management control
        None
    send(i)
    time_point = time.time()
GPIO.output('P8_7', GPIO.LOW)  # Trigger line low
port.close()
예제 #4
0
class VL53L1X:
    """VL53L1X ToF."""
    def __init__(self,
                 i2c_bus=1,
                 i2c_address=0x29,
                 tca9548a_num=255,
                 tca9548a_addr=0):
        """Initialize the VL53L1X ToF Sensor from ST"""
        self._i2c_bus = i2c_bus
        self.i2c_address = i2c_address
        self._tca9548a_num = tca9548a_num
        self._tca9548a_addr = tca9548a_addr

        self._i2c = SMBus(i2c_bus)
        try:
            if tca9548a_num == 255:
                self._i2c.read_byte_data(self.i2c_address, 0x00)
        except IOError:
            raise RuntimeError("VL53L1X not found on adddress: {:02x}".format(
                self.i2c_address))

        self._dev = None
        # Register Address
        self.ADDR_UNIT_ID_HIGH = 0x16  # Serial number high byte
        self.ADDR_UNIT_ID_LOW = 0x17  # Serial number low byte
        self.ADDR_I2C_ID_HIGH = 0x18  # Write serial number high byte for I2C address unlock
        self.ADDR_I2C_ID_LOW = 0x19  # Write serial number low byte for I2C address unlock
        self.ADDR_I2C_SEC_ADDR = 0x8a  # Write new I2C address after unlock

    def open(self, reset=False):
        self._i2c.open(bus=self._i2c_bus)
        self._configure_i2c_library_functions()
        self._dev = _TOF_LIBRARY.initialise(self.i2c_address,
                                            self._tca9548a_num,
                                            self._tca9548a_addr, reset)

    def close(self):
        self._i2c.close()
        self._dev = None

    def _configure_i2c_library_functions(self):
        # I2C bus read callback for low level library.
        def _i2c_read(address, reg, data_p, length):
            ret_val = 0

            msg_w = i2c_msg.write(address, [reg >> 8, reg & 0xff])
            msg_r = i2c_msg.read(address, length)

            self._i2c.i2c_rdwr(msg_w, msg_r)

            if ret_val == 0:
                for index in range(length):
                    data_p[index] = ord(msg_r.buf[index])

            return ret_val

        # I2C bus write callback for low level library.
        def _i2c_write(address, reg, data_p, length):
            ret_val = 0
            data = []

            for index in range(length):
                data.append(data_p[index])

            msg_w = i2c_msg.write(address, [reg >> 8, reg & 0xff] + data)

            self._i2c.i2c_rdwr(msg_w)

            return ret_val

        # I2C bus write callback for low level library.
        def _i2c_multi(address, reg):
            ret_val = 0

            # Write to the multiplexer
            self._i2c.write_byte(address, reg)

            return ret_val

        # Pass i2c read/write function pointers to VL53L1X library.
        self._i2c_multi_func = _I2C_MULTI_FUNC(_i2c_multi)
        self._i2c_read_func = _I2C_READ_FUNC(_i2c_read)
        self._i2c_write_func = _I2C_WRITE_FUNC(_i2c_write)
        _TOF_LIBRARY.VL53L1_set_i2c(self._i2c_multi_func, self._i2c_read_func,
                                    self._i2c_write_func)

    def start_ranging(self, mode=VL53L1xDistanceMode.LONG):
        """Start VL53L1X ToF Sensor Ranging"""
        _TOF_LIBRARY.startRanging(self._dev, mode)

    def set_distance_mode(self, mode):
        """Set distance mode

        :param mode: One of 1 = Short, 2 = Medium or 3 = Long

        """
        _TOF_LIBRARY.setDistanceMode(self._dev, mode)

    def stop_ranging(self):
        """Stop VL53L1X ToF Sensor Ranging"""
        _TOF_LIBRARY.stopRanging(self._dev)

    def get_distance(self):
        """Get distance from VL53L1X ToF Sensor"""
        return _TOF_LIBRARY.getDistance(self._dev)

    def set_timing(self, timing_budget, inter_measurement_period):
        """Set the timing budget and inter measurement period.

        A higher timing budget results in greater measurement accuracy,
        but also a higher power consumption.

        The inter measurement period must be >= the timing budget, otherwise
        it will be double the expected value.

        :param timing_budget: Timing budget in microseconds
        :param inter_measurement_period: Inter Measurement Period in milliseconds

        """
        if (inter_measurement_period * 1000) < timing_budget:
            raise ValueError(
                "The Inter Measurement Period must be >= Timing Budget")

        self.set_timing_budget(timing_budget)
        self.set_inter_measurement_period(inter_measurement_period)

    def set_timing_budget(self, timing_budget):
        """Set the timing budget in microseocnds"""
        _TOF_LIBRARY.setMeasurementTimingBudgetMicroSeconds(
            self._dev, timing_budget)

    def set_inter_measurement_period(self, period):
        """Set the inter-measurement period in milliseconds"""
        _TOF_LIBRARY.setInterMeasurementPeriodMilliSeconds(self._dev, period)

    # This function included to show how to access the ST library directly
    # from python instead of through the simplified interface
    def get_timing(self):
        budget = c_uint(0)
        budget_p = pointer(budget)
        status = _TOF_LIBRARY.VL53L1_GetMeasurementTimingBudgetMicroSeconds(
            self._dev, budget_p)
        if status == 0:
            return budget.value + 1000
        else:
            return 0

    def change_address(self, new_address):
        status = _TOF_LIBRARY.setDeviceAddress(self._dev, new_address)
        if status == 0:
            self.i2c_address = new_address
        else:
            raise RuntimeError(
                "change_address failed with code: {}".format(status))
        return True

    def get_RangingMeasurementData(self):
        '''
        Returns the full RangingMeasurementData structure.
        (it ignores the fields that are not implemented according to en.DM00474730.pdf)
        '''
        contents = _getRangingMeasurementData(self._dev).contents
        return {
            'StreamCount': contents.StreamCount,
            'SignalRateRtnMegaCps': contents.SignalRateRtnMegaCps / 65536,
            'AmbientRateRtnMegaCps': contents.AmbientRateRtnMegaCps / 65536,
            'EffectiveSpadRtnCount': contents.EffectiveSpadRtnCount / 256,
            'SigmaMilliMeter': contents.SigmaMilliMeter / 65536,
            'RangeMilliMeter': contents.RangeMilliMeter,
            'RangeStatus': contents.RangeStatus
        }
예제 #5
0
class EPS(Device):
    BUS_NAME = '/dev/i2c-1'
    ADDRESS = 0x57

    def __init__(self):
        super().__init__("EPS")
        self.bus = SMBus()

    def is_open(self) -> bool:
        return self.bus.fd is not None

    def write_i2c_block_response(self, register: EPSRegister,
                                 data) -> bytes or None:
        if type(register) != EPSRegister:
            return

        self.write_i2c_block_data(register, data)
        return self.read_byte()

    def write_byte_response(self, register: EPSRegister,
                            value) -> bytes or None:
        if type(register) != EPSRegister:
            return

        self.write_byte_data(register, value)
        return self.read_byte()

    def read_byte_data(self, register: EPSRegister) -> bytes or None:
        if type(register) != EPSRegister:
            return

        self.bus.open(self.BUS_NAME)
        next_byte = self.bus.read_byte_data(self.ADDRESS, register.value)
        self.bus.close()
        return next_byte

    def read_byte(self) -> bytes or None:
        self.bus.open(self.BUS_NAME)
        next_byte = self.bus.read_byte(self.ADDRESS)
        self.bus.close()
        return next_byte

    def write_i2c_block_data(self, register: EPSRegister, data):
        if type(register) != EPSRegister:
            return

        self.bus.open(self.BUS_NAME)
        self.bus.write_i2c_block_data(self.ADDRESS, register.value, data)
        self.bus.close()

    def write_byte_data(self, register: EPSRegister, value):
        if type(register) != EPSRegister:
            return

        self.bus.open(self.BUS_NAME)
        self.bus.write_byte_data(self.ADDRESS, register.value, value)
        self.bus.close()

    def functional(self):
        raise NotImplementedError

    def reset(self):
        raise NotImplementedError

    def disable(self):
        raise NotImplementedError

    def enable(self):
        raise NotImplementedError
예제 #6
0
class VL53L1X:
    """VL53L1X ToF."""
    def __init__(self,
                 i2c_bus=1,
                 i2c_address=0x29,
                 tca9548a_num=255,
                 tca9548a_addr=0):
        """Initialize the VL53L1X ToF Sensor from ST"""
        self._i2c_bus = i2c_bus
        self.i2c_address = i2c_address
        self._tca9548a_num = tca9548a_num
        self._tca9548a_addr = tca9548a_addr
        self._i2c = SMBus(1)
        self._dev = None
        # Resgiter Address
        self.ADDR_UNIT_ID_HIGH = 0x16  # Serial number high byte
        self.ADDR_UNIT_ID_LOW = 0x17  # Serial number low byte
        self.ADDR_I2C_ID_HIGH = 0x18  # Write serial number high byte for I2C address unlock
        self.ADDR_I2C_ID_LOW = 0x19  # Write serial number low byte for I2C address unlock
        self.ADDR_I2C_SEC_ADDR = 0x8a  # Write new I2C address after unlock

    def open(self):
        self._i2c.open(bus=self._i2c_bus)
        self._configure_i2c_library_functions()
        self._dev = _TOF_LIBRARY.initialise(self.i2c_address)

    def close(self):
        self._i2c.close()
        self._dev = None

    def _configure_i2c_library_functions(self):
        # I2C bus read callback for low level library.
        def _i2c_read(address, reg, data_p, length):
            ret_val = 0

            msg_w = i2c_msg.write(address, [reg >> 8, reg & 0xff])
            msg_r = i2c_msg.read(address, length)

            self._i2c.i2c_rdwr(msg_w, msg_r)

            if ret_val == 0:
                for index in range(length):
                    data_p[index] = ord(msg_r.buf[index])

            return ret_val

        # I2C bus write callback for low level library.
        def _i2c_write(address, reg, data_p, length):
            ret_val = 0
            data = []

            for index in range(length):
                data.append(data_p[index])

            msg_w = i2c_msg.write(address, [reg >> 8, reg & 0xff] + data)

            self._i2c.i2c_rdwr(msg_w)

            return ret_val

        # Pass i2c read/write function pointers to VL53L1X library.
        self._i2c_read_func = _I2C_READ_FUNC(_i2c_read)
        self._i2c_write_func = _I2C_WRITE_FUNC(_i2c_write)
        _TOF_LIBRARY.VL53L1_set_i2c(self._i2c_read_func, self._i2c_write_func)

    def start_ranging(self, mode=VL53L1xDistanceMode.LONG):
        """Start VL53L1X ToF Sensor Ranging"""
        _TOF_LIBRARY.startRanging(self._dev, mode)

    def stop_ranging(self):
        """Stop VL53L1X ToF Sensor Ranging"""
        _TOF_LIBRARY.stopRanging(self._dev)

    def get_distance(self):
        """Get distance from VL53L1X ToF Sensor"""
        return _TOF_LIBRARY.getDistance(self._dev)

    # This function included to show how to access the ST library directly
    # from python instead of through the simplified interface
    def get_timing(self):
        budget = c_uint(0)
        budget_p = pointer(budget)
        status = _TOF_LIBRARY.VL53L1_GetMeasurementTimingBudgetMicroSeconds(
            self._dev, budget_p)
        if status == 0:
            return budget.value + 1000
        else:
            return 0

    def change_address(self, new_address):
        _TOF_LIBRARY.setDeviceAddress(self._dev, new_address)
예제 #7
0
class VL53L1X:
    """VL53L1X ToF."""
    def __init__(self, i2c_bus=1):
        """Initialize the VL53L1X ToF Sensor from ST"""
        self._i2c_bus = i2c_bus
        self._i2c = SMBus(1)
        self._default_dev = None
        self._dev_list = None

        # Resgiter Address
        self.ADDR_UNIT_ID_HIGH = 0x16  # Serial number high byte
        self.ADDR_UNIT_ID_LOW = 0x17  # Serial number low byte
        self.ADDR_I2C_ID_HIGH = 0x18  # Write serial number high byte for I2C address unlock
        self.ADDR_I2C_ID_LOW = 0x19  # Write serial number low byte for I2C address unlock
        self.ADDR_I2C_SEC_ADDR = 0x8a  # Write new I2C address after unlock

    def open(self):
        self._i2c.open(bus=self._i2c_bus)
        self._configure_i2c_library_functions()
        self._default_dev = _TOF_LIBRARY.initialise()
        self._dev_list = dict()

    def add_sensor(self, sensor_id, address):
        self._dev_list[sensor_id] = _TOF_LIBRARY.copy_dev(self._default_dev)
        _TOF_LIBRARY.init_dev(self._dev_list[sensor_id], c_uint8(address))

    def close(self):
        self._i2c.close()
        self._default_dev = None
        self._dev_list = None

    def _configure_i2c_library_functions(self):
        # I2C bus read callback for low level library.
        def _i2c_read(address, reg, data_p, length):
            ret_val = 0

            msg_w = i2c_msg.write(address, [reg >> 8, reg & 0xff])
            msg_r = i2c_msg.read(address, length)

            # print("R: a: %x\tr:%d" % (address,reg))
            try:
                self._i2c.i2c_rdwr(msg_w, msg_r)
            except:
                print("Cannot read on 0x%x I2C bus, reg: %d" % (address, reg))

            if ret_val == 0:
                for index in range(length):
                    data_p[index] = ord(msg_r.buf[index])

            return ret_val

        # I2C bus write callback for low level library.
        def _i2c_write(address, reg, data_p, length):
            ret_val = 0
            data = []

            for index in range(length):
                data.append(data_p[index])

            msg_w = i2c_msg.write(address, [reg >> 8, reg & 0xff] + data)
            # print("W: a: %x\tr:%d" % (address,reg))

            try:
                self._i2c.i2c_rdwr(msg_w)
            except:
                print("Cannot write on 0x%x I2C bus, reg: %d" % (address, reg))

            return ret_val

        # Pass i2c read/write function pointers to VL53L1X library.
        self._i2c_read_func = _I2C_READ_FUNC(_i2c_read)
        self._i2c_write_func = _I2C_WRITE_FUNC(_i2c_write)
        _TOF_LIBRARY.VL53L1_set_i2c(self._i2c_read_func, self._i2c_write_func)

    def start_ranging(self, sensor_id, mode=VL53L1xDistanceMode.LONG):
        """Start VL53L1X ToF Sensor Ranging"""
        dev = self._dev_list[sensor_id]
        _TOF_LIBRARY.startRanging(dev, mode)

    def stop_ranging(self, sensor_id):
        """Stop VL53L1X ToF Sensor Ranging"""
        dev = self._dev_list[sensor_id]
        _TOF_LIBRARY.stopRanging(dev)

    def get_distance(self, sensor_id):
        dev = self._dev_list[sensor_id]
        return _TOF_LIBRARY.getDistance(dev)

    def get_address(self, sensor_id):
        dev = self._dev_list[sensor_id]
        return _TOF_LIBRARY.get_address(dev)

    def change_address(self, sensor_id, new_address):
        dev = self._dev_list[sensor_id]
        _TOF_LIBRARY.setDeviceAddress(dev, new_address)
예제 #8
0
class VL53L1X:
    """VL53L1X ToF."""
    def __init__(self, i2c_bus=1, i2c_address=0x29, tca9548a_num=255, tca9548a_addr=0):
        """Initialize the VL53L1X ToF Sensor from ST"""
        self._i2c_bus = i2c_bus
        self.i2c_address = i2c_address
        self._tca9548a_num = tca9548a_num
        self._tca9548a_addr = tca9548a_addr

        self._i2c = SMBus()
        if tca9548a_num == 255:
            try:
                self._i2c.open(bus=self._i2c_bus)
                self._i2c.read_byte_data(self.i2c_address, 0x00)
            except IOError:
                raise RuntimeError("VL53L1X not found on adddress: {:02x}".format(self.i2c_address))
            finally:
                self._i2c.close()

        self._dev = None
        # Register Address
        self.ADDR_UNIT_ID_HIGH = 0x16  # Serial number high byte
        self.ADDR_UNIT_ID_LOW = 0x17   # Serial number low byte
        self.ADDR_I2C_ID_HIGH = 0x18   # Write serial number high byte for I2C address unlock
        self.ADDR_I2C_ID_LOW = 0x19    # Write serial number low byte for I2C address unlock
        self.ADDR_I2C_SEC_ADDR = 0x8a  # Write new I2C address after unlock

    def open(self, reset=False):
        self._i2c.open(bus=self._i2c_bus)
        self._configure_i2c_library_functions()
        self._dev = _TOF_LIBRARY.initialise(self.i2c_address, self._tca9548a_num, self._tca9548a_addr, reset)

    def close(self):
        self._i2c.close()
        self._dev = None

    def _configure_i2c_library_functions(self):
        # I2C bus read callback for low level library.
        def _i2c_read(address, reg, data_p, length):
            ret_val = 0

            msg_w = i2c_msg.write(address, [reg >> 8, reg & 0xff])
            msg_r = i2c_msg.read(address, length)

            self._i2c.i2c_rdwr(msg_w, msg_r)

            if ret_val == 0:
                for index in range(length):
                    data_p[index] = ord(msg_r.buf[index])

            return ret_val

        # I2C bus write callback for low level library.
        def _i2c_write(address, reg, data_p, length):
            ret_val = 0
            data = []

            for index in range(length):
                data.append(data_p[index])

            msg_w = i2c_msg.write(address, [reg >> 8, reg & 0xff] + data)

            self._i2c.i2c_rdwr(msg_w)

            return ret_val

        # I2C bus write callback for low level library.
        def _i2c_multi(address, reg):
            ret_val = 0

            # Write to the multiplexer
            self._i2c.write_byte(address, reg)

            return ret_val

        # Pass i2c read/write function pointers to VL53L1X library.
        self._i2c_multi_func = _I2C_MULTI_FUNC(_i2c_multi)
        self._i2c_read_func = _I2C_READ_FUNC(_i2c_read)
        self._i2c_write_func = _I2C_WRITE_FUNC(_i2c_write)
        _TOF_LIBRARY.VL53L1_set_i2c(self._i2c_multi_func, self._i2c_read_func, self._i2c_write_func)

    # The ROI is a square or rectangle defined by two corners: top left and bottom right.
    # Default ROI is 16x16 (indices 0-15). The minimum ROI size is 4x4.
    def set_user_roi(self, user_roi):
        """Set Region Of Interest (ROI)"""
        _TOF_LIBRARY.setUserRoi(self._dev,
                                user_roi.top_left_x,
                                user_roi.top_left_y,
                                user_roi.bot_right_x,
                                user_roi.bot_right_y)

    def start_ranging(self, mode=VL53L1xDistanceMode.LONG):
        """Start VL53L1X ToF Sensor Ranging"""
        _TOF_LIBRARY.startRanging(self._dev, mode)

    def set_distance_mode(self, mode):
        """Set distance mode

        :param mode: One of 1 = Short, 2 = Medium or 3 = Long

        """
        _TOF_LIBRARY.setDistanceMode(self._dev, mode)

    def stop_ranging(self):
        """Stop VL53L1X ToF Sensor Ranging"""
        _TOF_LIBRARY.stopRanging(self._dev)

    def get_distance(self):
        """Get distance from VL53L1X ToF Sensor"""
        return _TOF_LIBRARY.getDistance(self._dev)

    def set_timing(self, timing_budget, inter_measurement_period):
        """Set the timing budget and inter measurement period.

        A higher timing budget results in greater measurement accuracy,
        but also a higher power consumption.

        The inter measurement period must be >= the timing budget, otherwise
        it will be double the expected value.

        :param timing_budget: Timing budget in microseconds
        :param inter_measurement_period: Inter Measurement Period in milliseconds

        """
        if (inter_measurement_period * 1000) < timing_budget:
            raise ValueError("The Inter Measurement Period must be >= Timing Budget")

        self.set_timing_budget(timing_budget)
        self.set_inter_measurement_period(inter_measurement_period)

    def set_timing_budget(self, timing_budget):
        """Set the timing budget in microseocnds"""
        _TOF_LIBRARY.setMeasurementTimingBudgetMicroSeconds(self._dev, timing_budget)

    def set_inter_measurement_period(self, period):
        """Set the inter-measurement period in milliseconds"""
        _TOF_LIBRARY.setInterMeasurementPeriodMilliSeconds(self._dev, period)

    # This function included to show how to access the ST library directly
    # from python instead of through the simplified interface
    def get_timing(self):
        budget = c_uint(0)
        budget_p = pointer(budget)
        status = _TOF_LIBRARY.VL53L1_GetMeasurementTimingBudgetMicroSeconds(self._dev, budget_p)
        if status == 0:
            return budget.value + 1000
        else:
            return 0

    def change_address(self, new_address):
        status = _TOF_LIBRARY.setDeviceAddress(self._dev, new_address)
        if status == 0:
            self.i2c_address = new_address
        else:
            raise RuntimeError("change_address failed with code: {}".format(status))
        return True