def __init__(self, i2c): ''' Initialize mechanisms used by the ignition computer to interface with the flight computer. Right now, the coprocessors communicate over I2C due to the short rnage involved ''' try: self._sc_device = I2CDevice(i2c, Const.I2C_ADDR_SC) except ValueError: print("[ECI] Error initializing SC device") try: self._ec_device = I2CDevice(i2c, Const.I2C_ADDR_EC) except ValueError: print("[ECI] Error initializing EC device") self._buf = bytearray(1) self.updateFailed = False self.SCVState = False self.ecCommand = 0b0 self.firstrun = False self.state = {'MV_S1': None, 'MV_R1': None, 'MV_R1_moving': None, 'MV_G1': None, 'eMatch': None} self.update() self.SCVState = self.state['MV_G1']
def __init__(self, bus, addr=None, gain=GAIN_1X, debug=False): if isinstance(bus, busio.I2C): self._write_read = self._write_read_i2c if addr is None: self.device = I2CDevice(bus, 0xC0) else: self.device = I2CDevice(bus, addr) elif isinstance(bus, busio.SPI): self._write_read = self._write_read_spi if addr is None: import digitalio, board self.device = SPIDevice(bus, digitalio.DigitalInOut(board.CE0)) else: self.device = SPIDevice(bus, addr) else: assert False, "Invalid bus" self._debug = debug self._status_last = 0 self._res_current = _RES_2_15 self._gain_current = gain # Put the device in a known state to start self.reset() # Set gain to the supplied level self.gain = self._gain_current
def __init__(self, i2c1_bus, i2c2_bus, force=False): ## Setup pins so that statue upon switchign to output ## is identical to the board electrical default. This ## allows object to be created an no state change occur. self.pin_rst = digitalio.DigitalInOut(board.USBRESET) self.pin_rst.switch_to_output(value=True) self.pin_hen = digitalio.DigitalInOut(board.USBHOSTEN) self.pin_hen.switch_to_output(value=False) try: self.pin_bcen = digitalio.DigitalInOut(board.USBBCEN) self.pin_bcen.switch_to_output(value=False) except AttributeError: stdout( "WARN : Firmware does not define pin for battery charge configuration" ) self.pin_bcen = None self.vlim = analogio.AnalogIn(board.ANVLIM) self.vlogic = analogio.AnalogIn(board.AN5V) self.i2c_device = I2CDevice(i2c2_bus, _I2C_ADDR_USB, probe=False) self.mcp_device = I2CDevice(i2c1_bus, _I2C_ADDR_MCP, probe=False) self.eeprom = capablerobot_eeprom.EEPROM(i2c1_bus, '24AA025E48') ## Load default configuration and then check filesystem for INI file to update it self.config = dict(highspeed_disable=False, loop_delay=0.1, external_heartbeat=False, force=False, reset_on_delay=False, reset_on_link_loss=True, link_loss_delay=30, descriptor_config=_DESCRIPTOR_MPN_REV_SERIAL, descriptor_custom='') self._update_config_from_ini() self._last_poll_time = None ## Here we are using the port remapping to determine if the hub IC ## has been previously configured. If so, we don't need to reset ## it or configure it and can just control it as-is. ## ## If the hub has not been configured (e.g. when the board is first ## powered on), this call will raise an OSError. That will then trigger ## the normal reset & configure process. try: self.remap = self.get_port_remap() stdout("Hub IC has been configured") except OSError: self.remap = _DEFAULT_PORT_MAP stdout("Hub IC is in default state") if self.remap == _DEFAULT_PORT_MAP or force or self.config['force']: stdout("Resetting and configuring Hub IC") self.reset() self.configure() self.set_mcp_config()
def __init__(self, i2c_bus, _veml6070_it="VEML6070_1_T", ack=False): # Check if the IT is valid if _veml6070_it not in _VEML6070_INTEGRATION_TIME: raise ValueError( "Integration Time invalid. Valid values are: ", _VEML6070_INTEGRATION_TIME.keys(), ) # Check if ACK is valid if ack not in (True, False): raise ValueError("ACK must be 'True' or 'False'.") # Passed checks; set self values self._ack = int(ack) self._ack_thd = 0x00 self._it = _veml6070_it # Latch the I2C addresses self.i2c_cmd = I2CDevice(i2c_bus, _VEML6070_ADDR_CMD) self.i2c_low = I2CDevice(i2c_bus, _VEML6070_ADDR_LOW) self.i2c_high = I2CDevice(i2c_bus, _VEML6070_ADDR_HIGH) # Initialize the VEML6070 ara_buf = bytearray(1) try: with I2CDevice(i2c_bus, _VEML6070_ADDR_ARA) as ara: ara.readinto(ara_buf) except ValueError: # the ARA address is never valid? datasheet error? pass self.buf = bytearray(1) self.buf[0] = (self._ack << 5 | _VEML6070_INTEGRATION_TIME[self._it][0] << 2 | 0x02) with self.i2c_cmd as i2c_cmd: i2c_cmd.write(self.buf)
def __init__(self, i2c): try: self.i2c_device = I2CDevice(i2c, BMX160_I2C_ADDR,probe=False) except: self.i2c_device = I2CDevice(i2c, BMX160_I2C_ALT_ADDR,probe=False) super().__init__()
def __init__(self, i2c): self._accel_device = I2CDevice(i2c, _ADDRESS_ACCEL) self._mag_device = I2CDevice(i2c, _ADDRESS_MAG) self._write_u8(self._accel_device, _REG_ACCEL_CTRL_REG1_A, 0x27) # Enable the accelerometer self._write_u8(self._mag_device, _REG_MAG_MR_REG_M, 0x00) # Enable the magnetometer self._lsm303mag_gauss_lsb_xy = 1100.0 self._lsm303mag_gauss_lsb_z = 980.0 self._mag_gain = MAGGAIN_1_3 self._mag_rate = MAGRATE_0_7
def __init__(self, i2c_bus, address=_REG_ATECC_DEVICE_ADDR, debug=False): """Initializes an ATECC device. :param busio i2c_bus: I2C Bus object. :param int address: Device address, defaults to _ATECC_DEVICE_ADDR. :param bool debug: Library debugging enabled """ self._debug = debug self._i2cbuf = bytearray(12) # don't probe, the device will NACK until woken up self._wake_device = I2CDevice(i2c_bus, 0x00, probe=False) self._i2c_device = I2CDevice(i2c_bus, address, probe=False) if (self.version() >> 8) not in (_ATECC_508_VER, _ATECC_608_VER): raise RuntimeError( "Failed to find 608 or 508 chip. Please check your wiring.")
def __init__(self, i2c_bus, addr=0x10): self.i2c_device = I2CDevice(i2c_bus, addr, probe=False) self._name = None self._temp_cal = None self._temp_slope = None self._temp_zero = None
def __init__(self): self.pins = _PINS self.cs = DigitalInOut(board.GP17) self.cs.direction = Direction.OUTPUT self.cs.value = 0 self.pixels = adafruit_dotstar.DotStar(board.GP18, board.GP19, 16, brightness=0.1, auto_write=True) i2c = busio.I2C(board.GP5, board.GP4) self.expander = I2CDevice(i2c, 0x20) self.keys = [] self.time_of_last_press = time.monotonic() self.time_since_last_press = None self.led_sleep_enabled = False self.led_sleep_time = 60 self.sleeping = False self.was_asleep = False self.last_led_states = None # self.rotation = 0 self.full_state = [0] for i in range(len(self.pins)): _key = Key(i, self.pins[i], self.pixels, self.full_state) self.keys.append(_key)
def __init__(self, i2c, *, n=12, address=0x15, brightness=1.0, auto_write=True, retries=3, retrypause=0.001): if brightness < 0.0 or brightness > 1.0: raise ValueError("brightness out of range") self._i2c = i2c self._n = n # 12 LEDs on bear and fox badges self._address = address self._brightness = brightness self._auto_write = auto_write self._attempts = retries + 1 self._retrypause = retrypause self._device = I2CDevice(i2c, address) # red LED bellow chin is index 0 and order is counter-clockwise self._leds = [0.0] * self._n # empirical testing suggests this is 8 # see https://github.com/sandyjmacdonald/bearables/issues/1 self._maxbrightness = 8 self._convertfactor = self._maxbrightness * self._brightness self._mode = None self._pattern = None
def __init__(self, i2c): self.i2c_device = I2CDevice(i2c, _ADDRESS_MAG) if self._device_id != 0x40: raise AttributeError("Cannot find an LIS2MDL") self.reset()
def __init__(self, i2c_bus, address=_KEYPAD_I2C_DEFAULT_ADDRESS, addr_reg=0): self.i2c_device = I2CDevice(i2c_bus, address) self.read_buffer = bytearray(2) self.write_buffer = bytearray(4)
def __init__(self, i2c, address=_TMP007_I2CADDR, samplerate=CFG_16SAMPLE): """Initialize TMP007 device on the specified I2C address and bus number. Address defaults to 0x40 and bus number defaults to the appropriate bus for the hardware. Start taking temperature measurements. Samplerate can be one of TMP007_CFG_1SAMPLE, TMP007_CFG_2SAMPLE, TMP007_CFG_4SAMPLE, TMP007_CFG_8SAMPLE, or TMP007_CFG_16SAMPLE. The default is 16 samples for the highest resolution. Returns True if the device is intialized, False otherwise. """ self._device = I2CDevice(i2c, address) self._write_u16(_TMP007_CONFIG, _TMP007_CFG_RESET) time.sleep(.5) if samplerate not in (CFG_1SAMPLE, CFG_2SAMPLE, CFG_4SAMPLE, CFG_8SAMPLE, CFG_16SAMPLE): raise ValueError('Unexpected samplerate value! Must be one of: ' \ 'CFG_1SAMPLE, CFG_2SAMPLE, CFG_4SAMPLE, CFG_8SAMPLE, or CFG_16SAMPLE') # Set configuration register to turn on chip, enable data ready output, # and start sampling at the specified rate. config = _TMP007_CFG_MODEON | _TMP007_CFG_DRDYEN | samplerate self._write_u16(_TMP007_CONFIG, config) # Check device ID match expected value. dev_id = self.read_register(_TMP007_DEVID) if dev_id != 0x78: raise RuntimeError('Init failed - Did not find TMP007')
def __init__(self, i2c, rate=0.2, inttime=0.2, winfac=1.0, address=0x23): """ setup the LTR559ALS with specified measurement rate and integration time winfac is the factor to compensate light loss due to aperture or window above the device 1.0 = no window above = pure die i2c_address is its address on the I2C bus """ if LTR559ALS._als == None: LTR559ALS._als = I2CDevice(i2c, address) mid = self._read_reg(self._REG_MANUFAC_ID) if mid == 0x05: pid = self._read_reg(self._REG_PART_ID) if pid != 0x92: raise ValueError('unknown part id' + hex(pid)) else: raise ValueError('unknown manufacturer id' + hex(mid)) self._write_reg(self._REG_ALS_CONTR, 0x01) # ALS active mode self._write_reg(self._REG_PS_CONTR, 0x03) # PS active mode self.Set_ALS_Measurement_Rate(rate, inttime) self.Set_ALS_Gain(1) self._WinFac = winfac self._LastValidLux = 0
def __init__(self, i2c_bus, addr=0x49, drdy=None): self._drdy = drdy if drdy is not None: drdy.switch_to_input() self.i2c_device = I2CDevice(i2c_bus, addr) self.sw_reset()
def __init__(self, i2c_bus, address=0x5A): self.i2c_device = I2CDevice(i2c_bus, address) # check that the HW id is correct if self.hw_id != _HW_ID_CODE: raise RuntimeError( "Device ID returned is not correct! Please check your wiring.") # try to start the app buf = bytearray(1) buf[0] = 0xF4 with self.i2c_device as i2c: i2c.write(buf, end=1) time.sleep(0.1) # make sure there are no errors and we have entered application mode if self.error: raise RuntimeError( "Device returned a error! Try removing and reapplying power to " "the device and running the code again.") if not self.fw_mode: raise RuntimeError( "Device did not enter application mode! If you got here, there may " "be a problem with the firmware on your sensor.") self.interrupt_enabled = False # default to read every second self.drive_mode = DRIVE_MODE_1SEC self._eco2 = None # pylint: disable=invalid-name self._tvoc = None # pylint: disable=invalid-name
def wakeup(self): """Wakes up THE ATECC608A from sleep or idle modes. Returns True if device woke up from sleep/idle mode. """ while not self._i2c_bus.try_lock(): pass # check if it exists, first if 0x60 in self._i2c_bus.scan(): self._i2c_bus.unlock() return zero_bits = bytearray(2) try: self._i2c_bus.writeto(0x0, zero_bits) except OSError: pass # this may fail, that's ok - its just to wake up the chip! time.sleep(_TWLO_TIME) data = self._i2c_bus.scan() # check for an i2c device try: if data[0] != 96: raise TypeError( 'ATECCx08 not found - please check your wiring!') except IndexError: raise IndexError("ATECCx08 not found - please check your wiring!") self._i2c_bus.unlock() if not self._i2c_device: self._i2c_device = I2CDevice(self._i2c_bus, _REG_ATECC_DEVICE_ADDR) # check if we are ready to read from r = bytearray(1) self._get_response(r) if r[0] != 0x11: raise RuntimeError("Failed to wakeup")
def __init__(self, i2c, device_address= _ADDRESS_MAG): self._mag_device = I2CDevice(i2c, device_address) self._write_u8(self._mag_device, _REG_MAG_MR_REG_M, 0x00) # Enable the magnetometer self._lsm303mag_gauss_lsb_xy = 1100.0 self._lsm303mag_gauss_lsb_z = 980.0 self._mag_gain = MAGGAIN_1_3 self._mag_rate = MAGRATE_0_7
def __init__(self, i2c, *, address=FDC2214_I2C_ADDR_0): self._device = I2CDevice(i2c, address) # Check for valid chip ID if self._read16(FDC2214_DEVICE_ID) not in (0x3055, 0x3054): raise RuntimeError('Failed to find FD2214, check wiring!') self._write16(FDC2214_MUX_CONFIG, 0x220D) self._write16(FDC2214_CONFIG, 0x9E01) self._write16(FDC2214_RCOUNT_CH0, 0xFFFF) self._write16(FDC2214_RCOUNT_CH1, 0xFFFF) self._write16(FDC2214_RCOUNT_CH2, 0xFFFF) self._write16(FDC2214_RCOUNT_CH3, 0xFFFF) self._write16(FDC2214_OFFSET_CH0, 0x0000) self._write16(FDC2214_OFFSET_CH1, 0x0000) self._write16(FDC2214_OFFSET_CH2, 0x0000) self._write16(FDC2214_OFFSET_CH3, 0x0000) self._write16(FDC2214_SETTLECOUNT_CH0, 0x0400) self._write16(FDC2214_SETTLECOUNT_CH1, 0x0400) self._write16(FDC2214_SETTLECOUNT_CH2, 0x0400) self._write16(FDC2214_SETTLECOUNT_CH3, 0x0400) self._write16(FDC2214_CLOCK_DIVIDERS_CH0, 0x1001) self._write16(FDC2214_CLOCK_DIVIDERS_CH1, 0x1001) self._write16(FDC2214_CLOCK_DIVIDERS_CH2, 0x1001) self._write16(FDC2214_CLOCK_DIVIDERS_CH3, 0x1001) self._write16(FDC2214_DRIVE_CH0, 0x8C40) self._write16(FDC2214_DRIVE_CH1, 0x8C40) self._write16(FDC2214_DRIVE_CH2, 0x8C40) self._write16(FDC2214_DRIVE_CH3, 0x8C40) self._Fsense = self._Csense = 0 self._channel = 2 self._MSB = FDC2214_DATA_CH2_MSB self._LSB = FDC2214_DATA_CH2_LSB
def __init__(self, address=0x56, port=1): self.address = address self.MOTOR_ADDR_BASE = 0x00 self.ENCODER_ADDR_BASE = 0x08 i2c = busio.I2C(board.SCL, board.SDA) self.device = I2CDevice(i2c, address)
def setup_sgp30(i2c): from adafruit_bus_device.i2c_device import I2CDevice dev = I2CDevice(i2c, 0x58) with dev: dev.write(bytearray([0x20, 0x03])) return dev
def __init__(self, i2c, addr=0x5A): self.i2c_device = I2CDevice(i2c, addr) #check that the HW id is correct if self.hw_id != CCS811_HW_ID_CODE: raise RuntimeError( "Device ID returned is not correct! Please check your wiring.") #try to start the app buf = bytearray(1) buf[0] = 0xF4 self.i2c_device.write(buf, end=1, stop=True) time.sleep(.1) #make sure there are no errors and we have entered application mode if self.checkError(): raise RuntimeError( "Device returned an Error! Try removing and reapplying power to the device and running the code again." ) if not self.fw_mode: raise RuntimeError( "Device did not enter application mode! If you got here, there may be a problem with the firmware on your sensor." ) self.interrupt_enabled = False #default to read every second self.setDriveMode(CCS811_DRIVE_MODE_1SEC)
def __init__( # pylint: disable=too-many-arguments self, i2c_bus: I2C, address: int = 0x0C, gain: int = GAIN_1X, resolution: int = RESOLUTION_16, filt: int = FILTER_7, oversampling: int = OSR_3, debug: bool = False, ) -> None: self.i2c_device = I2CDevice(i2c_bus, address) self._debug = debug self._status_last = 0 self._res_x = self._res_y = self._res_z = resolution self._filter = filt self._osr = oversampling self._gain_current = gain # Put the device in a known state to start self.reset() # Set resolution to the supplied level self.resolution_x = self._res_x self.resolution_y = self._res_y self.resolution_z = self._res_z # Set filter to the supplied level self.filter = self._filter # Set oversampling to the supplied level self.oversampling = self._osr # Set gain to the supplied level self.gain = self._gain_current
def __init__(self, i2c_bus): self._driver_led = False self._indicator_led = False self._driver_led_current = Adafruit_AS726x.DRIVER_CURRENT_LIMITS.index( 12.5) self._indicator_led_current = Adafruit_AS726x.INDICATOR_CURRENT_LIMITS.index( 1) self._conversion_mode = Adafruit_AS726x.MODE_2 self._integration_time = 0 self._gain = Adafruit_AS726x.GAIN.index(1) self.buf2 = bytearray(2) self.i2c_device = I2CDevice(i2c_bus, _AS726X_ADDRESS) # reset device self._virtual_write(_AS726X_CONTROL_SETUP, 0x80) # wait for it to boot up time.sleep(1) # try to read the version reg to make sure we can connect version = self._virtual_read(_AS726X_HW_VERSION) # TODO: add support for other devices if version != 0x40: raise ValueError( "device could not be reached or this device is not supported!") self.integration_time = 140 self.conversion_mode = Adafruit_AS726x.MODE_2 self.gain = 64
def __init__(self, i2c_bus, *, addr=_MPRLS_DEFAULT_ADDR, reset_pin=None, eoc_pin=None, psi_min=0, psi_max=25): # Init I2C self._i2c = I2CDevice(i2c_bus, addr) self._buffer = bytearray(4) # Optional hardware reset pin if reset_pin is not None: reset_pin.direction = Direction.OUTPUT reset_pin.value = True reset_pin.value = False time.sleep(0.01) reset_pin.value = True time.sleep(0.005) # Start up timing # Optional end-of-conversion pin self._eoc = eoc_pin if eoc_pin is not None: self._eoc.direction = Direction.INPUT if psi_min >= psi_max: raise ValueError("Min PSI must be < max!") self._psimax = psi_max self._psimin = psi_min
def __init__(self, i2c_bus, *, integration_time=50, high_dynamic=True, uva_a_coef=2.22, uva_b_coef=1.33, uvb_c_coef=2.95, uvb_d_coef=1.74, uva_response=0.001461, uvb_response=0.002591): # Set coefficients self._a = uva_a_coef self._b = uva_b_coef self._c = uvb_c_coef self._d = uvb_d_coef self._uvaresp = uva_response self._uvbresp = uvb_response self._uvacalc = self._uvbcalc = None # Init I2C self._i2c = I2CDevice(i2c_bus, _VEML6075_ADDR) self._buffer = bytearray(3) # read ID! veml_id = self._read_register(_REV_ID) if veml_id != 0x26: raise RuntimeError("Incorrect VEML6075 ID 0x%02X" % veml_id) # shut down self._write_register(_REG_CONF, 0x01) # Set integration time self.integration_time = integration_time # enable conf = self._read_register(_REG_CONF) if high_dynamic: conf |= 0x08 conf &= ~0x01 # Power on self._write_register(_REG_CONF, conf)
def __init__(self, i2c_bus=None, address=MPU_ADDRESS): """ Create an i2c device from the MPU6050""" self.i2c = i2c_bus if self.i2c == None: import busio from board import SDA, SCL self.i2c = busio.I2C(SCL, SDA) self.i2c_device = I2CDevice(self.i2c, address) """ Wake up the MPU-6050 since it starts in sleep mode """ self.wakeup() print('MPU already awaked') """ verify the accel range and get the accel scale modifier""" print('accelerometer range set: {} g'.format(self.read_accel_range())) self.accel_scale_modifier = self.get_accel_scale_modifier() """ verify the gyro range and get the gyro scale modifier""" print('gyroscope range set: {} °/s'.format(self.read_gyro_range())) self.gyro_scale_modifier = self.get_gyro_scale_modifier() """ configuring the Digital Low Pass Filter """ #by default: # Bandwith of 21Hz and delay of 8.5ms, Sampling Freq 1KHz -> Accelerometer # Bandwith of 20Hz and delay of 8.3ms, Sampling Freq 1KHz -> Gyroscope self.filter_sensor = 0x04 print('digital filter configure to be: {}'.format(self.filter_sensor))
def __init__(self, i2c, address=_FT6206_DEFAULT_I2C_ADDR, debug=False, irq_pin=None): self._i2c = I2CDevice(i2c, address) self._debug = debug self._irq_pin = irq_pin chip_data = self._read(_FT6XXX_REG_LIBH, 8) # don't wait for IRQ lib_ver, chip_id, _, _, firm_id, _, vend_id = struct.unpack( ">HBBBBBB", chip_data) if vend_id != 0x11: raise RuntimeError("Did not find FT chip") if chip_id == 0x06: self.chip = "FT6206" elif chip_id == 0x64: self.chip = "FT6236" if debug: print("Library vers %04X" % lib_ver) print("Firmware ID %02X" % firm_id) print("Point rate %d Hz" % self._read(_FT6XXX_REG_POINTRATE, 1)[0]) print("Thresh %d" % self._read(_FT6XXX_REG_THRESHHOLD, 1)[0])
def __init__(self, i2c, address=_DRV2605_ADDR): self._device = I2CDevice(i2c, address) # Check chip ID is 3 or 7 (DRV2605 or DRV2605L). status = self._read_u8(_DRV2605_REG_STATUS) device_id = (status >> 5) & 0x07 if device_id not in (3, 7): raise RuntimeError("Failed to find DRV2605, check wiring!") # Configure registers to initialize chip. self._write_u8(_DRV2605_REG_MODE, 0x00) # out of standby self._write_u8(_DRV2605_REG_RTPIN, 0x00) # no real-time-playback self._write_u8(_DRV2605_REG_WAVESEQ1, 1) # strong click self._write_u8(_DRV2605_REG_WAVESEQ2, 0) self._write_u8(_DRV2605_REG_OVERDRIVE, 0) # no overdrive self._write_u8(_DRV2605_REG_SUSTAINPOS, 0) self._write_u8(_DRV2605_REG_SUSTAINNEG, 0) self._write_u8(_DRV2605_REG_BREAK, 0) self._write_u8(_DRV2605_REG_AUDIOMAX, 0x64) # Set ERM open-loop mode. self.use_ERM() # turn on ERM_OPEN_LOOP control3 = self._read_u8(_DRV2605_REG_CONTROL3) self._write_u8(_DRV2605_REG_CONTROL3, control3 | 0x20) # Default to internal trigger mode and TS2200 A library. self.mode = MODE_INTTRIG self.library = LIBRARY_TS2200A self._sequence = _DRV2605_Sequence(self)
def __init__(self): self._i2c = busio.I2C(board.SCL, board.SDA) self._spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) try: cs = DigitalInOut(board.D5) # Chip select of the MAX31865 board. self.tsensor = MAX31865(self._spi, cs, rtd_nominal=1000.0, ref_resistor=4300.0) except: print('No temperature sensor found.\n') try: self._adc = ADS.ADS1115(self._i2c) sleep(0.1) # short pause after ads1115 class creation recommended self._pressure_sensor_0 = AnalogIn(self._adc, ADS.P0) self._pressure_sensor_1 = AnalogIn(self._adc, ADS.P1) self._o2_sensor = AnalogIn(self._adc, ADS.P2, ADS.P3) except: print('No ADC found.\n') try: self._flow_sensor = I2CDevice(self._i2c, 0x40) with self._flow_sensor: self._flow_sensor.write(b"\x10\x00") sleep(0.1) except: print('No flow sensor found.\n')