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 run(self): self.running = True dev = InputDevice(list_devices()[0]) controller = Controller(dev, [self.left_stick]) bus = SMBus(I2C_BUS) motors = MotorGroup(bus) try: while self.running: if controller.read_one(): left, right = drive_from_vector(*self.left_stick.value) motors.set(left, right) print(f"{self.name} stopping") finally: motors.set(0, 0) bus.close()
def setup_eon_fan(): global LEON os.system("echo 2 > /sys/module/dwc3_msm/parameters/otg_switch") bus = SMBus(7, force=True) try: bus.write_byte_data(0x21, 0x10, 0xf) # mask all interrupts bus.write_byte_data( 0x21, 0x03, 0x1) # set drive current and global interrupt disable bus.write_byte_data(0x21, 0x02, 0x2) # needed? bus.write_byte_data(0x21, 0x04, 0x4) # manual override source except IOError: print("LEON detected") LEON = True bus.close()
def setup_leon_fan(): bus = SMBus(7, force=True) # https://www.nxp.com/docs/en/data-sheet/PTN5150.pdf j = 0 for i in [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10]: print("FAN SPEED", j) ret = bus.read_i2c_block_data(0x3d, 0, 4) print(ret) ret = bus.write_i2c_block_data(0x3d, 0, [i]) time.sleep(1) ret = bus.read_i2c_block_data(0x3d, 0, 4) print(ret) j += 1 bus.close()
def temp(): bus = SMBus(1) sensor = MLX90614(bus, address=0x5A) print("Ambient Temperature :", sensor.get_ambient()) print("Object Temperature :", sensor.get_object_1()) temp = sensor.get_object_1() bus.close() if temp > 35: print("High Temperature") GPIO.output(buzzer, GPIO.HIGH) print("Buzzer ON") time.sleep(5) else: print("Normal temperature") Process() time.sleep(5)
def get_sid(self): sid = 99999 try: info = [0xffff] * 3 test = 0 bus = SMBus(I2CBUS) bus.write_byte_data(self.I2Caddr, SGP30_SID_MSB, SGP30_SID_LSB) time.sleep(0.01) #resp = bus.read_i2c_block_data( self.I2Caddr, 0, 9 ) read = i2c_msg.read(self.I2Caddr, 9) bus.i2c_rdwr(read) resp = list(read) bus.close() sid_1 = [resp[0], resp[1], resp[2]] sid_2 = [resp[3], resp[4], resp[5]] sid_3 = [resp[6], resp[7], resp[8]] if (self.crc8(sid_1) == 0): info[0] = (sid_1[0] << 8) | sid_1[1] test += 1 if (self.crc8(sid_2) == 0): info[1] = (sid_2[0] << 8) | sid_2[1] test += 1 if (self.crc8(sid_3) == 0): info[2] = (sid_3[0] << 8) | sid_3[1] test += 1 if test == 3: sid = (info[0] << 32) | (info[1] << 16) | info[2] print "sgp30.get_sid(): 0x%012x" % (sid) #log Serial ID f = open(self.FptrSID, "w") f.write("%d" % sid) f.close() else: print "sgp30.get_sid(): CRC error" except: bus.close() print "sgp30.get_sid() failed" return sid
def task(self): co2_val = 99999 try: bus = SMBus(I2CBUS) write = i2c_msg.write(self.I2Caddr, K30_MSG) bus.i2c_rdwr(write) time.sleep(0.02) read = i2c_msg.read(self.I2Caddr, 4) bus.i2c_rdwr(read) resp = list(read) bus.close() #print resp cs = resp[0] + resp[1] + resp[2] cs &= 0xff # check checksum if cs == resp[3]: co2_val = (resp[1] << 8) | resp[2] # sensor provides signed int if co2_val < 32767 and co2_val > 100: # read of i2c co2 value passes muster # include it in the rolling average self.co2_buff[self.co2_ptr] = co2_val self.co2_ptr += 1 if self.co2_ptr >= CO2_MAX: self.co2_ptr = 0 co2_avg = 0 for i in range(CO2_MAX): co2_avg += self.co2_buff[i] co2_avg /= CO2_MAX #print "CO2: %d" % co2_avg f = open(self.FptrCO2, "w") f.write("%d" % co2_avg) f.close() except: bus.close() print "k30.task() failed" return co2_val
def set_eon_fan(val): global last_eon_fan_val if last_eon_fan_val is None or last_eon_fan_val != val: bus = SMBus(7, force=True) try: i = [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10][val] bus.write_i2c_block_data(0x3d, 0, [i]) except OSError: # tusb320 if val == 0: bus.write_i2c_block_data(0x67, 0xa, [0]) else: bus.write_i2c_block_data(0x67, 0xa, [0x20]) bus.write_i2c_block_data(0x67, 0x8, [(val - 1) << 6]) bus.close() last_eon_fan_val = val
def run(self): self.running = True bus13 = SMBus(13) bus7 = SMBus(7) motors = MotorGroup(bus13) #motors = MagicMock() lux_sensor = LuxSensor(bus7) start_lux = lux_sensor.calibrate(1000) cherrypy.engine.log(f"{self.name} was initialised") try: target_finder = TargetFinder(self.camera, self.colour, self.debug_stream) self.camera.start_recording( output=target_finder, format='bgr', splitter_port=3, ) cherrypy.engine.log(f"{self.name} started the camera") # turn motors.set(-self.turn_speed, self.turn_speed) cherrypy.engine.log(f"{self.name} Where's the red????!") while self.running: if (target_finder.found_area >= self.min_area and abs(self.camera.resolution[0] / 2 - target_finder.found_centroid[0]) < self.center_size): motors.set(self.drive_speed, self.drive_speed) cherrypy.engine.log( f"{self.name} OOH RED! area={target_finder.found_area}" ) lux = lux_sensor.read() if lux not in range(int(start_lux - self.lux_range), int(start_lux + self.lux_range)): motors.set(0, 0) cherrypy.engine.log( f"{self.name} I found it, am I a good boy?") break while self.running: time.sleep(1 / float(self.camera.framerate)) finally: motors.set(0, 0) self.camera.stop_recording(splitter_port=3) bus13.close() bus7.close()
def get_baseline(self): try: # eCO2 baseline word first + crc # tVOC baseline word second + crc # these two lists need to be in reverse order for setting baseline bus = SMBus(I2CBUS) bus.write_byte_data(self.I2Caddr, SGP30_MSB, SGP30_GET_BASE) time.sleep(0.02) # for some reason an extra null byte is needed to get data resp = bus.read_i2c_block_data(self.I2Caddr, 0, 6) # below doesn't work #read = i2c_msg.read( selfI2Caddr, 6 ) #bus.i2c_rdwr(read) #resp = list(read) bus.close() # Because there are two set of baselines we will just # write them directly to the file-system instead of # looking for changes baseline_co2 = [resp[0], resp[1], resp[2]] baseline_voc = [resp[3], resp[4], resp[5]] if (self.crc8(baseline_co2) == 0): # comma delimited output #msg = str(baseline_co2).strip('[]') bl = (resp[0] << 8) | resp[1] f = open(self.FptrBaseC, "w") f.write("%d" % bl) f.close() print "sgp30.get_baseline() co2: 0x%04x" % bl if (self.crc8(baseline_voc) == 0): # comma delimited output #msg = str(baseline_voc).strip('[]') bl = (resp[3] << 8) | resp[4] f = open(self.FptrBaseV, "w") f.write("%d" % bl) f.close() print "sgp30.get_baseline() voc: 0x%04x" % bl except: bus.close() print "sgp30.get_baseline() failed"
def read_arduino(slave_addr, sensor_type): try: I2Cbus = SMBus(BUS) # byte = convert_bytes_to_list(bytes(str(sensor_type), "utf-8")) byte = int(sensor_type) # I2Cbus.write_i2c_block_data(slave_addr, MEMORY_ADDR, byte) I2Cbus.write_byte_data(slave_addr, MEMORY_ADDR, byte) response = I2Cbus.read_i2c_block_data(slave_addr, MEMORY_ADDR, BYTE_LEN) # response = I2Cbus.read_byte_data(slave_addr, MEMORY_ADDR) I2Cbus.close() return "ok", int(bytearray(response).decode("utf-8", "ignore")) # return "ok", response except: I2Cbus.close() print("failed to retrieve data from arduino...") print(traceback.format_exc()) return "error", traceback.format_exc()
def set_eon_fan(self, speed: int) -> None: if self.fan_speed != speed: # FIXME: this is such an ugly hack to get the right index val = speed // 16384 bus = SMBus(7, force=True) try: i = [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10][val] bus.write_i2c_block_data(0x3d, 0, [i]) except OSError: # tusb320 if val == 0: bus.write_i2c_block_data(0x67, 0xa, [0]) else: bus.write_i2c_block_data(0x67, 0xa, [0x20]) bus.write_i2c_block_data(0x67, 0x8, [(val - 1) << 6]) bus.close() self.fan_speed = speed
class RevvyTransportI2C(RevvyTransportBase): BOOTLOADER_I2C_ADDRESS = 0x2B ROBOT_I2C_ADDRESS = 0x2D def __init__(self, bus): self._bus = SMBus(bus) def _bind(self, address): return RevvyTransport(RevvyTransportI2CDevice(address, self._bus)) def create_bootloader_control(self) -> BootloaderControl: return BootloaderControl(self._bind(self.BOOTLOADER_I2C_ADDRESS)) def create_application_control(self) -> RevvyControl: return RevvyControl(self._bind(self.ROBOT_I2C_ADDRESS)) def close(self): self._bus.close()
def lm75a(address): if 1 < len(sys.argv): address = int(sys.argv[1], 16) try: bus = SMBus(1) raw = bus.read_word_data(address, 0) & 0xffff raw = ((raw << 8) & 0xffff) + (raw >> 8) temperature = (raw / 32.0) / 8.0 return temperature except Exception as e: print(e) finally: bus.close()
class RaspberryI2c(I2c): '''@brief version to actually use the I2C bus ''' def __init__(self, bus_id): '''@brief constructor ''' super(RaspberryI2c, self).__init__(bus_id) from smbus2 import SMBus self._bus = SMBus(bus='/dev/i2c-%d' % bus_id) def _write(self, address, register, data): self._bus.write_i2c_block_data(address, register, data) def _read(self, address, register, length): return bytes(self._bus.read_i2c_block_data(address, register, length)) def _close(self): self._bus.close()
def set_eon_fan(val): global LEON, last_eon_fan_val if not EON: return from smbus2 import SMBus if last_eon_fan_val is None or last_eon_fan_val != val: bus = SMBus(7, force=True) if LEON: i = [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10][val] bus.write_i2c_block_data(0x3d, 0, [i]) else: bus.write_byte_data(0x21, 0x04, 0x2) bus.write_byte_data(0x21, 0x03, (val*2)+1) bus.write_byte_data(0x21, 0x04, 0x4) bus.close() last_eon_fan_val = val
class LSM6: """ Usage is: with LSM6() as imu: """ DS33_SA0_HIGH_ADDRESS = 0b1101011 DS33_SA0_LOW_ADDRESS = 0b1101010 def __init__(self): self.bus = SMBus(1) self.address = self.DS33_SA0_HIGH_ADDRESS # TODO: high address is assumed, SA0 connected to supply voltage # Enable Accelerometer high performance mode, ODR = 1000, (+-2g) self.bus.write_byte_data(self.address, RegAddr['CTRL1_XL'], 0x80) # Enable Gyro high performance mode, ODR = 1000, (245 dps) self.bus.write_byte_data(self.address, RegAddr['CTRL2_G'], 0x80) # Enable auto increment self.bus.write_byte_data(self.address, RegAddr['CTRL3_C'], 0x04) def read_values(self): """ This function reads the IMUs measurements Returns: The sensors measurements in the following format (Gyro X, Gyro Y, Gyro Z, Acceleration X, Acc Y, Acc Z) """ value_list = self.bus.read_i2c_block_data( self.address, RegAddr['OUTX_L_G'], RegAddr['OUTZ_H_XL'] - RegAddr['OUTX_L_G']) value_list = [(value_list[i], value_list[i + 1]) for i in range(0, len(value_list), 2)] value_list = list(map(_calc_value, value_list)) for i in range(3): value_list[i] *= 4.375 # convert to MilliG for i in range(3, 6): value_list[i] *= 0.61 # convert to MilliDPS return tuple(value_list) def __enter__(self): return self def __exit__(self, exc_type, exc_value, exc_traceback): self.bus.close() return True
def set_comp(self, ah): msg = [SGP30_SET_AH] # start with command LSB # we don't want to completely turn off compensation when humididty is very low # per datasheet page 8/15 minimum value is 1/256 g/M^3 #if ah < 0.1: # ah = 0.01 # Enviro's very low winter time AH values may be causing large baseline offsets # testing limiting minimum AH value to 1g/M^3 if ah < 1.0: ah = 1.0 ah_i = int(ah // 1) # integer byte ah_i &= 0xff ah_d = int((ah % 1) * 256.0) # decimal byte ah_d &= 0xff ah_comp = [ah_i, ah_d] # in SGP30 format ah_crc = self.crc8(ah_comp) # addend crc byte ah_comp.append(ah_crc) # add AH data list to message list msg.extend(ah_comp) print "sgp30.set_comp(): set AH: %.1f" % (ah) print "sgp30.set_comp(): AH regs. 0x%02x 0x%02x" % (ah_i, ah_d) try: bus = SMBus(I2CBUS) resp = bus.write_i2c_block_data(self.I2Caddr, SGP30_MSB, msg) bus.close() time.sleep(0.01) # log AH value f = open(self.FptrAH, "w") f.write("%3.1f" % ah) f.close() except: bus.close() print "sgp30.set_comp() failed"
class IRTempProcessor(SensorProcessor): """MLX90614 sensor implementation (Infrared Temperature) Attributes: **_address (int)**: I2C address **_bus_id (int)**: I2C bus number **_bus (:obj: `SMBus`)**: smbus object **_sensor (:obj: `MLX90614`)**: MLX90614 sensor object """ def __init__(self): """Constructs a new IRTempProcessor instance""" super().__init__() self._address = None self._bus_id = None self._bus = None self._sensor = None def setup(self): """Sets up sensor configurations that should happen after loading from the database""" self._address = int(self._parameters['address'], 16) self._bus_id = int(self._parameters['bus_id']) def _read_sensor(self, ts): """Reads data from the sensor Args: **ts (int)**: timestamp of when the data was read """ self._bus = SMBus(self._bus_id) self._sensor = MLX90614(self._bus, address=self._address) data = { "ambient": self._sensor.get_ambient(), "object": self._sensor.get_object_1() } self._bus.close() return data
def setup_eon_fan(): global LEON if not EON: return os.system("echo 2 > /sys/module/dwc3_msm/parameters/otg_switch") from smbus2 import SMBus bus = SMBus(7, force=True) try: bus.write_byte_data(0x21, 0x10, 0xf) # mask all interrupts bus.write_byte_data(0x21, 0x03, 0x1) # set drive current and global interrupt disable bus.write_byte_data(0x21, 0x02, 0x2) # needed? bus.write_byte_data(0x21, 0x04, 0x4) # manual override source except IOError: print "LEON detected" #os.system("echo 1 > /sys/devices/soc/6a00000.ssusb/power_supply/usb/usb_otg") LEON = True bus.close()
def handle(self): # self.request is the TCP socket connected to the client self.data = self.request.recv(1024) print "{} wrote:".format(self.client_address[0]) speed = self.data.split(':') speed_left = int(100 * float(speed[0])) speed_right = int(100 * float(speed[1])) if speed_left < 0: speed_left = 256 + speed_left if speed_right < 0: speed_right = 256 + speed_right print(speed_left, speed_right) i2c = SMBus(1) i2c.write_byte(0x41, speed_left) i2c.write_byte(0x42, speed_right) i2c.close()
def set_eon_fan(val): global LEON, last_eon_fan_val if last_eon_fan_val is None or last_eon_fan_val != val: bus = SMBus(7, force=True) if LEON: try: i = [0x1, 0x3 | 0, 0x3 | 0x08, 0x3 | 0x10][val] bus.write_i2c_block_data(0x3d, 0, [i]) except IOError: # tusb320 if val == 0: bus.write_i2c_block_data(0x67, 0xa, [0]) else: bus.write_i2c_block_data(0x67, 0xa, [0x20]) bus.write_i2c_block_data(0x67, 0x8, [(val - 1) << 6]) else: bus.write_byte_data(0x21, 0x04, 0x2) bus.write_byte_data(0x21, 0x03, (val * 2) + 1) bus.write_byte_data(0x21, 0x04, 0x4) bus.close() last_eon_fan_val = val
class GDK101(object): '''driver code for GDK101 gamma ray sensor''' def __init__(self, busnum, addr): self.bus = SMBus(busnum) self.addr = addr rc = self.reset() if rc != 1: # reset failed raise Exception('GKD101: failed to reset sensor') def _readGKD101(self, cmd): '''implement simple I²C interface of GDK101 - send command - block-read two bytes ''' self.bus.write_byte_data(self.addr, 0, cmd) return self.bus.read_i2c_block_data(self.addr, 0, 2) def reset(self): d = self._readGKD101(CMD_reset) return d[0] def read1(self): ''' read 1 min average''' d = self._readGKD101(CMD_readDose1) return d[0] + d[1] / 100. def read10(self): ''' read 10 min sliding average''' d = self._readGKD101(CMD_readDose10) return d[0] + d[1] / 100. def version(self): '''return firmware version''' fw = self._readGKD101(CMD_firmware) return str(fw[0] + fw[1] / 10.) def close(self): '''close bus''' self.bus.close()
class Sensor: def __init__(self): self.SENSOR_DEVICE_ADDRESS = 0x0d self.SENSOR_BYTES = 20 self.I2C_MODE = 1 self.bus = SMBus(self.I2C_MODE) self.msg = i2c_msg.read(self.SENSOR_DEVICE_ADDRESS, self.SENSOR_BYTES) self.sensorIndex = { 'uv': [2], 'temp': [4, 5], 'pressure': [8, 9, 10, 11], 'atmtemp': [8, 9, 10, 11], 'humidity': [8, 9, 10, 11] } def parseMsg(self, msg): return [hex(i) for i in list(msg)] def getAllSensorValue(self): msg = self.msg self.bus.i2c_rdwr(msg) return self.parseMsg(msg) def getSensorValue(self, sensor): sensorValues = self.getAllSensorValue() bytesRequired = [] for i in self.sensorIndex[sensor]: bytesRequired.append(sensorValues[i]) return bytesRequired def getSensorValueBytes(self): msg = self.msg self.bus.i2c_rdwr(msg) return msg.__bytes__() def close(self): self.bus.close()
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()
def set_baseline(self, baseline_voc, baseline_co2): # tVOC baseline word first + crc # eCO2 baseline word second + crc baseline = [0x00] * 2 msg = [SGP30_SET_BASE] # start with command LSB # VOC first baseline[0] = (baseline_voc & 0xff00) >> 8 baseline[0] &= 0xff baseline[1] = baseline_voc & 0xff msg.extend(baseline) msg.append(self.crc8(baseline)) # Then eCO2 baseline[0] = (baseline_co2 & 0xff00) >> 8 baseline[0] &= 0xff baseline[1] = baseline_co2 & 0xff msg.extend(baseline) msg.append(self.crc8(baseline)) print "sgp30.set_baseline() voc: %02x %02x crc: %02x" % ( msg[1], msg[2], msg[3]) print "sgp30.set_baseline() co2: %02x %02x crc: %02x" % ( msg[4], msg[5], msg[6]) try: bus = SMBus(I2CBUS) resp = bus.write_i2c_block_data(self.I2Caddr, SGP30_MSB, msg) bus.close() time.sleep(0.01) except: bus.close() print "sgp30.set_baseline() failed"
class SGP30: def __init__(self, i2c_dev=None, i2c_msg=None, i2c_addr=SGP30_I2C_ADDR): """Mapping table of SGP30 commands. Friendly-name, followed by 16-bit command, then the number of parameter and response words. Each word is two bytes followed by a third CRC checksum byte. So a response length of 2 would result in the transmission of 6 bytes total. """ self.commands = { 'init_air_quality': (0x2003, 0, 0), 'measure_air_quality': (0x2008, 0, 2), 'get_baseline': (0x2015, 0, 2), 'set_baseline': (0x201e, 2, 0), 'set_humidity': (0x2061, 1, 0), # 'measure_test': (0x2032, 0, 1), # Production verification only 'get_feature_set_version': (0x202f, 0, 1), 'measure_raw_signals': (0x2050, 0, 2), 'get_serial_id': (0x3682, 0, 3) } self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._i2c_msg = i2c_msg if self._i2c_dev is None: from smbus2 import SMBus, i2c_msg self._i2c_msg = i2c_msg self._i2c_dev = SMBus(1) def command(self, command_name, parameters=None): if parameters is None: parameters = [] parameters = list(parameters) cmd, param_len, response_len = self.commands[command_name] if len(parameters) != param_len: raise ValueError("{} requires {} parameters. {} supplied!".format( command_name, param_len, len(parameters))) parameters_out = [cmd] for i in range(len(parameters)): parameters_out.append(parameters[i]) parameters_out.append(self.calculate_crc(parameters[i])) data_out = struct.pack('>H' + ('HB' * param_len), *parameters_out) msg_w = self._i2c_msg.write(self._i2c_addr, data_out) self._i2c_dev.i2c_rdwr(msg_w) time.sleep(0.025) # Suitable for all commands except 'measure_test' if response_len > 0: # Each parameter is a word (2 bytes) followed by a CRC (1 byte) msg_r = self._i2c_msg.read(self._i2c_addr, response_len * 3) self._i2c_dev.i2c_rdwr(msg_r) buf = msg_r.buf[0:response_len * 3] response = struct.unpack('>' + ('HB' * response_len), buf) verified = [] for i in range(response_len): offset = i * 2 value, crc = response[offset:offset + 2] if crc != self.calculate_crc(value): raise RuntimeError( "Invalid CRC in response from SGP30: {:02x} != {:02x}", crc, self.calculate_crc(value), buf) verified.append(value) return verified def calculate_crc(self, data): """Calculate an 8-bit CRC from a 16-bit word Defined in section 6.6 of the SGP30 datasheet. Polynominal: 0x31 (x8 + x5 + x4 + x1) Initialization: 0xFF Reflect input/output: False Final XOR: 0x00 """ crc = 0xff # Initialization value # calculates 8-Bit checksum with given polynomial for byte in [(data & 0xff00) >> 8, data & 0x00ff]: crc ^= byte for _ in range(8): if crc & 0x80: crc = (crc << 1) ^ 0x31 # XOR with polynominal else: crc <<= 1 return crc & 0xff def get_unique_id(self): result = self.command('get_serial_id') return result[0] << 32 | result[1] << 16 | result[0] def get_feature_set_version(self): result = self.command('get_feature_set_version')[0] return (result & 0xf000) >> 12, result & 0x00ff def start_measurement(self, run_while_waiting=None): """Start air quality measurement on the SGP30. The first 15 readings are discarded so this command will block for 15s. :param run_while_waiting: Function to call for every discarded reading. """ self.command('init_air_quality') testsamples = 0 while True: # Discard the initialisation readings as per page 8/15 of the datasheet eco2, tvoc = self.command('measure_air_quality') # The first 15 readings should return as 400, 0 so abort when they change # Break after 20 test samples to avoid a potential infinite loop if eco2 != 400 or tvoc != 0 or testsamples >= 20: break if callable(run_while_waiting): run_while_waiting() time.sleep(1.0) testsamples += 1 def get_air_quality(self): """Get an air quality measurement. Returns an instance of SGP30Reading with the properties equivalent_co2 and total_voc. This should be called at 1s intervals to ensure the dynamic baseline compensation on the SGP30 operates correctly. """ eco2, tvoc = self.command('measure_air_quality') return SGP30Reading(eco2, tvoc) def get_baseline(self): """Get the current baseline setting. Returns an instance of SGP30Reading with the properties equivalent_co2 and total_voc. """ eco2, tvoc = self.command('get_baseline') return SGP30Reading(eco2, tvoc) def set_baseline(self, eco2, tvoc): self.command('set_baseline', [tvoc, eco2]) def __del__(self): self._i2c_dev.close()
def get_y_rotation(x, y, z): radians = math.atan(y / dist(x, z)) return radians def get_z_rotation(x, y, z): radians = math.atan(z / dist(x, y)) return radians bus.write_byte_data(DEV_ADDR, 0x6B, 0b00000000) try: while True: x = read_data(register_accel_xout_h) y = read_data(register_accel_yout_h) z = read_data(register_accel_zout_h) aX = get_x_rotation(accel_g(x), accel_g(y), accel_g(z)) aY = get_y_rotation(accel_g(x), accel_g(y), accel_g(z)) aZ = get_z_rotation(accel_g(x), accel_g(y), accel_g(z)) data = str(aX) + ' , ' + str(aY) + ' , ' + str(aZ) + '$' print(data) time.sleep(0.3) except KeyboardInterrupt: print("\nInterrupted!") except: print("\nClosing socket") finally: bus.close()
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 I2CBus(I2CInterface): """An I2C bus implementation for the Raspberry Pi. Derived from the SMBus2 library by 'kplindegaard' at https://github.com/kplindegaard/smbus2. """ def __init__(self, board_rev=board_revision.REV1): """Initialize a new instance of I2CBus. :param int board_rev: The board revision. """ I2CInterface.__init__(self) self.__busID = 1 if board_rev == board_revision.REV1: self.__busID = 0 self.__isOpen = False self.__bus = None @property def is_open(self): """Get a value indicating whether the connection is open. :returns: True if the connection is open. :rtype: bool """ return self.__isOpen def open(self): """Open a connection to the I2C bus. :raises: raspy.object_disposed_exception.ObjectDisposedException if this instance has been disposed. :raises: raspy.io.io_exception.IOException if unable to open the bus connection. """ if self.is_disposed: raise ObjectDisposedException("I2CBus") if self.__isOpen: return try: self.__bus = SMBus(self.__busID) except OSError or IOError: msg = "Error opening bus '" + str(self.__busID) + "'." raise IOException(msg) if self.__bus.fd is None: msg = "Error opening bus '" + str(self.__busID) + "'." raise IOException(msg) self.__isOpen = True def close(self): """Close the bus connection.""" if self.is_disposed: return if self.__isOpen: if self.__bus is not None: self.__bus.close() self.__isOpen = False self.__bus = None def dispose(self): """Dispose of all the managed resources used by this instance.""" if self.is_disposed: return self.close() self.__busID = None I2CInterface.dispose(self) def write_bytes(self, address, buf): """Write a list of bytes to the specified device address. Currently, RPi drivers do not allow writing more than 3 bytes at a time. As such, if any list of greater than 3 bytes is provided, an exception is thrown. :param int address: The address of the target device. :param list buf: A list of bytes to write to the bus. :raises: raspy.object_disposed_exception.ObjectDisposedException if this instance has been disposed. :raises: raspy.invalid_operation_exception.InvalidOperationException if a connection to the I2C bus has not yet been opened. :raises: raspy.illegal_argument_exception.IllegalArgumentException if the buffer contains more than 3 bytes or if the specified buffer parameter is not a list. :raises: raspy.io.io_exception.IOException if an error occurs while writing the buffer contents to the I2C bus or if only a partial write succeeds. """ if self.is_disposed: raise ObjectDisposedException("I2CBus") if not self.__isOpen: raise InvalidOperationException("No open connection to write to.") if isinstance(buf, list): if len(buf) > 3: # TODO we only do this to keep parity with the JS and C# # ports. They each have their own underlying native # implementations. SMBus2 itself is capable of writing # much more than 3 bytes. We should change this as soon # as we can get the other ports to support more. msg = "Cannot write more than 3 bytes at a time." raise IllegalArgumentException(msg) else: msg = "The specified buf param value is not a list." raise IllegalArgumentException(msg) try: trans = i2c_msg.write(address, buf) self.__bus.i2c_rdwr(trans) except OSError or IOError: msg = "Error writing to address '" + str(address) msg += "': I2C transaction failed." raise IOException(msg) def write_byte(self, address, byt): """Write a single byte to the specified device address. :param int address: The address of the target device. :param int byt: The byte value to write. :raises: raspy.object_disposed_exception.ObjectDisposedException if this instance has been disposed. :raises: raspy.invalid_operation_exception.InvalidOperationException if a connection to the I2C bus has not yet been opened. :raises: raspy.io.io_exception.IOException if an error occurs while writing the buffer contents to the I2C bus or if only a partial write succeeds. """ buf = list() buf[0] = byt self.write_bytes(address, buf) def write_command(self, address, command, data1=None, data2=None): """Write a command with data to the specified device address. :param int address: The address of the target device. :param int command: The command to send to the device. :param int data1: The data to send as the first parameter (optional). :param int data2: The data to send as the second parameter (optional). :raises: raspy.object_disposed_exception.ObjectDisposedException if this instance has been disposed. :raises: raspy.invalid_operation_exception.InvalidOperationException if a connection to the I2C bus has not yet been opened. :raises: raspy.io.io_exception.IOException if an error occurs while writing the buffer contents to the I2C bus or if only a partial write succeeds. """ buf = list() buf[0] = command if data1: buf[1] = data1 if data1 and data2: buf[1] = data1 buf[2] = data2 self.write_bytes(address, buf) def write_command_byte(self, address, command, data): """Write a command with data to the specified device address. :param int address: The address of the target device. :param int command: The command to send to the device. :param int data: The data to send with the command. :raises: raspy.object_disposed_exception.ObjectDisposedException if this instance has been disposed. :raises: raspy.invalid_operation_exception.InvalidOperationException if a connection to the I2C bus has not yet been opened. :raises: raspy.io.io_exception.IOException if an error occurs while writing the buffer contents to the I2C bus or if only a partial write succeeds. """ buf = list() buf[0] = command buf[1] = data & 0xff buf[2] = data >> 8 self.write_bytes(address, buf) def read_bytes(self, address, count): """Read bytes from the device at the specified address. :param int address: The address of the device to read from. :param int count: The number of bytes to read. :returns: The bytes read. :rtype: list :raises: raspy.object_disposed_exception.ObjectDisposedException if this instance has been disposed. :raises: raspy.invalid_operation_exception.InvalidOperationException if a connection to the I2C bus has not yet been opened. :raises: raspy.io.io_exception.IOException if an error occurs while writing the buffer contents to the I2C bus or if only a partial write succeeds. """ if self.is_disposed: return if not self.__isOpen: raise InvalidOperationException("No open connection to read from.") buf = [] msg = "Error reading from address '" + str(address) msg += "': I2C transaction failed." try: trans = i2c_msg.read(address, count) self.__bus.i2c_rdwr(trans) buf = list(trans) except OSError or IOError: raise IOException(msg) if len(buf) <= 0: raise IOException(msg) return buf def read(self, address): """Read a single byte from the device at the specified address. :param int address: The address of the device to read from. :returns: The byte read. :rtype: int :raises: raspy.object_disposed_exception.ObjectDisposedException if this instance has been disposed. :raises: raspy.invalid_operation_exception.InvalidOperationException if a connection to the I2C bus has not yet been opened. :raises: raspy.io.io_exception.IOException if an error occurs while writing the buffer contents to the I2C bus or if only a partial write succeeds. """ result = self.read_bytes(address, 1) return result[0]
class VideoCamera(object): def __init__(self): self.servoxPIN = 32 self.servoyPIN = 33 self.camera = PiCamera() self.camera.framerate = 32 self.camera.rotation = 180 self.rawCapture = PiRGBArray(self.camera) # allow the camera to warmup time.sleep(0.1) self.send_email = os.environ.get('SEND_EMAIL') self.mid = 0 self.temp = None self.detector = dlib.get_frontal_face_detector() self.predictor = dlib.shape_predictor( "models/shape_predictor_68_face_landmarks.dat") self.model = load_model('models/mask_detector.h5') self.mask_detection_completed = False self.mask_count = 0 self.temperature_check_completed = False self.operation_status_failed = False if self.send_email == 'TRUE': self.sender_email = os.environ.get('EMAIL_ID') self.receiver_email = os.environ.get('EMAIL_ID') self.password = os.environ.get('EMAIL_PWD') self.message = MIMEMultipart("alternative") self.message[ "Subject"] = "Alert: A New Person Entered the Premises" self.message["From"] = self.sender_email self.message["To"] = self.receiver_email self.servoX = Servo(self.servoxPIN) self.servoY = Servo(self.servoyPIN) self.servoX.setAngle(90) self.servoY.setAngle(90) self.bus = SMBus(1) self.sensor = MLX90614(self.bus, address=0x5A) def detect_mask(self, image): copy_img = image.copy() resized = cv2.resize(copy_img, (254, 254)) resized = img_to_array(resized) resized = preprocess_input(resized) resized = np.expand_dims(resized, axis=0) mask, _ = self.model.predict([resized])[0] return mask def email(self, img_path, temp, mask): with open(img_path, 'rb') as f: # set attachment mime and file name, the image type is png mime = MIMEBase('image', 'png', filename='img1.png') # add required header data: mime.add_header('Content-Disposition', 'attachment', filename='img1.png') mime.add_header('X-Attachment-Id', '0') mime.add_header('Content-ID', '<0>') # read attachment file content into the MIMEBase object mime.set_payload(f.read()) # encode with base64 encoders.encode_base64(mime) # add MIMEBase object to MIMEMultipart object self.message.attach(mime) body = MIMEText( ''' <html> <body> <h1>Alert</h1> <h2>A new has Person entered the Premises</h2> <h2>Body Temperature: {}</h2> <h2>Mask: {}</h2> <h2>Time: {}</h2> <p> <img src="cid:0"> </p> </body> </html>'''.format(temp, mask, datetime.now()), 'html', 'utf-8') self.message.attach(body) context = ssl.create_default_context() with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server: server.login(self.sender_email, self.password) server.sendmail(self.sender_email, self.receiver_email, self.message.as_string()) def __del__(self): self.servoX.stop() self.servoY.stop() self.GPIO.cleanup() self.bus.close() def get_frame(self): success, img = True, self.frame.array img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) im_p = Image.fromarray(img) draw = ImageDraw.Draw(im_p) font_3 = ImageFont.truetype("Arial Unicode.ttf", 100) global mask_detected, body_temperature, temp_high, temp_low, not_proceed, proceed, visitor_id, promt promt = None if success: if self.mask_detection_completed is False: mask_prob = self.detect_mask(img) if mask_prob > 0.5: self.mask_count += 1 if self.mask_count >= 5: self.mask_detection_completed = True self.pidX = PID() self.pidY = PID() self.pidX.initialize() self.pidY.initialize() elif mask_prob < 0.5: mask_detected = False elif self.mask_detection_completed: if self.temperature_check_completed is False: mask_detected = True faces = self.detector(img_gray, 0) if len(faces) > 0: for face in faces: landmarks = self.predictor(img_gray, face) im_n = np.array(im_p) landmarks_list = [] for i in range(0, landmarks.num_parts): landmarks_list.append( (landmarks.part(i).x, landmarks.part(i).y)) cv2.circle( im_n, (landmarks.part(i).x, landmarks.part(i).y), 4, (255, 255, 255), -1) dist = np.sqrt((landmarks.part(21).x - landmarks.part(22).x)**2 + (landmarks.part(21).y - landmarks.part(22).y)**2) face_ptx, face_pty = (int( (landmarks.part(21).x + landmarks.part(22).x) / 2), int((landmarks.part(21).y + landmarks.part(22).y) / 2) - int(dist)) cv2.circle(im_n, (face_ptx, face_pty), 4, (0, 255, 0), -1) Y, X, _ = img.shape sensor_ptx, sensor_pty = (int(X / 2), int(Y / 3)) cv2.rectangle(im_n, (sensor_ptx - 10, sensor_pty - 10), (sensor_ptx + 10, sensor_pty + 10), (255, 0, 0), 4) cv2.circle(im_n, (sensor_ptx, sensor_pty), 5, (255, 0, 0), -1) diff_x, diff_y = sensor_ptx - face_ptx, sensor_pty - face_pty if -10 < diff_x < 10 and -10 < diff_y < 10: self.temp = self.sensor.get_amb_temp() body_temperature = self.temp if self.temp > 100: temp_high = True self.operation_status_failed = True self.temperature_check_completed = True else: temp_low = True self.temperature_check_completed = True else: im_p = Image.fromarray(im_n) draw = ImageDraw.Draw(im_p) servoX.setAngle(-1 * self.pidX.update(diff_x)) servoY.setAngle(-1 * self.pidY.update(diff_y)) if diff_x > 0: draw.text((700, 500), '→', (0, 0, 0), font=font_3) elif diff_x < 0: draw.text((700, 500), '←', (0, 0, 0), font=font_3) if diff_y > 0: draw.text((600, 500), '↓', (0, 0, 0), font=font_3) elif diff_y < 0: draw.text((600, 500), '↑', (0, 0, 0), font=font_3) else: promt = 'No Face Detected Please remove mask' elif self.temperature_check_completed: proceed = True c_id = os.environ.get('COUNTER_ID') cv2.imwrite('pictures/{}.jpg'.format(str(c_id)), img) self.email('pictures/{}.jpg'.format(c_id), self.temp, 'Wearing') os.environ['COUNTER_ID'] = str(int(c_id) + 1) self.mid += 1 # Reset self.mask_detection_completed = False self.mask_count = 0 self.temperature_check_completed = False self.temp = None mask_detected = False body_temperature = None temp_high = False temp_low = False not_proceed = False proceed = False promt = None elif self.operation_status_failed: self.mask_detection_completed = False self.mask_count = 0 self.temperature_check_completed = False self.temp = None self.operation_status_failed = False mask_detected = False body_temperature = None temp_high = False temp_low = False not_proceed = False proceed = False promt = None visitor_id = self.mid + 1 img = np.array(im_p) self.rawCapture.truncate(0) ret, jpeg = cv2.imencode('.jpg', img) return jpeg.tobytes()
def test_func(self): bus = SMBus(1) print("\nSupported I2C functionality: %x" % bus.funcs) bus.close()