class AMG88XX: # AMG8833 specs AMG8833_PIXEL_ARRAY_WIDTH = 8 AMG8833_PIXEL_ARRAY_HEIGHT = 8 AMG8833_PIXEL_TEMP_CONVERSION = 0.25 AMG8833_THERMISTOR_CONVERSION = 0.0625 AMG8833_MIN_TEMP = 22 AMG8833_MAX_TEMP = 32.0 def __init__(self, bus=1, address=0x69): self._address = address self._bus = SMBus(bus) self.write(AMG88XX_PCTL, AMG88XX_NORMAL_MODE) self.write(AMG88XX_RST, AMG88XX_INITIAL_RESET) self.write_bit(AMG88XX_INTC, AMG88XX_INTEN_bit, AMG88XX_INT_DISABLED) self.write_bit(AMG88XX_FPSC, AMG88XX_FPS_bit, AMG88XX_FPS_10) # ----------------------------- I2C Utilites -----------------------------# def write(self, register, data): self._bus.write_byte_data(self._address, register, data) time.sleep(0.0001) def write_bit(self, register, bit, val): bitmask = (val & 0b1) << bit data = self._bus.read_byte_data(self._address, register) data |= bitmask self._bus.write_byte_data(self._address, register, data) def read(self, register): return self._bus.read_byte_data(self._address, register) def read_bytes(self, register, num_bytes): return self._bus.read_i2c_block_data(self._address, register, num_bytes) # ------------------------------- AMG8833 --------------------------------# def get_temperature(self): """Temperature of the sensor in Celsius""" raw = (self.read(AMG88XX_TTHH << 8)) | self.read(AMG88XX_TTHL) return _signed_12bit_to_float(raw) * self.AMG8833_THERMISTOR_CONVERSION def get_pixels(self): """Temperature of each pixel across the sensor in Celsius. Temperatures are stored in a two dimensional list where the first index is the row and the second is the column. The first row is on the side closest to the writing on the sensor.""" pixels = [[0] * self.AMG8833_PIXEL_ARRAY_WIDTH for _ in range(self.AMG8833_PIXEL_ARRAY_HEIGHT)] for row in range(self.AMG8833_PIXEL_ARRAY_HEIGHT): for col in range(self.AMG8833_PIXEL_ARRAY_WIDTH): reg = AMG88XX_PIXEL_OFFSET + ((row * self.AMG8833_PIXEL_ARRAY_HEIGHT + col) << 1) raw = self.read_bytes(reg, 2) reading = raw[1] << 8 | raw[0] pixels[row][col] = _twos_comp_to_float(reading) * self.AMG8833_PIXEL_TEMP_CONVERSION return pixels
class MPL3115A2: def __init__(self, addr=MPL3115A2_DEFAULT_ADDRESS, channel=I2C_DEFAULT_CHANNEL): self.__addr = addr self.__bus = SMBus(channel) self.__bus.write_byte_data(self.__addr, PT_DATA_CFG, DREM | PDEFE | TDEFE) def __altitude_data_ready(self): status = self.__bus.read_byte_data(self.__addr, STATUS) return (status & PDR) == PDR def __temperature_data_ready(self): status = self.__bus.read_byte_data(self.__addr, STATUS) return (status & TDR) == TDR def set_altitude(self, altitude): while self.__altitude_data_ready(): self.__bus.read_i2c_block_data(self.__addr, OUT_P_MSB, 3) self.__bus.write_byte_data(self.__addr, OFF_H, 0) altitude_offset = round(altitude - self.read_altitude()) altitude_offset = -128 if altitude_offset < -128 else altitude_offset altitude_offset = 127 if altitude_offset > 127 else altitude_offset self.__bus.write_byte_data( self.__addr, OFF_H, altitude_offset.to_bytes(1, 'big', signed=True)[0]) def read_altitude(self): self.__bus.write_byte_data(self.__addr, CTRL_REG1, ALT | OST) while not self.__altitude_data_ready(): pass alt_data = self.__bus.read_i2c_block_data(self.__addr, OUT_P_MSB, 3) alt_int = int.from_bytes([alt_data[0], alt_data[1]], byteorder='big', signed=True) alt_fract = alt_data[2] >> 4 altitude = alt_int + (alt_fract / 16) return altitude def read_temperature(self): self.__bus.write_byte_data(self.__addr, CTRL_REG1, ALT | OST) while not self.__temperature_data_ready(): pass t_data = self.__bus.read_i2c_block_data(self.__addr, OUT_T_MSB, 2) t_int = int.from_bytes([t_data[0]], byteorder='big', signed=True) t_fract = t_data[1] >> 4 t = t_int + (t_fract / 16) return t
class Zero2Go: def __init__(self) -> None: try: from smbus2 import SMBus except ModuleNotFoundError: print("Zero2Go requires smbus2 module and python-smbus package:") print("`sudo apt install python-smbus`") print("`pip install smbus2`") return self.bus = SMBus(1) self._I2C_ADDRESS = 0x29 self._channel_to_int_registers = { 'A': 1, 'B': 3, 'C': 5, } self._channel_to_dec_registers = { 'A': 2, 'B': 4, 'C': 6, } @staticmethod def is_available() -> bool: """ Whether this device uses Zero2Go """ try: from smbus2 import SMBus except ModuleNotFoundError: return False return subprocess.call(['service', 'zero2go_daemon', 'status'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0 def voltage_for_channel(self, channel: str) -> float: """ Reads the current voltage value for the given channel :param channel: The channel to read from (either 'A', 'B', or 'C') """ if channel not in self._channel_to_int_registers.keys(): raise ValueError("Channel has to be either 'A', 'B', or 'C'!") int_voltage = self.bus.read_byte_data( self._I2C_ADDRESS, self._channel_to_int_registers[channel]) dec_voltage = self.bus.read_byte_data( self._I2C_ADDRESS, self._channel_to_dec_registers[channel]) * 0.01 return int_voltage + dec_voltage
class Imu: # create class instance as singleton to prevent multiple I2C initialization attempts def __new__(cls): if not hasattr(cls, 'instance'): cls.instance = super().__new__(cls) return cls.instance def __init__(self): self.bus = SMBus(1) # select I2C bus 1 (pin 3 & 5) self.MPU_Init() def MPU_Init(self): # write to sample rate register self.bus.write_byte_data(Device_Address, SMPLRT_DIV, 7) # write to power management register self.bus.write_byte_data(Device_Address, PWR_MGMT_1, 1) # write to Configuration register self.bus.write_byte_data(Device_Address, CONFIG, 0) # write to Gyro configuration register self.bus.write_byte_data(Device_Address, GYRO_CONFIG, 24) # write to interrupt enable register self.bus.write_byte_data(Device_Address, INT_ENABLE, 1) def read_raw_data(self, addr): # accelerometer and gyroscope values are 16-bit high = self.bus.read_byte_data(Device_Address, addr) low = self.bus.read_byte_data(Device_Address, addr + 1) # concatenate higher and lower value value = ((high << 8) | low) # to get signed value from mpu6050 if value > 32768: value = value - 65536 return value # read accelerometer value def get_accel(self): acc_x = self.read_raw_data(ACCEL_XOUT_H) / 16384.0 acc_y = self.read_raw_data(ACCEL_YOUT_H) / 16384.0 acc_z = self.read_raw_data(ACCEL_ZOUT_H) / 16384.0 return acc_x, acc_y, acc_z # read gyroscope value def get_gyro(self): gyro_x = self.read_raw_data(GYRO_XOUT_H) / 131.0 gyro_y = self.read_raw_data(GYRO_YOUT_H) / 131.0 gyro_z = self.read_raw_data(GYRO_ZOUT_H) / 131.0 return gyro_x, gyro_y, gyro_z
def is_navigator_r3_connected() -> bool: try: bus = SMBus(1) ADS1115_address = 0x48 bus.read_byte_data(ADS1115_address, 0) bus = SMBus(4) PCA9685_address = 0x40 bus.read_byte_data(PCA9685_address, 0) return True except Exception: return False
class MPU6050Interface: def __init__(self): ''' Python interface for MPU6050. Provides python wrappers around C-level MPU6050 routines ''' # setup c routines by loading shared object library self.so_file = "MPU_6050_Module.so" # .so on Linux, .pyd on Windows # open i2c bus 1 self.bus = SMBus(1) # initialize hardware # MPU6050.init() self.bus.write_byte_data(MPU_ADDR, SMPLRT_DIV, 0x07) self.bus.write_byte_data(MPU_ADDR, PWR_MGMT_1, 0x01) self.bus.write_byte_data(MPU_ADDR, CONFIG, 0) self.bus.write_byte_data(MPU_ADDR, GYRO_CONFIG, 24) self.bus.write_byte_data(MPU_ADDR, INT_ENABLE, 0x01) def read_raw_data(self, addr): ''' returns a 16-bit value from a certain address ''' high_byte = self.bus.read_byte_data(MPU_ADDR, addr) low_byte = self.bus.read_byte_data(MPU_ADDR, addr + 1) value = (high_byte << 8) | low_byte return value def get_acc_xyz(self): ''' returns accelerometer readings in g ''' Ax = self.read_raw_data(ACCEL_XOUT_H) Ay = self.read_raw_data(ACCEL_YOUT_H) Az = self.read_raw_data(ACCEL_ZOUT_H) # divide by sensitivity scale factor Ax /= 16384 Ay /= 16384 Az /= 16384 return (Ax, Ay, Az) def get_gyr_xyz(self): ''' returns accelerometer readings in g ''' Gx = self.read_raw_data(GYRO_XOUT_H) Gy = self.read_raw_data(GYRO_YOUT_H) Gz = self.read_raw_data(GYRO_ZOUT_H) # divide by sensitivity scale factor Gx /= 131 Gy /= 131 Gz /= 131 return (Gx, Gy, Gz)
def test_read(self): res = [] res2 = [] res3 = [] bus = SMBus(1) # Read bytes for k in range(2): x = bus.read_byte_data(80, k) res.append(x) self.assertEqual(len(res), 2, msg="Result array of incorrect length.") # Read word x = bus.read_word_data(80, 0) res2.append(x & 255) res2.append(x / 256) self.assertEqual(len(res2), 2, msg="Result array of incorrect length.") self.assertListEqual(res, res2, msg="Byte and word reads differ") # Read block of N bytes n = 2 x = bus.read_i2c_block_data(80, 0, n) res3.extend(x) self.assertEqual(len(res3), n, msg="Result array of incorrect length.") self.assertListEqual(res, res3, msg="Byte and block reads differ") bus.close()
def get_data_bme280(): global values i2c_address = 0x76 bus_number = 1 bus = SMBus(bus_number) setup(i2c_address, bus) while True: digs = get_calib_param(i2c_address, bus) data = [] for i in range(0xF7, 0xF7 + 8): data.append(bus.read_byte_data(i2c_address, i)) pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4) temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4) hum_raw = (data[6] << 8) | data[7] temp, t_fine = get_temp(digs['temperture'], temp_raw) pressure = get_pressure(digs['pressure'], pres_raw, t_fine) humid = get_humid(digs['humidity'], hum_raw, t_fine) values = {'temperature': temp, 'pressure': pressure, 'humidity': humid} sleep(1)
class i2c_device: def __init__(self, addr, port=I2CBUS): self.addr = addr self.bus = SMBus(port) # Write a single command def write_cmd(self, cmd): self.bus.write_byte(self.addr, cmd) sleep(0.0001) # Write a command and argument def write_cmd_arg(self, cmd, data): self.bus.write_byte_data(self.addr, cmd, data) sleep(0.0001) # Write a block of data def write_block_data(self, cmd, data): self.bus.write_block_data(self.addr, cmd, data) sleep(0.0001) # Read a single byte def read(self): return self.bus.read_byte(self.addr) # Read def read_data(self, cmd): return self.bus.read_byte_data(self.addr, cmd) # Read a block of data def read_block_data(self, cmd): return self.bus.read_block_data(self.addr, cmd)
class RotEncThread(threading.Thread): global clk_last_state def __init__(self): threading.Thread.__init__(self) self.read_volume = 0 self.last_read_volume = 0 self.vol_change_func = None self.arduino_addr = 0x08 self.bus = SMBus(1) self.get_vol_arr = [103, 101, 116, 118, 0] def set_vol_change_func(self, func): self.vol_change_func = func def run(self): #try: while True: #lock.acquire() try: #self.bus.write_i2c_block_data(self.arduino_addr, 0x00, self.get_vol_arr) self.bus.write_byte(self.arduino_addr, 0x01) time.sleep(0.1) self.read_volume = self.bus.read_byte_data( self.arduino_addr, 0) #print(self.read_volume) if self.read_volume != self.last_read_volume: self.vol_change_func(self.read_volume) self.last_read_volume = self.read_volume finally: #lock.release() time.sleep(0.01)
class mcp23017: IODIRA = 0x00 IODIRB = 0x01 IPOLA = 0x02 IPOLB = 0x03 GPINTENA = 0x04 GPINTENB = 0x05 DEFVALA = 0x06 DEFVALB = 0x07 INTCONA = 0x08 INTCONB = 0x09 IOCONA = 0x0A IOCONB = 0x0B GPPUA = 0x0C GPPUB = 0x0D INTFA = 0x0E INTFB = 0x0F INTCAPA = 0x10 INTCAPB = 0x11 GPIOA = 0x12 GPIOB = 0x13 OLATA = 0x14 OLATB = 0x15 def __init__(self, address=0): self.address = 0b0100000 | address # [0 1 0 0 A2 A1 A0] print(hex(self.address)) self.bus = SMBus(1) def write_register(self, register, data): self.bus.write_byte_data(self.address, register, data) def read_register(self, register): return self.bus.read_byte_data(self.address, register)
class smbusIO(i2cIO): """ an implementation of i2c_io which talks over the smbus. """ def __init__(self, bus_id=1): super().__init__() from smbus2 import SMBus self.bus = SMBus(bus=bus_id) def write(self, i2c_address, register, val): """ Delegates to smbus.write_byte_data """ return self.bus.write_byte_data(i2c_address, register, val) def read(self, i2c_address, register): """ Delegates to smbus.read_byte_data """ return self.bus.read_byte_data(i2c_address, register) def read_block(self, i2c_address, register, length): """ Delegates to smbus.read_i2c_block_data """ return self.bus.read_i2c_block_data(i2c_address, register, length)
class smbus_io(i2c_io): """ an implementation of i2c_io which talks over the smbus. """ def __init__(self, busId=1): super().__init__() self.bus = SMBus(bus=busId) """ Delegates to smbus.write_byte_data """ def write(self, i2cAddress, register, val): return self.bus.write_byte_data(i2cAddress, register, val) """ Delegates to smbus.read_byte_data """ def read(self, i2cAddress, register): return self.bus.read_byte_data(i2cAddress, register) """ Delegates to smbus.read_i2c_block_data """ def readBlock(self, i2cAddress, register, length): return self.bus.read_i2c_block_data(i2cAddress, register, length)
class I2cBus(BaseI2cDriver.I2cBus): def __init__(self, bus_id): super().__init__(bus_id) try: self.bus = SMBus(bus_id) except Exception as e: raise InvalidDriverError( 'Unable to initialize i2c connection with bus {}. Check if i2c bus is avalable.'.format(bus_id), e) def close(self): if self.bus is not None: self.bus.close() def read_byte(self, addr: int, register: int) -> int: return self.bus.read_byte_data(addr, register) def read_word(self, addr: int, register: int) -> int: return self.bus.read_word_data(addr, register) def read_block(self, addr: int, register, length: int) -> List[int]: return self.bus.read_i2c_block_data(addr, register, length) def write_byte_data(self, addr, register, value): self.bus.write_byte_data(addr, register, value) def write_word_data(self, addr, register, value): self.bus.write_word_data(addr, register, value) def write_block_data(self, addr, register, data): self.bus.write_i2c_block_data(addr, register, data)
class I2C(object): """ This is just a wrapper around i2c. There are so many implementations. """ def __init__(self, address, bus=1): self.i2c = SMBus(bus) self.address = address def __del__(self): self.i2c.close() def read8(self, reg): b = self.i2c.read_byte_data(self.address, reg) return b def read_block(self, reg, size): block = self.i2c.read_i2c_block_data(self.address, reg, size) return block def write_block(self, reg, data): self.i2c.write_i2c_block_data(self.address, reg, data) def write8(self, reg, data): # print(hex(self.address), reg, data) self.i2c.write_byte_data(self.address, reg, data)
class VCNL4010: """Vishay VCNL4010 proximity and ambient light sensor.""" def __init__(self): self._device = SMBus(1) self.led_current = 20 self.frequency = FREQUENCY_390K625 self._write_u8(_VCNL4010_INTCONTROL, 0x08) def _read_u8(self, address): # Read an 8-bit unsigned value from the specified 8-bit address. with SMBus(1) as self._device: self._device.read_byte_data(_VCNL4010_I2CADDR_DEFAULT, address) return read def _write_u8(self, address, val): # Write an 8-bit unsigned value to the specified 8-bit address. with SMBus(1) as self._device: self._device.write_byte_data(_VCNL4010_I2CADDR_DEFAULT, address, val) def _read_u16BE(self, address): with SMBus(1) as self._device: read_block = self._device.read_i2c_block_data( _VCNL4010_I2CADDR_DEFAULT, address, 2) return (read_block[0] << 8) | read_block[1] @property def proximity(self): """The detected proximity of an object in front of the sensor. This is a unit-less unsigned 16-bit value (0-65535) INVERSELY proportional to the distance of an object in front of the sensor (up to a max of ~200mm). For example a value of 10 is an object farther away than a value of 1000. Note there is no conversion from this value to absolute distance possible, you can only make relative comparisons. """ # Clear interrupt. status = self._read_u8(_VCNL4010_INTSTAT) status &= ~0x80 self._write_u8(_VCNL4010_INTSTAT, status) # Grab a proximity measurement. self._write_u8(_VCNL4010_COMMAND, _VCNL4010_MEASUREPROXIMITY) # Wait for result, then read and return the 16-bit value. while True: result = self._read_u8(_VCNL4010_COMMAND) if result & _VCNL4010_PROXIMITYREADY: return self._read_u16BE(_VCNL4010_PROXIMITYDATA)
def detect_navigator() -> Tuple[bool, str]: """Check if navigator is connected using the sensors on the I²C BUS Returns: (bool, str): True if a navigator is connected, false otherwise. String is always empty """ try: bus = SMBus(1) PCA9685_address = 0x40 ADS1115_address = 0x48 bus.read_byte_data(PCA9685_address, 0) bus.read_byte_data(ADS1115_address, 0) return (True, "") except Exception as error: print(f"Navigator not detected on I2C bus: {error}") return (False, "")
def __read_status(self, bus: SMBus) -> tp.Tuple[bool, bool]: """ This method reads the status from the sensor :param bus: an open i2c bus that is already protected by a Lock """ logger.debug("Reading sensor status") status_int = bus.read_byte_data(self.i2c_address, Bme280Reader.REG_ADDR_STATUS) status_struct = Bme280Reader.STRUCT_STATUS.parse(status_int.to_bytes(1, endianness)) return bool(status_struct.measuring), bool(status_struct.im_update)
class Lidar_Lite(): def __init__(self, bus): self.bus = SMBus(bus) self.address = 0x62 self.distWriteReg = 0x00 self.distWriteVal = 0x04 self.distReadReg1 = 0x8f self.distReadReg2 = 0x10 self.velWriteReg = 0x04 self.velWriteVal = 0x08 self.velReadReg = 0x09 self.updateTime = 0.005 """ def connect(self, bus): try: self.bus = SMBus(bus) time.sleep(0.5) return 0 except: return -1 """ def writeAndWait(self, register, value): self.bus.write_byte_data(self.address, register, value) time.sleep(self.updateTime) def readAndWait(self, register): res = self.bus.read_byte_data(self.address, register) time.sleep(self.updateTime) return res def readDistAndWait(self, register): res = self.bus.read_i2c_block_data(self.address, register, 2) time.sleep(self.updateTime) return (res[0] << 8 | res[1]) def getDistance(self): self.writeAndWait(self.distWriteReg, self.distWriteVal) dist = self.readDistAndWait(self.distReadReg1) return dist def getVelocity(self): self.writeAndWait(self.distWriteReg, self.distWriteVal) self.writeAndWait(self.velWriteReg, self.velWriteVal) vel = self.readAndWait(self.velReadReg) return self.signedInt(vel) def signedInt(self, value): if value > 127: return (256 - value) * (-1) else: return value
class I2C(object): def __init__(self, bus_number, device_address): self.smbus = SMBus(bus_number) self.device_address = device_address def set_bit(self,register, index): read_value = np.uint8(self.smbus.read_byte_data(self.device_address, register)) bit_array = np.unpackbits(read_value) bit_array[index*-1-1] = 1 self.smbus.write_byte_data(self.device_address,register, np.packbits(bit_array)) def clear_bit(self,register, index): read_value = np.uint8(self.smbus.read_byte_data(self.device_address, register)) bit_array = np.unpackbits(read_value) bit_array[index*-1-1] = 0 self.smbus.write_byte_data(self.device_address,register, np.packbits(bit_array)) def read_bit(self,register, index): value = self.smbus.read_byte_data(device_address, register) eight_bit = format(value, '08b') return eight_bit[index*(-1)-1] def write_byte(self,register, value): self.smbus.write_byte_data(self.device_address,register, int(value)) def read_byte(self, register): return self.smbus.read_byte_data(self.device_address,register) def read_block(self,register, number_to_read): return self.smbus.read_i2c_block_data(self.device_address, register, number_to_read) def byte_array_to_float32(self,array): return np.fromiter(array[::-1], dtype=np.uint8).view('<f4')
def readModifyWrite(iicAddr, regAddr, data, shiftVal): bus = SMBus(1) #read data from reg regData = np.uint8(bus.read_byte_data(iicAddr, regAddr)) #clear bits in position mask = ~np.uint8(0x3 << shiftVal) clearedReg = (mask & regData) newData = (clearedReg | (data) << shiftVal) #write data back to pca bus.write_byte_data(iicAddr, regAddr, newData)
def getPortState(): portState = [] cnt = 0 bus = SMBus(1) while cnt < 48: #grab i2c address, reg addr, and data shift offset, disregard newData (iicData[2]) iicData = lookUpIicPortCmd(cnt, 0) regData = np.uint8(bus.read_byte_data(iicData[0], iicData[1])) state = (regData >> iicData[3]) & np.uint8(0x03) portState.append(state) cnt += 1 return portState
class I2CController: # # I2C # def __init__(self): try: self.i2cBus = SMBus( 1) # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1) except: print("Error opening I2C bus") raise I2CUnavailableError("Error opening I2C bus") return self.MCUI2CAddress = 0x8 self.CNCI2CAddress = 0x10 def checkI2CStatus(self): self.i2cBus.read_byte_data(80, 0) # Write a single register # cmd = 0x32 # value = 0x80 # bus.write_byte_data(self.MCUI2CAddress, cmd, value) # Write an array of registers # values = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff] # bus.write_i2c_block_data(self.MCUI2CAddress, cmd, values) def sendToMCU(self, cmdId, value): self.i2cBus.write_byte_data(self.MCUI2CAddress, cmdId, value) return def sendToCNC(self, cmdId, value): self.i2cBus.write_byte_data(self.CNCI2CAddress, cmdId, value) return def closeI2C(self): self.i2cBus.close()
class MCP9808: def __init__(self, bus, addr, resolution=0x03): self.addr = addr self.res = resolution self.bus = SMBus(bus) self.init() # Initialise the MCP9808 with resolution for continuous readings def init(self): # Write config config = [0x00, 0x00] self.bus.write_i2c_block_data(self.addr, 0x01, config) # Write resolution if ((self.res > 0x03) or (self.res < 0)): self.res = 0x03 self.bus.write_byte_data(self.addr, 0x08, self.res) # Read Device ID/Revision register rid = self.bus.read_byte_data(self.addr, 0x07) tmp = self.bus.read_i2c_block_data(self.addr, 0x06, 2) mid = ((tmp[0] & 0x1F) * 256) + tmp[1] #print "Init MCP9808 Manufacurer ID: 0x{:04x}, Device ID: 0x{:02x}".format(mid, rid) # Obtain temperature reading def t_read(self): # Final celcius temp ctemp = 0.0 # Obtain temp reading in binary tin = self.bus.read_i2c_block_data(self.addr, 0x05, 2) bt = ((tin[0] & 0x1F) * 256) + tin[1] # Check if two's comp if (bt > 4095): bt -= 8192 # Multiply by resolution if (self.res == 0x00): ctemp = bt * 0.5 elif (self.res == 0x01): ctemp = bt * 0.25 elif (self.res == 0x02): ctemp = bt * 0.125 elif (self.res == 0x03): ctemp = bt * 0.0625 else: ctemp = bt * 0.0625 # Round and format return "{:.2f}".format(round(ctemp, 2))
class Device(object): """Class for communicating with an I2C device using the adafruit-pureio pure python smbus library, or other smbus compatible I2C interface. Allows reading and writing 8-bit, 16-bit, and byte array values to registers on the device.""" def __init__(self, address, busnum): """Create an instance of the I2C device at the specified address on the specified I2C bus number.""" self._address = address self._bus = SMBus(busnum) self._logger = logging.getLogger('Rover_log') def writeByte(self, value): """Write an 8-bit value""" value = value & 0xFF self._bus.write_byte(self._address, register, value) self._logger.debug("Wrote 0x%02X to register 0x%02X", value, register) def write8(self, value, register=0): """Write an 8-bit value to the specified register. use register 0 if not needed""" value = value & 0xFF self._bus.write_byte_data(self._address, register, value) self._logger.debug("Wrote 0x%02X to register 0x%02X", value, register) def readU8(self, register=0): """Read an unsigned byte from the specified register. use 0 if egister is not needed""" result = self._bus.read_byte_data(self._address, register) & 0xFF self._logger.debug("Read 0x%02X from register 0x%02X", result, register) return result def writeList(self, data, register=0): """Write bytes to the specified register. Use 0 if register is not needed""" self._bus.write_i2c_block_data(self._address, register, data) self._logger.debug("Wrote to register 0x%02X: %s", register, data) def readList(self, length, register=0): """Read a length number of bytes from the specified register, use 0 if register is not needed. Results will be returned as a bytearray.""" results = self._bus.read_i2c_block_data(self._address, register, length) self._logger.debug("Read the following from register 0x%02X: %s", register, results) return results
def getPWMValues(): iicAddress = [0x60, 0x61, 0x62] #i2c mux 7 bit addresses pwmRegAddr = [3, 5] bus = SMBus(1) bankPwm = [] #nested loop through devices and regs addrCnt = 0 regCnt = 0 while addrCnt < 3: while regCnt < 2: readData = np.uint8( bus.read_byte_data(iicAddress[addrCnt], pwmRegAddr[regCnt])) bankPwm.append(flooredPercentage(float(readData / 256.0), 1)) #format data as percent regCnt += 1 regCnt = 0 #reset count for next device addrCnt += 1 return bankPwm
class UltrasonicDriver(): def __init__(self): self.bus = SMBus(0) self.buffer = Array('I', range(4)) self.lock = Lock() self.t = Thread(target=self.write_to_mem) self.t.start() def readI2C(self): #Reads the distances from the slave bval = 0 #Temp variable to store the byte read from the bus bval = self.bus.read_byte_data(SLAVE_ADDR, 0) #Read the byte from the bus return bval #Return read byte def write_to_mem(self): while True: self.lock.acquire() while (self.readI2C() < 255): pass for i in range(4): self.buffer[i] = self.readI2C() self.lock.release() time.sleep(0.200) def read_from_mem(self): temp = [0, 0, 0, 0] self.lock.acquire() for i in range(4): temp[i] = self.buffer[i] self.lock.release() return temp def get_distances(self): return self.read_from_mem()
class BME280: def __init__(self): self.bus_number = 1 self.i2c_address = 0x76 self.bus = SMBus(self.bus_number) self.digT = [] self.digP = [] self.digH = [] self.t_fine = 0.0 def writeReg(self, reg_address, data): self.bus.write_byte_data(self.i2c_address, reg_address, data) def get_calib_param(self): calib = [] for i in range(0x88, 0x88 + 24): calib.append(self.bus.read_byte_data(self.i2c_address, i)) calib.append(self.bus.read_byte_data(self.i2c_address, 0xA1)) for i in range(0xE1, 0xE1 + 7): calib.append(self.bus.read_byte_data(self.i2c_address, i)) self.digT.append((calib[1] << 8) | calib[0]) self.digT.append((calib[3] << 8) | calib[2]) self.digT.append((calib[5] << 8) | calib[4]) self.digP.append((calib[7] << 8) | calib[6]) self.digP.append((calib[9] << 8) | calib[8]) self.digP.append((calib[11] << 8) | calib[10]) self.digP.append((calib[13] << 8) | calib[12]) self.digP.append((calib[15] << 8) | calib[14]) self.digP.append((calib[17] << 8) | calib[16]) self.digP.append((calib[19] << 8) | calib[18]) self.digP.append((calib[21] << 8) | calib[20]) self.digP.append((calib[23] << 8) | calib[22]) self.digH.append(calib[24]) self.digH.append((calib[26] << 8) | calib[25]) self.digH.append(calib[27]) self.digH.append((calib[28] << 4) | (0x0F & calib[29])) self.digH.append((calib[30] << 4) | ((calib[29] >> 4) & 0x0F)) self.digH.append(calib[31]) for i in range(1, 2): if self.digT[i] & 0x8000: self.digT[i] = (-self.digT[i] ^ 0xFFFF) + 1 for i in range(1, 8): if self.digP[i] & 0x8000: self.digP[i] = (-self.digP[i] ^ 0xFFFF) + 1 for i in range(0, 6): if self.digH[i] & 0x8000: self.digH[i] = (-self.digH[i] ^ 0xFFFF) + 1 def readData(self): data = [] for i in range(0xF7, 0xF7 + 8): data.append(self.bus.read_byte_data(self.i2c_address, i)) temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4) pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4) hum_raw = (data[6] << 8) | data[7] return self.compensate_T(temp_raw), self.compensate_P( pres_raw), self.compensate_H(hum_raw) def compensate_T(self, adc_T): global t_fine v1 = (adc_T / 16384.0 - self.digT[0] / 1024.0) * self.digT[1] v2 = (adc_T / 131072.0 - self.digT[0] / 8192.0) * ( adc_T / 131072.0 - self.digT[0] / 8192.0) * self.digT[2] t_fine = v1 + v2 temperature = t_fine / 5120.0 #print "temp : %-6.2f ℃" % (temperature) return temperature def compensate_P(self, adc_P): global t_fine pressure = 0.0 v1 = (t_fine / 2.0) - 64000.0 v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * self.digP[5] v2 = v2 + ((v1 * self.digP[4]) * 2.0) v2 = (v2 / 4.0) + (self.digP[3] * 65536.0) v1 = (((self.digP[2] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8) + ((self.digP[1] * v1) / 2.0)) / 262144 v1 = ((32768 + v1) * self.digP[0]) / 32768 if v1 == 0: return 0 pressure = ((1048576 - adc_P) - (v2 / 4096)) * 3125 if pressure < 0x80000000: pressure = (pressure * 2.0) / v1 else: pressure = (pressure / v1) * 2 v1 = (self.digP[8] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096 v2 = ((pressure / 4.0) * self.digP[7]) / 8192.0 pressure = pressure + ((v1 + v2 + self.digP[6]) / 16.0) #print "pressure : %7.2f hPa" % (pressure/100) return pressure / 100 def compensate_H(self, adc_H): global t_fine var_h = t_fine - 76800.0 if var_h != 0: var_h = (adc_H - (self.digH[3] * 64.0 + self.digH[4] / 16384.0 * var_h) ) * (self.digH[1] / 65536.0 * (1.0 + self.digH[5] / 67108864.0 * var_h * (1.0 + self.digH[2] / 67108864.0 * var_h))) else: return 0 var_h = var_h * (1.0 - self.digH[0] * var_h / 524288.0) if var_h > 100.0: var_h = 100.0 elif var_h < 0.0: var_h = 0.0 #print "hum : %6.2f %" % (var_h) return var_h def setup(self): osrs_t = 1 #Temperature oversampling x 1 osrs_p = 1 #Pressure oversampling x 1 osrs_h = 1 #Humidity oversampling x 1 mode = 3 #Normal mode t_sb = 5 #Tstandby 1000ms filter = 0 #Filter off spi3w_en = 0 #3-wire SPI Disable ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode config_reg = (t_sb << 5) | (filter << 2) | spi3w_en ctrl_hum_reg = osrs_h self.writeReg(0xF2, ctrl_hum_reg) self.writeReg(0xF4, ctrl_meas_reg) self.writeReg(0xF5, config_reg)
class AXP209(object): def __init__(self, bus=0): """ Initialize the AXP209 object :param bus: i2c bus number or a SMBus object :type bus: Integer or SMBus object """ if isinstance(bus, int): self.bus = SMBus(bus, force=True) self.autocleanup = True else: self.bus = bus self.autocleanup = False # force ADC enable for battery voltage and current self.adc_enable1 = 0xc3 def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): if self.autocleanup: self.close() def close(self): self.bus.close() @property def gpio2_output(self): pass @gpio2_output.setter def gpio2_output(self, val): flags = GPIO012_FEATURE_SET_FLAGS() if bool(val): flags.gpio_function = 0b111 else: flags.gpio_function = 0b000 self.bus.write_byte_data(AXP209_ADDRESS, GPIO2_FEATURE_SET_REG, flags.asbyte) @property def adc_enable1(self): flags = ADC_ENABLE1_FLAGS() flags.asbyte = self.bus.read_byte_data(AXP209_ADDRESS, ADC_ENABLE1_REG) return flags @adc_enable1.setter def adc_enable1(self, flags): if hasattr(flags, "asbyte"): flags = flags.asbyte self.bus.write_byte_data(AXP209_ADDRESS, ADC_ENABLE1_REG, flags) @property def power_input_status(self): flags = POWER_INPUT_STATUS_FLAGS() flags.asbyte = self.bus.read_byte_data(AXP209_ADDRESS, POWER_INPUT_STATUS_REG) return flags @property def battery_current_direction(self): return bool(self.power_input_status.battery_current_direction) @property def power_operating_mode(self): flags = POWER_OPERATING_STATUS_FLAGS() flags.asbyte = self.bus.read_byte_data(AXP209_ADDRESS, POWER_OPERATING_MODE_REG) return flags @property def battery_exists(self): return bool(self.power_operating_mode.battery_exists) @property def battery_charging(self): return bool(self.power_operating_mode.battery_charging) @property def battery_voltage(self): """ Returns voltage in mV """ msb = self.bus.read_byte_data(AXP209_ADDRESS, BATTERY_VOLTAGE_MSB_REG) lsb = self.bus.read_byte_data(AXP209_ADDRESS, BATTERY_VOLTAGE_LSB_REG) voltage_bin = msb << 4 | lsb & 0x0f return voltage_bin * 1.1 @property def battery_charge_current(self): """ Returns current in mA """ msb = self.bus.read_byte_data(AXP209_ADDRESS, BATTERY_CHARGE_CURRENT_MSB_REG) lsb = self.bus.read_byte_data(AXP209_ADDRESS, BATTERY_CHARGE_CURRENT_LSB_REG) # (12 bits) charge_bin = msb << 4 | lsb & 0x0f # 0 mV -> 000h, 0.5 mA/bit FFFh -> 1800 mA return charge_bin * 0.5 @property def battery_discharge_current(self): """ Returns current in mA """ msb = self.bus.read_byte_data(AXP209_ADDRESS, BATTERY_DISCHARGE_CURRENT_MSB_REG) lsb = self.bus.read_byte_data(AXP209_ADDRESS, BATTERY_DISCHARGE_CURRENT_LSB_REG) # 13bits discharge_bin = msb << 5 | lsb & 0x1f # 0 mV -> 000h, 0.5 mA/bit 1FFFh -> 1800 mA return discharge_bin * 0.5 @property def internal_temperature(self): """ Returns temperature in celsius C """ temp_msb = self.bus.read_byte_data(AXP209_ADDRESS, INTERNAL_TEMPERATURE_MSB_REG) temp_lsb = self.bus.read_byte_data(AXP209_ADDRESS, INTERNAL_TEMPERATURE_LSB_REG) # MSB is 8 bits, LSB is lower 4 bits temp = temp_msb << 4 | temp_lsb & 0x0f # -144.7c -> 000h, 0.1c/bit FFFh -> 264.8c return temp*0.1-144.7 @property def battery_gauge(self): gauge_bin = self.bus.read_byte_data(AXP209_ADDRESS, BATTERY_GAUGE_REG) gauge = gauge_bin & 0x7f if gauge > 100: return -1 return gauge
class InputModule(AbstractInput): """ A sensor support class that monitors the MH-Z16's CO2 concentration """ def __init__(self, input_dev, testing=False): super(InputModule, self).__init__() self.logger = logging.getLogger("mycodo.inputs.mh_z16") if not testing: self.logger = logging.getLogger( "mycodo.mh_z16_{id}".format(id=input_dev.unique_id.split('-')[0])) self.interface = input_dev.interface self.uart_location = input_dev.uart_location if self.interface == 'UART': import serial # Check if device is valid self.serial_device = is_device(self.uart_location) if self.serial_device: try: self.ser = serial.Serial(self.serial_device, timeout=1) except serial.SerialException: self.logger.exception('Opening serial') else: self.logger.error( 'Could not open "{dev}". ' 'Check the device location is correct.'.format( dev=self.uart_location)) elif self.interface == 'I2C': from smbus2 import SMBus self.i2c_address = int(str(input_dev.i2c_location), 16) self.i2c_bus = input_dev.i2c_bus self.cmd_measure = [0xFF, 0x01, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63] self.IOCONTROL = 0X0E << 3 self.FCR = 0X02 << 3 self.LCR = 0X03 << 3 self.DLL = 0x00 << 3 self.DLH = 0X01 << 3 self.THR = 0X00 << 3 self.RHR = 0x00 << 3 self.TXLVL = 0X08 << 3 self.RXLVL = 0X09 << 3 self.i2c = SMBus(self.i2c_bus) self.begin() def get_measurement(self): """ Gets the MH-Z16's CO2 concentration in ppmv via UART""" return_dict = measurements_dict.copy() co2 = None if self.interface == 'UART': if not self.serial_device: # Don't measure if device isn't validated return None self.ser.flushInput() time.sleep(1) self.ser.write(bytearray([0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])) time.sleep(.01) resp = self.ser.read(9) if len(resp) != 0: high = resp[2] low = resp[3] co2 = (high * 256) + low elif self.interface == 'I2C': self.write_register(self.FCR, 0x07) self.send(self.cmd_measure) try: co2 = self.parse(self.receive()) except Exception: co2 = None return_dict[0]['value'] = co2 return return_dict def begin(self): try: self.write_register(self.IOCONTROL, 0x08) except IOError: pass self.write_register(self.FCR, 0x07) self.write_register(self.LCR, 0x83) self.write_register(self.DLL, 0x60) self.write_register(self.DLH, 0x00) self.write_register(self.LCR, 0x03) @staticmethod def parse(response): checksum = 0 if len(response) < 9: return None for i in range(0, 9): checksum += response[i] if response[0] == 0xFF: if response[1] == 0x9C: if checksum % 256 == 0xFF: return (response[2] << 24) + (response[3] << 16) + (response[4] << 8) + response[5] return None def read_register(self, reg_addr): time.sleep(0.01) return self.i2c.read_byte_data(self.i2c_address, reg_addr) def write_register(self, reg_addr, val): time.sleep(0.01) self.i2c.write_byte_data(self.i2c_address, reg_addr, val) def send(self, command): if self.read_register(self.TXLVL) >= len(command): self.i2c.write_i2c_block_data(self.i2c_address, self.THR, command) def receive(self): n = 9 buf = [] start = time.clock() while n > 0: rx_level = self.read_register(self.RXLVL) if rx_level > n: rx_level = n buf.extend(self.i2c.read_i2c_block_data(self.i2c_address, self.RHR, rx_level)) n = n - rx_level if time.clock() - start > 0.2: break return buf
''' Author: Taylor Witherell File: i2cLidar.py Description: Uses I2C communications protocol to get data from the lidar sensor Pin outs: 5V, GND, SCL (column 1, row 3), SDA (column 1, row 4) ''' from smbus2 import SMBus, i2c_msg #from smbus import * i2c_bus = SMBus(1) i2c_address = '/dev/i2c-1' open(i2c_address) # To open a given i2c bus. i2c_addr = '0x10' register = '0x2C' i2c_bus.read_byte_data(i2c_addr,register,force=None) # To read a single byte from a designated register. #read_block_data(i2c_addr,register,force=None) # To read a block of up to 32-bytes from a given register. #read_i2c_block_data(i2c_addr,register,length,force=None) # To read a block of byte data from a given register. #read_word_data(i2c_addr,register,force=None) # To read a single word (2 bytes) from a given register. close() # To close I2C connection.