class Pi_hat_adc(): def __init__(self, bus_num=1, addr=ADC_DEFAULT_IIC_ADDR): self.bus = Bus(bus_num) self.addr = addr # get all raw adc data,THe max value is 4095,cause it is 12 Bit ADC def get_all_adc_raw_data(self): array = [] for i in range(ADC_CHAN_NUM): data = self.bus.read_i2c_block_data(self.addr, REG_RAW_DATA_START + i, 2) val = data[1] << 8 | data[0] array.append(val) return array def get_nchan_adc_raw_data(self, n): data = self.bus.read_i2c_block_data(self.addr, REG_RAW_DATA_START + n, 2) val = data[1] << 8 | data[0] return val # get all data with unit mv. def get_all_vol_milli_data(self): array = [0 for _ in range(ADC_CHAN_NUM)] for i in range(ADC_CHAN_NUM): data = self.bus.read_i2c_block_data(self.addr, REG_VOL_START + i, 2) val = data[1] << 8 | data[0] array[i] = val return array def get_nchan_vol_milli_data(self, n): data = self.bus.read_i2c_block_data(self.addr, REG_VOL_START + n, 2) val = data[1] << 8 | data[0] return val
class GroveTemperatureHumiditySensorSHT3x(object): def __init__(self, address=0x45, bus=None): self.address = address # I2C bus self.bus = Bus(bus) def read(self): # high repeatability, clock stretching disabled self.bus.write_i2c_block_data(self.address, 0x24, [0x00]) # measurement duration < 16 ms time.sleep(0.016) # read 6 bytes back # Temp MSB, Temp LSB, Temp CRC, Humididty MSB, Humidity LSB, Humidity CRC data = self.bus.read_i2c_block_data(0x45, 0x00, 6) temperature = data[0] * 256 + data[1] celsius = -45 + (175 * temperature / 65535.0) humidity = 100 * (data[3] * 256 + data[4]) / 65535.0 if data[2] != CRC(data[:2]): raise RuntimeError("temperature CRC mismatch") if data[5] != CRC(data[3:5]): raise RuntimeError("humidity CRC mismatch") return celsius, humidity
class GroveTemperatureHumidityAHT20(object): def __init__(self, address=0x38, bus=None): self.address = address # I2C bus self.bus = Bus(bus) def read(self): self.bus.write_i2c_block_data(self.address, 0x00, [0xac, 0x33, 0x00]) # measurement duration < 16 ms time.sleep(0.016) data = self.bus.read_i2c_block_data(self.address, 0x00, 6) humidity = data[1] humidity <<= 8 humidity += data[2] humidity <<= 4 humidity += (data[3] >> 4) humidity /= 1048576.0 humidity *= 100 temperature = data[3] & 0x0f temperature <<= 8 temperature += data[4] temperature <<= 8 temperature += data[5] temperature = temperature / 1048576.0 * 200.0 - 50.0 # Convert to Celsius return temperature, humidity
class Pi_hat_adc(): def __init__(self,bus_num=1,addr=ADC_DEFAULT_IIC_ADDR): self.bus=Bus(bus_num) self.addr=addr def get_all_vol_milli_data(self): array = [] for i in range(ADC_CHAN_NUM): data=self.bus.read_i2c_block_data(self.addr,REG_VOL_START+i,2) val=data[1]<<8|data[0] array.append(val) return array def get_nchan_vol_milli_data(self,n): data=self.bus.read_i2c_block_data(self.addr,REG_VOL_START+n,2) val =data[1]<<8|data[0] return val
class Pi_hat_adc(): def __init__(self,bus_num=1,addr=0X04): self.bus=Bus(bus_num) self.addr=addr #get all raw adc data,THe max value is 4095,cause it is 12 Bit ADC def get_all_adc_raw_data(self): array = [] for i in range(8): data=self.bus.read_i2c_block_data(self.addr,0X10+i,2) val=data[1]<<8|data[0] array.append(val) return array def get_nchan_adc_raw_data(self,n): data=self.bus.read_i2c_block_data(self.addr,0X10+n,2) val =data[1]<<8|data[0] return val
class I2C_Station: def __init__(self, weather_sensor_address=Config.I2C_WEATHER_SENSOR_ADDRESS, bus=None): self.weather_sensor_address = weather_sensor_address self.bus = Bus(bus) if Config.ENABLE_POWERGAUGE: self.powergauge_module = LC709203F( board.I2C(), address=Config.I2C_POWERGAUGE_ADDRESS) def CRC(self, data): crc = 0xff for s in data: crc ^= s for _ in range(8): if crc & 0x80: crc <<= 1 crc ^= 0x131 else: crc <<= 1 return crc def read_weather_data(self): self.bus.write_i2c_block_data(self.weather_sensor_address, 0x24, [0x00]) time.sleep(0.016) data = self.bus.read_i2c_block_data(self.weather_sensor_address, 0x00, 6) temperature = data[0] * 256 + data[1] celsius = -45 + (175 * temperature / 65535.0) humidity = 100 * (data[3] * 256 + data[4]) / 65535.0 return celsius, humidity def get_power_stats(self): try: voltage = self.powergauge_module.cell_voltage power = self.powergauge_module.cell_percent except Exception as e: voltage = None power = None return power, voltage
class GroveTemperatureHumiditySensorSHT3x(object): def __init__(self, address=0x45, bus=None): self.address = address # I2C bus self.bus = Bus(bus) def CRC(self, data): crc = 0xff for s in data: crc ^= s for i in range(8): if crc & 0x80: crc <<= 1 crc ^= 0x131 else: crc <<= 1 return crc def read(self): # High repeatability, clock stretching disabled self.bus.write_i2c_block_data(self.address, 0x24, [0x00]) # Measurement duration < 16 ms time.sleep(0.016) # Read 6 bytes back: # Temp MSB, Temp LSB, Temp CRC, # Humididty MSB, Humidity LSB, Humidity CRC data = self.bus.read_i2c_block_data(0x45, 0x00, 6) temperature = data[0] * 256 + data[1] celsius = -45 + (175 * temperature / 65535.0) humidity = 100 * (data[3] * 256 + data[4]) / 65535.0 if data[2] != self.CRC(data[:2]): raise RuntimeError("Temperature CRC mismatch") if data[5] != self.CRC(data[3:5]): raise RuntimeError("Humidity CRC mismatch") return celsius, humidity
class ADXL372(object): def __init__(self, address=0x53, i2c=None): self.address = address self.bus = Bus(i2c) print('ID: {}'.format(self.id)) self.reset() self._timing_control = 0 self._power_control = 0 self._measurement_control = 0 self._sample_rate = 400 self._bandwidth = 200 self._mode = STANDBY_MODE def read(self): raw = self.bus.read_i2c_block_data(self.address, ADXL372_X_DATA_H, 6) return self.xyz(raw) def read_fifo(self, size): data = [] while size > 32: data.extend( self.bus.read_i2c_block_data(self.address, ADXL372_FIFO_DATA, 32)) size -= 32 if size: data.extend( self.bus.read_i2c_block_data(self.address, ADXL372_FIFO_DATA, size)) return data def reset(self): self.write_register(ADXL372_SRESET, 0x52) def timing_control(self, sample_rate=400, wakeup_ms=52): try: sample_bits = ADXL372_SAMPLE_RATE.index(sample_rate) wakeup_bits = ADXL372_WAKEUP_TIME.index(wakeup_ms) except ValueError: print('Supported sample rates: {}'.format(ADXL372_SAMPLE_RATE)) print('Supported wakeup time: {}'.format(ADXL372_WAKEUP_TIME)) raise ValueError('Invalid sample rate or wakeup time') self._timing_control = (sample_bits << TIMING_ODR_POS) | ( wakeup_bits << TIMING_WUR_POS) self._sample_rate = sample_rate self.write_register(ADXL372_TIMING, self._timing_control) def power_control(self, mode=0, low_pass_filter=0, high_pass_filter=0): if mode not in ADXL372_OP_MODE: raise ValueError('Invalid operating mode') value = mode if not low_pass_filter: value |= 1 << 3 if not high_pass_filter: value |= 1 << 2 self._mode = mode self._power_control = value self.write_register(ADXL372_POWER_CTL, value) def measurement_control(self, bandwidth=200, low_noise=0, linkloop=0, autosleep=0): try: value = ADXL372_BANDWIDTH.index(bandwidth) except ValueError: print('Supported bandwidth: {}'.format(ADXL372_BANDWIDTH)) raise ValueError('Invalid bandwidth') if low_noise: value |= 1 << 3 if linkloop: value |= linkloop << 4 if autosleep: value |= 1 << 6 self._measurement_control = value self.write_register(ADXL372_MEASURE, value) def fifo_control(self, mode=FIFO_STREAMED, format=FIFO_XYZ, samples=0x80): self.write_register(ADXL372_FIFO_SAMPLES, samples & 0xFF) self.write_register(ADXL372_FIFO_CTL, ((samples >> 8) & 0x1) | (mode << 1) | (format << 3)) @property def sample_rate(self): return self._sample_rate @sample_rate.setter def sample_rate(self, value): self._sample_rate = value try: simple_bits = ADXL372_SAMPLE_RATE.index(value) except ValueError: print('Supported sample rates: {}'.format(ADXL372_SAMPLE_RATE)) raise ValueError('Invalid sample rate') self._timing_control = (self._timing_control & TIMING_ODR_MASK) | ( simple_bits << TIMING_ODR_POS) self.write_register(ADXL372_TIMING, self._timing_control) @property def bandwidth(self): return self._bandwidth @bandwidth.setter def bandwidth(self, value): if value in ADXL372_BANDWIDTH: self._bandwidth = value bandwidth_bits = ADXL372_BANDWIDTH.index(value) self._measurement_control = ( self._measurement_control & MEASURE_BANDWIDTH_MASK) | bandwidth_bits else: print('Supported bandwidth: {}'.format(ADXL372_BANDWIDTH)) raise ValueError('Invalid bandwidth') @property def mode(self): return self._mode @mode.setter def mode(self, value): if value in ADXL372_OP_MODE: self._mode = value self._power_control = (self._power_control & PWRCTRL_OPMODE_MASK) | value self.write_register(ADXL372_POWER_CTL, value) else: raise ValueError('Invalid operating mode') @property def samples_in_fifo(self): data = self.bus.read_word_data(self.address, ADXL372_FIFO_ENTRIES_2) return ((data & 0x3) << 8) | ((data >> 8) & 0xFF) @property def status(self): return self.bus.read_word_data(self.address, ADXL372_STATUS_1) @property def id(self): return self.bus.read_i2c_block_data(self.address, ADXL372_ADI_DEVID, 4) def read_register(self, register): return self.bus.read_byte_data(self.address, register) def write_register(self, register, value): self.bus.write_byte_data(self.address, register, value) def update_register(self, register, mask, shift, value): data = self.read_register(register) data = (data & mask) | ((value << shift) & ~mask) self.write_register(register, data) def dump_registers(self): registers = self.bus.read_i2c_block_data(self.address, 0x39, 0x43 - 0x39) for register in registers: print(hex(register)) def xyz(self, raw): value = [0] * 3 for i in range(3): value[i] = (raw[2 * i] << 4) | (raw[2 * i + 1] >> 4) if value[i] & 0xF00: value[i] = -((~value[i] & 0xFFF) + 1) return value
class grove_si114x(object): def __init__(self, address=SI114X_ADDR): self.bus = Bus() self.addr = address self._logger = logging.getLogger('grove_si114x') assert self.Begin( ), "Please check if the I2C device insert in I2C of Base Hat" def __del__(self): self._WriteByte(SI114X_COMMAND, SI114X_RESET) time.sleep(0.1) self.bus.close() def __exit__(self): self.bus.close() #Init the si114x and begin to collect data def Begin(self): if self._ReadByte(SI114X_PART_ID) != 0X45: return False self.Reset() #INIT self.DeInit() return True #reset the si114x #inclue IRQ reg, command regs... def Reset(self): self._WriteByte(SI114X_MEAS_RATE0, 0) self._WriteByte(SI114X_MEAS_RATE1, 0) self._WriteByte(SI114X_IRQ_ENABLE, 0) self._WriteByte(SI114X_IRQ_MODE1, 0) self._WriteByte(SI114X_IRQ_MODE2, 0) self._WriteByte(SI114X_INT_CFG, 0) self._WriteByte(SI114X_IRQ_STATUS, 0xFF) self._WriteByte(SI114X_COMMAND, SI114X_RESET) time.sleep(0.1) self._WriteByte(SI114X_HW_KEY, 0x17) time.sleep(0.1) #default init def DeInit(self): #ENABLE UV reading #these reg must be set to the fixed value self._WriteByte(SI114X_UCOEFF0, 0x29) self._WriteByte(SI114X_UCOEFF1, 0x89) self._WriteByte(SI114X_UCOEFF2, 0x02) self._WriteByte(SI114X_UCOEFF3, 0x00) self.WriteParamData( SI114X_CHLIST, SI114X_CHLIST_ENUV | SI114X_CHLIST_ENALSIR | SI114X_CHLIST_ENALSVIS | SI114X_CHLIST_ENPS1) # #set LED1 CURRENT(22.4mA)(It is a normal value for many LED) # self.WriteParamData(SI114X_PS1_ADCMUX, SI114X_ADCMUX_LARGE_IR) self._WriteByte(SI114X_PS_LED21, SI114X_LED_CURRENT_22MA) self.WriteParamData(SI114X_PSLED12_SELECT, SI114X_PSLED12_SELECT_PS1_LED1) # # #PS ADC SETTING # self.WriteParamData(SI114X_PS_ADC_GAIN, SI114X_ADC_GAIN_DIV1) self.WriteParamData(SI114X_PS_ADC_COUNTER, SI114X_ADC_COUNTER_511ADCCLK) self.WriteParamData( SI114X_PS_ADC_MISC, SI114X_ADC_MISC_HIGHRANGE | SI114X_ADC_MISC_ADC_RAWADC) # #VIS ADC SETTING # self.WriteParamData(SI114X_ALS_VIS_ADC_GAIN, SI114X_ADC_GAIN_DIV1) self.WriteParamData(SI114X_ALS_VIS_ADC_COUNTER, SI114X_ADC_COUNTER_511ADCCLK) self.WriteParamData(SI114X_ALS_VIS_ADC_MISC, SI114X_ADC_MISC_HIGHRANGE) # #IR ADC SETTING # self.WriteParamData(SI114X_ALS_IR_ADC_GAIN, SI114X_ADC_GAIN_DIV1) self.WriteParamData(SI114X_ALS_IR_ADC_COUNTER, SI114X_ADC_COUNTER_511ADCCLK) self.WriteParamData(SI114X_ALS_IR_ADC_MISC, SI114X_ADC_MISC_HIGHRANGE) # #interrupt enable # self._WriteByte(SI114X_INT_CFG, SI114X_INT_CFG_INTOE) self._WriteByte(SI114X_IRQ_ENABLE, SI114X_IRQEN_ALS) # #AUTO RUN # self._WriteByte(SI114X_MEAS_RATE0, 0xFF) self._WriteByte(SI114X_COMMAND, SI114X_PSALS_AUTO) #read param data def ReadParamData(self, Reg): self._WriteByte(SI114X_COMMAND, Reg | SI114X_QUERY) return self._ReadByte(SI114X_RD) #writ param data def WriteParamData(self, Reg, Value): #write Value into PARAMWR reg first self._WriteByte(SI114X_WR, Value) self._WriteByte(SI114X_COMMAND, Reg | SI114X_SET) #SI114X writes value out to PARAM_RD,read and confirm its right return self._ReadByte(SI114X_RD) #Read Visible Value @property def ReadVisible(self): return self._ReadHalfWord(SI114X_ALS_VIS_DATA0) #Read IR Value @property def ReadIR(self): return self._ReadHalfWord(SI114X_ALS_IR_DATA0) #Read UV Value #this function is a int value ,but the real value must be div 100 @property def ReadUV(self): return self._ReadHalfWord(SI114X_AUX_DATA0_UVINDEX0) #Read Proximity Value def ReadProximity(self, PSn): return self._ReadHalfWord(PSn) # read 8 bit data from Reg def _ReadByte(self, Reg): try: read_data = self.bus.read_byte_data(self.addr, Reg) except OSError: raise OSError( "Please check if the I2C device insert in I2C of Base Hat") return read_data # Write 8 bit data to Reg def _WriteByte(self, Reg, Value): try: self.bus.write_byte_data(self.addr, Reg, Value) except OSError: raise OSError( "Please check if the I2C device insert in I2C of Base Hat") # read 16 bit data from Reg def _ReadHalfWord(self, Reg): try: block = self.bus.read_i2c_block_data(self.addr, Reg, 2) except OSError: raise OSError( "Please check if the I2C device insert in I2C of Base Hat") read_data = (block[0] & 0xff) | (block[1] << 8) return read_data
class GroveThermocoupleAmpMCP9600(object): def __init__(self, address = 0x60): self._addr = address self._bus = Bus() self._therm = THER_TYPE_K self._junc = HOT_JUNCTION_REG_ADDR self._junc_res = COLD_JUNC_RESOLUTION_0_625 def _read_version(self): version = self._bus.read_i2c_block_data(self._addr,VERSION_ID_REG_ADDR,2) return version def _set_filt_coefficients(self,coefficients): data = self._bus.read_byte_data(self._addr,THERM_SENS_CFG_REG_ADDR) data = (data & 0xF8) | coefficients self._bus.write_byte_data(self._addr,THERM_SENS_CFG_REG_ADDR,data) def _set_cold_junc_resolution(self,junc_res): data = self._bus.read_byte_data(self._addr,DEVICE_CFG_REG_ADDR) data = (data & 0x7F) | junc_res self._bus.write_byte_data(self._addr,DEVICE_CFG_REG_ADDR,data) self._junc_res = junc_res def _set_ADC_meas_resolution(self,res): data = self._bus.read_byte_data(self._addr,DEVICE_CFG_REG_ADDR) data = (data & 0x9F) | res self._bus.write_byte_data(self._addr,DEVICE_CFG_REG_ADDR,data) def _set_burst_mode_samp(self,samp): data = self._bus.read_byte_data(self._addr,DEVICE_CFG_REG_ADDR) data = (data & 0xE3) | samp self._bus.write_byte_data(self._addr,DEVICE_CFG_REG_ADDR,data) def _set_sensor_mode(self,mode): data = self._bus.read_byte_data(self._addr,DEVICE_CFG_REG_ADDR) data = (data & 0xFC) | mode self._bus.write_byte_data(self._addr,DEVICE_CFG_REG_ADDR,data) def get_config(self): config1 = self._bus.read_byte_data(self._addr,DEVICE_CFG_REG_ADDR) config2 = self._bus.read_byte_data(self._addr,THERM_SENS_CFG_REG_ADDR) return config1, config2 def set_therm_type(self,therm_type): therm_cfg_data = self._bus.read_byte_data(self._addr,THERM_SENS_CFG_REG_ADDR) therm_cfg_data = (therm_cfg_data & 0x8F) | therm_type self._bus.write_byte_data(self._addr,THERM_SENS_CFG_REG_ADDR,therm_cfg_data) self._therm = therm_type def set_junc_type(self, junc): if not junc is None: self._junc = junc return self._junc def set_config(self, filter = FILT_OFF, junc_res = COLD_JUNC_RESOLUTION_0_625, adc_res = ADC_14BIT_RESOLUTION, burst_smps = BURST_1_SAMPLE, oper_mode = NORMAL_OPERATION ): self._set_filt_coefficients(filter) self._set_cold_junc_resolution(junc_res) self._set_ADC_meas_resolution(adc_res) self._set_burst_mode_samp(burst_smps) self._set_sensor_mode(oper_mode) return None def read(self): data = self._bus.read_word_data(self._addr, self._junc) # Big endian -> little endian data = socket.ntohs(data) # print("RAW = 0x%X" % data) # It's 16-bit 2's complement code temperature = ctypes.c_short(data).value / 16.0 return temperature
class Current(): ''' Grove Current Sensor class ''' def __init__(self, bus_num=1, addr=ADC_DEFAULT_IIC_ADDR): ''' Init iic. Args: bus_num(int): the bus number; addr(int): iic address; ''' self.bus = Bus(bus_num) self.addr = addr def get_nchan_vol_milli_data(self, n, averageValue): ''' Get n chanel data with unit mV. :param int n: the adc pin. :param int averageValue: Average acquisition frequency. Returns: int: voltage value ''' val = 0 for i in range(averageValue): data = self.bus.read_i2c_block_data(self.addr, REG_VOL_START + n, 2) val += data[1] << 8 | data[0] val = val / averageValue return val def get_nchan_current_data(self, n, sensitivity, Vref, averageValue): ''' 2.5A/5A DC/10A cunrrent sensor get n chanel data with unit mA. :param int n: the adc pin. :param float sensitivity: The coefficient by which voltage is converted into current. :param int Vref: Initial voltage at no load. :param int averageValue: Average acquisition frequency. Returns: int: current value ''' val = 0 for i in range(averageValue): data = self.bus.read_i2c_block_data(self.addr, REG_VOL_START + n, 2) val += data[1] << 8 | data[0] val = val / averageValue currentVal = (val - Vref) * sensitivity return currentVal, val def get_nchan_AC_current_data(self, n, sensitivity, Vref, averageValue): ''' 5A current sensor AC output and get n chanel data with unit mA. :param int n: the adc pin. :param float sensitivity: The coefficient by which voltage is converted into current. :param int Vref: Initial voltage at no load. :param int averageValue: Average acquisition frequency. Returns: int: current value ''' sensorValue = 0 for i in range(averageValue): data = self.bus.read_i2c_block_data(self.addr, REG_VOL_START + n, 2) val = data[1] << 8 | data[0] if (val > sensorValue): sensorValue = val time.sleep(0.00004) currentVal = ((sensorValue - Vref) * sensitivity) * 0.707 return currentVal
class gesture: active = 0 #Registers and variables for the gesture sensor #GES_REACTION_TIME =.500 # You can adjust the reaction time according to the actual circumstance. GES_REACTION_TIME = .250 # You can adjust the reaction time according to the actual circumstance. #GES_ENTRY_TIME =.800 # When you want to recognize the Forward/Backward gestures, your gestures' reaction time must less than GES_ENTRY_TIME(0.8s). GES_ENTRY_TIME = .400 # When you want to recognize the Forward/Backward gestures, your gestures' reaction time must less than GES_ENTRY_TIME(0.8s). #GES_QUIT_TIME =1.000 GES_QUIT_TIME = 0.500 BANK0 = 0 BANK1 = 1 bus = None busnum = -1 case = 1 PAJ7620_ADDR_BASE = 0x00 #REGISTER BANK SELECT PAJ7620_REGITER_BANK_SEL = (PAJ7620_ADDR_BASE + 0xEF) #W #DEVICE ID PAJ7620_ID = 0x73 #REGISTER BANK 0 PAJ7620_ADDR_SUSPEND_CMD = (PAJ7620_ADDR_BASE + 0x3) #W PAJ7620_ADDR_GES_PS_DET_MASK_0 = (PAJ7620_ADDR_BASE + 0x41) #RW PAJ7620_ADDR_GES_PS_DET_MASK_1 = (PAJ7620_ADDR_BASE + 0x42) #RW PAJ7620_ADDR_GES_PS_DET_FLAG_0 = (PAJ7620_ADDR_BASE + 0x43) #R PAJ7620_ADDR_GES_PS_DET_FLAG_1 = (PAJ7620_ADDR_BASE + 0x44) #R PAJ7620_ADDR_STATE_INDICATOR = (PAJ7620_ADDR_BASE + 0x45) #R PAJ7620_ADDR_PS_HIGH_THRESHOLD = (PAJ7620_ADDR_BASE + 0x69) #RW PAJ7620_ADDR_PS_LOW_THRESHOLD = (PAJ7620_ADDR_BASE + 0x6A) #RW PAJ7620_ADDR_PS_APPROACH_STATE = (PAJ7620_ADDR_BASE + 0x6B) #R PAJ7620_ADDR_PS_RAW_DATA = (PAJ7620_ADDR_BASE + 0x6C) #R #REGISTER BANK 1 PAJ7620_ADDR_PS_GAIN = (PAJ7620_ADDR_BASE + 0x44) #RW PAJ7620_ADDR_IDLE_S1_STEP_0 = (PAJ7620_ADDR_BASE + 0x67) #RW PAJ7620_ADDR_IDLE_S1_STEP_1 = (PAJ7620_ADDR_BASE + 0x68) #RW PAJ7620_ADDR_IDLE_S2_STEP_0 = (PAJ7620_ADDR_BASE + 0x69) #RW PAJ7620_ADDR_IDLE_S2_STEP_1 = (PAJ7620_ADDR_BASE + 0x6A) #RW PAJ7620_ADDR_OP_TO_S1_STEP_0 = (PAJ7620_ADDR_BASE + 0x6B) #RW PAJ7620_ADDR_OP_TO_S1_STEP_1 = (PAJ7620_ADDR_BASE + 0x6C) #RW PAJ7620_ADDR_OP_TO_S2_STEP_0 = (PAJ7620_ADDR_BASE + 0x6D) #RW PAJ7620_ADDR_OP_TO_S2_STEP_1 = (PAJ7620_ADDR_BASE + 0x6E) #RW PAJ7620_ADDR_OPERATION_ENABLE = (PAJ7620_ADDR_BASE + 0x72) #RW #PAJ7620_REGITER_BANK_SEL PAJ7620_BANK0 = 0 PAJ7620_BANK1 = 1 #PAJ7620_ADDR_SUSPEND_CMD PAJ7620_I2C_WAKEUP = 1 PAJ7620_I2C_SUSPEND = 0 #PAJ7620_ADDR_OPERATION_ENABLE PAJ7620_ENABLE = 1 PAJ7620_DISABLE = 0 #ADC, delete REG_ADDR_RESULT = 0x00 REG_ADDR_ALERT = 0x01 REG_ADDR_CONFIG = 0x02 REG_ADDR_LIMITL = 0x03 REG_ADDR_LIMITH = 0x04 REG_ADDR_HYST = 0x05 REG_ADDR_CONVL = 0x06 REG_ADDR_CONVH = 0x07 GES_RIGHT_FLAG = 1 << 0 GES_LEFT_FLAG = 1 << 1 GES_UP_FLAG = 1 << 2 GES_DOWN_FLAG = 1 << 3 GES_FORWARD_FLAG = 1 << 4 GES_BACKWARD_FLAG = 1 << 5 GES_CLOCKWISE_FLAG = 1 << 6 GES_COUNT_CLOCKWISE_FLAG = 1 << 7 GES_WAVE_FLAG = 1 << 0 #Gesture output FORWARD = 1 BACKWARD = 2 RIGHT = 3 LEFT = 4 UP = 5 DOWN = 6 CLOCKWISE = 7 ANTI_CLOCKWISE = 8 WAVE = 9 #Initial register state initRegisterArray = ([0xEF, 0x00], [0x32, 0x29], [0x33, 0x01], [0x34, 0x00], [0x35, 0x01], [0x36, 0x00], [0x37, 0x07], [0x38, 0x17], [0x39, 0x06], [0x3A, 0x12], [0x3F, 0x00], [0x40, 0x02], [0x41, 0xFF], [0x42, 0x01], [0x46, 0x2D], [0x47, 0x0F], [0x48, 0x3C], [0x49, 0x00], [0x4A, 0x1E], [0x4B, 0x00], [0x4C, 0x20], [0x4D, 0x00], [0x4E, 0x1A], [0x4F, 0x14], [0x50, 0x00], [0x51, 0x10], [0x52, 0x00], [0x5C, 0x02], [0x5D, 0x00], [0x5E, 0x10], [0x5F, 0x3F], [0x60, 0x27], [0x61, 0x28], [0x62, 0x00], [0x63, 0x03], [0x64, 0xF7], [0x65, 0x03], [0x66, 0xD9], [0x67, 0x03], [0x68, 0x01], [0x69, 0xC8], [0x6A, 0x40], [0x6D, 0x04], [0x6E, 0x00], [0x6F, 0x00], [0x70, 0x80], [ 0x71, 0x00 ], [0x72, 0x00], [0x73, 0x00], [0x74, 0xF0], [ 0x75, 0x00 ], [0x80, 0x42], [0x81, 0x44], [0x82, 0x04], [ 0x83, 0x20 ], [0x84, 0x20], [0x85, 0x00], [0x86, 0x10], [0x87, 0x00], [0x88, 0x05], [0x89, 0x18], [0x8A, 0x10], [0x8B, 0x01], [ 0x8C, 0x37 ], [0x8D, 0x00], [0x8E, 0xF0], [0x8F, 0x81], [ 0x90, 0x06 ], [0x91, 0x06], [0x92, 0x1E], [0x93, 0x0D], [ 0x94, 0x0A ], [0x95, 0x0A], [0x96, 0x0C], [0x97, 0x05], [ 0x98, 0x0A ], [0x99, 0x41], [0x9A, 0x14], [0x9B, 0x0A], [ 0x9C, 0x3F ], [0x9D, 0x33], [0x9E, 0xAE], [0x9F, 0xF9], [ 0xA0, 0x48 ], [0xA1, 0x13], [0xA2, 0x10], [0xA3, 0x08], [ 0xA4, 0x30 ], [0xA5, 0x19], [0xA6, 0x10], [0xA7, 0x08], [ 0xA8, 0x24 ], [0xA9, 0x04], [0xAA, 0x1E], [0xAB, 0x1E], [ 0xCC, 0x19 ], [0xCD, 0x0B], [0xCE, 0x13], [0xCF, 0x64], [ 0xD0, 0x21 ], [0xD1, 0x0F], [0xD2, 0x88], [0xE0, 0x01], [ 0xE1, 0x04 ], [0xE2, 0x41], [0xE3, 0xD6], [0xE4, 0x00], [ 0xE5, 0x0C ], [0xE6, 0x0A], [0xE7, 0x00], [0xE8, 0x00], [ 0xE9, 0x00 ], [0xEE, 0x07], [0xEF, 0x01], [0x00, 0x1E], [ 0x01, 0x1E ], [0x02, 0x0F], [0x03, 0x10], [0x04, 0x02], [ 0x05, 0x00 ], [0x06, 0xB0], [0x07, 0x04], [0x08, 0x0D], [ 0x09, 0x0E ], [0x0A, 0x9C], [0x0B, 0x04], [0x0C, 0x05], [ 0x0D, 0x0F ], [0x0E, 0x02], [0x0F, 0x12], [0x10, 0x02], [ 0x11, 0x02 ], [0x12, 0x00], [0x13, 0x01], [0x14, 0x05], [ 0x15, 0x07 ], [0x16, 0x05], [0x17, 0x07], [0x18, 0x01], [ 0x19, 0x04 ], [0x1A, 0x05], [0x1B, 0x0C], [0x1C, 0x2A], [ 0x1D, 0x01 ], [0x1E, 0x00], [0x21, 0x00], [0x22, 0x00], [ 0x23, 0x00 ], [0x25, 0x01], [0x26, 0x00], [0x27, 0x39], [ 0x28, 0x7F ], [0x29, 0x08], [0x30, 0x03], [0x31, 0x00], [ 0x32, 0x1A ], [0x33, 0x1A], [0x34, 0x07], [0x35, 0x07], [ 0x36, 0x01 ], [0x37, 0xFF], [0x38, 0x36], [0x39, 0x07], [ 0x3A, 0x00 ], [0x3E, 0xFF], [0x3F, 0x00], [0x40, 0x77], [ 0x41, 0x40 ], [0x42, 0x00], [0x43, 0x30], [0x44, 0xA0], [ 0x45, 0x5C ], [0x46, 0x00], [0x47, 0x00], [0x48, 0x58], [ 0x4A, 0x1E ], [0x4B, 0x1E], [0x4C, 0x00], [0x4D, 0x00], [ 0x4E, 0xA0 ], [0x4F, 0x80], [0x50, 0x00], [0x51, 0x00], [ 0x52, 0x00 ], [0x53, 0x00], [0x54, 0x00], [0x57, 0x80], [ 0x59, 0x10 ], [0x5A, 0x08], [0x5B, 0x94], [0x5C, 0xE8], [ 0x5D, 0x08 ], [0x5E, 0x3D], [0x5F, 0x99], [0x60, 0x45], [ 0x61, 0x40 ], [0x63, 0x2D], [0x64, 0x02], [0x65, 0x96], [ 0x66, 0x00 ], [0x67, 0x97], [0x68, 0x01], [0x69, 0xCD], [ 0x6A, 0x01 ], [0x6B, 0xB0], [0x6C, 0x04], [0x6D, 0x2C], [ 0x6E, 0x01 ], [0x6F, 0x32], [0x71, 0x00], [0x72, 0x01], [0x73, 0x35], [0x74, 0x00], [0x75, 0x33], [0x76, 0x31], [0x77, 0x01], [0x7C, 0x84], [0x7D, 0x03], [0x7E, 0x01]) #Enable debug message debug = 0 #Initialize the sensors def init(self, busno, caseflag): self.busnum = busno self.bus = Bus(busno) self.case = caseflag time.sleep(.001) self.paj7620SelectBank(self.BANK0) self.paj7620SelectBank(self.BANK0) data0 = self.paj7620ReadReg(0, 1)[0] data1 = self.paj7620ReadReg(1, 1)[0] if self.debug: print("data0:", data0, "data1:", data1) if data0 != 0x20: #or data1 <> 0x76: if self.debug: print("Error with sensor") #return 0xff if data0 == 0x20: if self.debug: print("wake-up finish.") for i in range(len(self.initRegisterArray)): self.paj7620WriteReg(self.initRegisterArray[i][0], self.initRegisterArray[i][1]) self.paj7620SelectBank(self.BANK0) self.active = 1 print("Paj7620 initialize register finished.") def paj7620Suspend(self): self.bus.write_word_data(self.PAJ7620_ID, 0x03, 0x01) self.bus.write_word_data(self.PAJ7620_ID, 0xEE, 0x01) #Write a byte to a register on the Gesture sensor def paj7620WriteReg(self, addr, cmd): self.bus.write_word_data(self.PAJ7620_ID, addr, cmd) #Select a register bank on the Gesture Sensor def paj7620SelectBank(self, bank): if bank == self.BANK0: self.paj7620WriteReg(self.PAJ7620_REGITER_BANK_SEL, self.PAJ7620_BANK0) #Read a block of bytes of length "qty" starting at address "addr" from the Gesture sensor def paj7620ReadReg(self, addr, qty): return self.bus.read_i2c_block_data(self.PAJ7620_ID, addr, qty) #Print the values from the gesture sensor def print_gesture(self): #data=self.paj7620ReadReg(0x43,1)[0] #data_wave=self.paj7620ReadReg(0x44, 1)[0] #if (data_wave == self.GES_WAVE_FLAG): # return "W" if self.case else "w" data = self.paj7620ReadReg(0x43, 1)[0] if data == self.GES_RIGHT_FLAG: time.sleep(self.GES_ENTRY_TIME) data = self.paj7620ReadReg(0x43, 1)[0] if data == self.GES_FORWARD_FLAG: return "F" if self.case else "f" time.sleep(self.GES_QUIT_TIME) elif data == self.GES_BACKWARD_FLAG: time.sleep(self.GES_QUIT_TIME) else: return "U" if self.case else "u" elif data == self.GES_LEFT_FLAG: time.sleep(self.GES_ENTRY_TIME) data = self.paj7620ReadReg(0x43, 1)[0] if data == self.GES_FORWARD_FLAG: return "F" if self.case else "f" time.sleep(self.GES_QUIT_TIME) elif data == self.GES_BACKWARD_FLAG: print(ba) time.sleep(self.GES_QUIT_TIME) else: return "D" if self.case else "d" elif data == self.GES_UP_FLAG: time.sleep(self.GES_ENTRY_TIME) data = self.paj7620ReadReg(0x43, 1)[0] if data == self.GES_FORWARD_FLAG: return "F" if self.case else "f" time.sleep(self.GES_QUIT_TIME) elif data == self.GES_BACKWARD_FLAG: return "B" if self.case else "b" time.sleep(self.GES_QUIT_TIME) else: return "L" if self.case else "l" elif data == self.GES_DOWN_FLAG: time.sleep(self.GES_ENTRY_TIME) data = self.paj7620ReadReg(0x43, 1)[0] if data == self.GES_FORWARD_FLAG: time.sleep(self.GES_QUIT_TIME) return "F" if self.case else "f" elif data == self.GES_BACKWARD_FLAG: return "B" if self.case else "b" time.sleep(self.GES_QUIT_TIME) else: return "R" if self.case else "r" elif data == self.GES_FORWARD_FLAG: return "F" if self.case else "f" time.sleep(self.GES_QUIT_TIME) elif data == self.GES_BACKWARD_FLAG: return "B" if self.case else "b" time.sleep(self.GES_QUIT_TIME) elif data == self.GES_CLOCKWISE_FLAG: return "C" if self.case else "c" elif data == self.GES_COUNT_CLOCKWISE_FLAG: return "A" if self.case else "a" #else: # data1=self.paj7620ReadReg(0x44, 1)[0] # if (data1 == self.GES_WAVE_FLAG): # return "W" if self.case else "w" def _gesture(self): data = self.paj7620ReadReg(0x43, 1)[0] if data == 1: return "U" if self.case else "u" elif data == 2: return "D" if self.case else "d" elif data == 16: return "F" if self.case else "f" elif data == 4: return "L" if self.case else "l" elif data == 32: return "B" if self.case else "b" elif data == 128: return "A" if self.case else "a" elif data == 64: return "C" if self.case else "c" elif data == 8: return "R" if self.case else "r"
class bme280: """ Grove bme280 sensor control library. Objects: - set_mode(mode, t_sb) - set_oversampling(osrs_h, osrs_t, osrs_p) - set_filter(filter_coefficient) - set_spi(spi3w_en) - write_reset() - read_id() - read_status() - read_compensated_signals() - read_raw_signals() - set_pressure_calibration(level, pressure) - get_altitude(pressure) """ # Constant Definitions # Modes MODE_SLEEP = 0b00 MODE_FORCE = 0b01 MODE_NORMAL = 0b11 # Normal mode standby values t_sb_0_5 = 0b000 t_sb_62_5 = 0b001 t_sb_125 = 0b010 t_sb_250 = 0b011 t_sb_500 = 0b100 t_sb_1000 = 0b101 t_sb_10 = 0b110 t_sb_20 = 0b111 # IIR filter coefficient filter_0 = 0b000 filter_2 = 0b001 filter_4 = 0b010 filter_8 = 0b011 filter_16 = 0b100 # SPI control SPI_ON = 0b01 SPI_OFF = 0b00 # Oversampling modes OVRS_x0 = 0b000 OVRS_x1 = 0b001 OVRS_x2 = 0b010 OVRS_x4 = 0b011 OVRS_x8 = 0b100 OVRS_x16 = 0b101 def __init__(self): # Rev 2 Pi, Pi 2 & Pi 3 uses bus 1, Rev 1 Pi uses bus 0 # bme280 default I2C Address is 0x76 self.bus = Bus() self.address = 0x76 self.mode = self.MODE_SLEEP self.t_sb = self.t_sb_1000 self.last_meas = 0 # Calibration data # Calibration data registers are 0x88-0xA1(25 bytes) and 0xE1-0xE7(7 bytes) total 32 bytes self.calib = [0x00] * 32 # Init raw data array and variables self.raw_data = [0x00] * 8 self.raw_temperature = 0x00000 self.raw_pressure = 0x00000 self.raw_humidity = 0x00000 # Init parameters self.osrs_h = self.OVRS_x0 self.osrs_t = self.OVRS_x0 self.osrs_p = self.OVRS_x0 # IIR filter and SPI interface are off by default self.filter = self.filter_0 self.spi3w_en = self.SPI_OFF # Status word. Only has two significant bits bit0 = im_update and bit3 = measuring self.status = 0x00 self.im_update = False self.measuring = False # Compensation values # Temperature trimming values self.dig_T1 = 0x0000 self.dig_T2 = 0x0000 self.dig_T3 = 0x0000 # Pressure trimming params self.dig_P1 = 0x0000 self.dig_P2 = 0x0000 self.dig_P3 = 0x0000 self.dig_P4 = 0x0000 self.dig_P5 = 0x0000 self.dig_P6 = 0x0000 self.dig_P7 = 0x0000 self.dig_P8 = 0x0000 self.dig_P9 = 0x0000 # Humidity trimming params self.dig_H1 = 0x00 self.dig_H2 = 0x0000 self.dig_H3 = 0x00 self.dig_H4 = 0x0000 self.dig_H5 = 0x0000 self.dig_H6 = 0x00 # Get the trimming values self.__read_calib() # Variables for compensated measurements self.temperature = 0x00000 self.pressure = 0x00000 self.humidity = 0x00000 self.calibrated_temperature = 0x00000 self.calibrated_pressure = 0x00000 self.calibrated_humidity = 0x00000 # Variables for measurement calibration self.calibration_temperature = 0 self.calibration_pressure = 0 self.calibration_humidity = 0 ######################################### # set bme280 operating mode # ######################################### def set_mode(self, mode=MODE_SLEEP, t_sb=t_sb_1000): # Writes ctrl_meas register with current temperature and pressure oversampling settings # Only changes the mode # If normal mode selected also sets the standby time in config register # Set class variables self.mode = mode self.t_sb = t_sb # If no measurements are enabled there is no point going into measurement if self.osrs_t + self.osrs_p + self.osrs_h == 0: print( "No measurement enabled!\nSee set_oversampling()-function to enable measurement." ) return 0 try: # If normal mode set also t_sb(standby time) if self.mode == self.MODE_NORMAL: # Write normal mode standby time t_sb to config register self.__config(t_sb, self.filter, self.spi3w_en) # Write mode to ctr_meas register self.__ctrl_meas(self.osrs_t, self.osrs_p, self.mode) # Otherwise just change the mode in ctrl_meas register else: self.__ctrl_meas(self.osrs_t, self.osrs_p, self.mode) self.last_meas = clock_gettime(CLOCK_REALTIME) # Everything went well return 1 return 1 except Exception as e: # e = sys.exc_info()[0] print("<p>Error: %s</p>" % e) return 0 ######################################################################### # Set oversampling/enable measurement. OVRS_x0 disables the measurement # ######################################################################### def set_oversampling(self, osrs_h=OVRS_x0, osrs_t=OVRS_x0, osrs_p=OVRS_x0): # Set oversampling variables self.osrs_h = osrs_h self.osrs_t = osrs_t self.osrs_p = osrs_p try: # Set humidity oversampling self.__ctrl_hum(self.osrs_h) # Set temperature and pressure oversampling self.__ctrl_meas(self.osrs_t, self.osrs_p, self.mode) except Exception as e: # e = sys.exc_info()[0] print("<p>Error: %s</p>" % e) return 0 # Everything went well return 1 return 1 ######################################### # Set internal IIR filter # ######################################### def set_filter(self, filter_coefficient=filter_0): self.filter = filter_coefficient try: # Write config register with new filter setting self.__config(self.t_sb, self.filter, self.spi3w_en) return 1 except Exception as e: # print("Error in set_filter()") print("<p>Error: %s</p>" % e) return 0 ######################################### # Set internal SPI interface # ######################################### def set_spi(self, spi3w_en=SPI_OFF): self.spi3w_en = spi3w_en try: # Write config register with new spi setting self.__config(self.t_sb, self.filter, self.spi3w_en) return 1 except Exception as e: # print("Error in set_filter()") print("<p>Error: %s</p>" % e) return 0 ######################################### # Reset command # ######################################### def write_reset(self): register = 0xE0 data = 0xB6 # Reset command to register, other values than 0xB6 has no effect r_len = 0 delay = 10 command = ([register, data], r_len, delay) try: self.read_write(command) return 1 except Exception as e: # print("Error in set_filter()") print("<p>Error: %s</p>" % e) return 0 ######################################### # read ID register # ######################################### def read_id(self): register = 0xD0 data = 0x00 r_len = 1 delay = 10 command = ([register, data], r_len, delay) try: return hex(self.read_write(command)[0]) except Exception as e: # print("Error in set_filter()") print("<p>Error: %s</p>" % e) return 0 ######################################### # read STATUS register # ######################################### def read_status(self): register = 0xF3 data = 0x00 r_len = 1 delay = 10 command = ([register, data], r_len, delay) try: self.status = self.read_write(command)[0] self.measuring = (self.status >> 3) & 0b1 self.im_update = self.status & 0b1 return [self.status, self.measuring, self.im_update] except Exception as e: # print("Error in set_filter()") print("<p>Error: %s</p>" % e) return 0 ######################################### # read calibration registers # ######################################### def __read_calib(self): # Calibration data registers are 0x88-0xA1(25 bytes) and 0xE1-0xE7(7 bytes) total 32 bytes # command format ([Register, Data Bytes], Number of bytes to read, Additional sleep(ms)) # If Number of bytes to read > 0 then read_write function reads from I2C Bus # Otherwise Write operation is performed. register1 = 0x88 register2 = 0xE1 data = 0x00 r_len1 = 26 r_len2 = 7 delay = 10 command1 = ([register1, data], r_len1, delay) command2 = ([register2, data], r_len2, delay) try: self.calib[0:26] = self.read_write(command1) self.calib[26:32] = self.read_write(command2) except Exception as e: # print("Error in set_filter()") print("<p>Error: %s</p>" % e) return 0 # Assign fetched data to trim parameters # Temperature trimming params # unsigned are ok, signed must be calculated with twos complement bytes_short = 16 bytes_char = 8 self.dig_T1 = (self.calib[1] << 8) + (self.calib[0] & 0xffff) self.dig_T2 = self.__twos_complement( ((self.calib[3] << 8) + self.calib[2]), bytes_short) self.dig_T3 = self.__twos_complement( (self.calib[5] << 8) + self.calib[4], bytes_short) # Pressure trimming params self.dig_P1 = ((self.calib[7] << 8) + self.calib[6]) & 0xffff self.dig_P2 = self.__twos_complement( (self.calib[9] << 8) + self.calib[8], bytes_short) self.dig_P3 = self.__twos_complement( (self.calib[11] << 8) + self.calib[10], bytes_short) self.dig_P4 = self.__twos_complement( (self.calib[13] << 8) + self.calib[12], bytes_short) self.dig_P5 = self.__twos_complement( (self.calib[15] << 8) + self.calib[14], bytes_short) self.dig_P6 = self.__twos_complement( (self.calib[17] << 8) + self.calib[16], bytes_short) self.dig_P7 = self.__twos_complement( (self.calib[19] << 8) + self.calib[18], bytes_short) self.dig_P8 = self.__twos_complement( (self.calib[21] << 8) + self.calib[20], bytes_short) self.dig_P9 = self.__twos_complement( (self.calib[23] << 8) + self.calib[22], bytes_short) # Humidity trimming params self.dig_H1 = self.calib[25] & 0xff self.dig_H2 = self.__twos_complement( (self.calib[27] << 8) + self.calib[26], bytes_short) self.dig_H3 = self.calib[28] & 0xff self.dig_H4 = self.__twos_complement( (self.calib[29] << 4) + (self.calib[30] & 0x0f), bytes_short) self.dig_H5 = self.__twos_complement( (self.calib[31] << 4) + ((self.calib[30] & 0xf0) >> 4), bytes_short) self.dig_H6 = self.__twos_complement(self.calib[32], bytes_char) # Everything went well return 1 return 1 ######################################### # read raw signals registers # ######################################### def read_raw_signals(self): # RAW Signals memory area is 0xF7-0xFE so there is 8 bytes # command format ([Register, Data Bytes], Number of bytes to read, Additional sleep(ms)) # If Number of bytes to read > 0 then read_write function reads from I2C Bus # Otherwise Write operation is performed. register = 0xF7 data = 0x00 r_len = 8 delay = 10 command = ([register, data], r_len, delay) try: self.raw_data = self.read_write(command) self.raw_pressure = (( (self.raw_data[0] << 8) + self.raw_data[1]) << 4) + ( (self.raw_data[2] >> 4) & 0x0f) self.raw_temperature = ((( (self.raw_data[3] << 8) + self.raw_data[4]) << 4) + ((self.raw_data[5] >> 4) & 0x0f)) self.raw_humidity = ((self.raw_data[6] << 8) + self.raw_data[7]) except Exception as e: # print("Error in set_filter()") print("<p>Error: %s</p>" % e) return 0 # Everything went well return 1 return 1 ######################################### # read compensated signals # ######################################### def read_compensated_signals(self): # Assuming that raw signals are already read # Compensation is performed like in datasheet appendix 8 # 8.1 Compensation formulas in double precision floating point try: # Get Temperature t_fine value t_fine = self.__comp_temperature() self.temperature = t_fine / 5120.0 # Output value of “51.23” equals 51.23 DegC self.calibrated_temperature = ( self.temperature + (0 if self.calibration_temperature is 0 else self.calibration_temperature)) # Get pressure self.pressure = self.__comp_pressure(t_fine) / 100.0 self.calibrated_pressure = (self.pressure + (0 if self.calibration_pressure is 0 else self.calibration_pressure)) # Get Humidity self.humidity = self.__comp_humidity(t_fine) self.calibrated_humidity = (self.humidity + (0 if self.calibration_humidity is 0 else self.calibration_humidity)) return 1 except Exception as e: # print("Error in set_filter()") print("<p>Error: %s</p>" % e) return 0 ######################################### # Temperature compensation formulas # # returns t_fine, because it is used in # # other compensation formulas # ######################################### def __comp_temperature(self): var1 = ((self.raw_temperature / 16384.0) - (self.dig_T1 / 1024.0)) * self.dig_T2 var2 = ((((self.raw_temperature / 131072.0) - (self.dig_T1 / 8192.0)) * ((self.raw_temperature / 131072.0) - (self.dig_T1 / 8192.0))) * self.dig_T3) # t_fine = var1 + var2 return var1 + var2 ############################################################# # Pressure compensation formulas # # Returns pressure in Pa as double. # # Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa # ############################################################# def __comp_pressure(self, t_fine): var1 = (t_fine / 2.0) - 64000.0 var2 = var1 * var1 * self.dig_P6 / 32768.0 var2 = var2 + var1 * self.dig_P5 * 2.0 var2 = (var2 / 4.0) + (self.dig_P4 * 65536.0) var1 = (self.dig_P3 * var1 * var1 / 524288.0 + self.dig_P2 * var1) / 524288.0 var1 = (1.0 + var1 / 32768.0) * self.dig_P1 if var1 == 0.0: return 0 # avoid exception caused by division by zero p = 1048576.0 - self.raw_pressure p = (p - (var2 / 4096.0)) * 6250.0 / var1 var1 = self.dig_P9 * p * p / 2147483648.0 var2 = p * self.dig_P8 / 32768.0 p = p + (var1 + var2 + self.dig_P7) / 16.0 return p ################################################## # Humidity compensation formulas # # Returns humidity in %rH as as double. # # Output value of “46.332” represents 46.332 %rH # ################################################## def __comp_humidity(self, t_fine): var_h = t_fine - 76800.0 var_h = ((self.raw_humidity - (self.dig_H4 * 64.0 + (self.dig_H5 / 16384.0 * var_h))) * (self.dig_H2 / 65536.0 * (1.0 + self.dig_H6 / 67108864.0 * var_h * (1.0 + self.dig_H3 / 67108864.0 * var_h)))) var_h = var_h * (1.0 - self.dig_H1 * var_h / 524288.0) if var_h > 100.0: var_h = 100.0 elif var_h < 0.0: var_h = 0.0 return var_h ######################################### # write ctrl_hum register # ######################################### def __ctrl_hum(self, osrs_h=OVRS_x0): register = 0xF2 r_len = 0 delay = 10 # Make byte to send # data = ((0x00 << 3) + osrs_h) data = osrs_h command = ([register, data], r_len, delay) self.read_write(command) ######################################### # write ctrl_meas register # ######################################### def __ctrl_meas(self, osrs_t=OVRS_x0, osrs_p=OVRS_x0, mode=MODE_SLEEP): register = 0xF4 r_len = 0 delay = 10 # Make byte to send data = ((((osrs_t << 3) + osrs_p) << 2) + mode) command = ([register, data], r_len, delay) self.read_write(command) ######################################### # write config register # ######################################### def __config(self, t_sb, iir_filter, spi3w_en): register = 0xF5 r_len = 0 delay = 10 # Make byte to send data = ((((t_sb << 3) + iir_filter) << 2) + spi3w_en) command = ([register, data], r_len, delay) self.read_write(command) ############################################################## # set_pressure_calibration # # level = known level from sea # # pressure = current local pressure normalized to sea level # ############################################################## def set_pressure_calibration(self, level, pressure): self.calibration_pressure = (pressure - level / 8) - self.pressure ######################################### # get current altitude # # pressure = current sea level pressure # ######################################### def get_altitude(self, pressure): return (pressure - self.calibrated_pressure) * 8 ########################################### # read and write data to the bme280/(I2C) # ########################################### def read_write(self, command): if command[1] <= 0: # Write to I2C-bus # write_i2c_block_data(address, offset, [data_bytes]) self.bus.write_i2c_block_data(self.address, command[0][0], command[0][1:]) sleep(command[2] / 1000) return 1 else: # Read from I2C-Bus # read_i2c_block_data(address, register, number_of_data_bytes) return self.bus.read_i2c_block_data(self.address, command[0][0], command[1]) ######################################### # Twos complement calculation # ######################################### @staticmethod def __twos_complement(input_value, num_bits): """Calculates a two's complement integer from the given input value's bits.""" mask = 2**(num_bits - 1) return -(input_value & mask) + (input_value & (mask - 1))
class ButtonTypedI2c(Button): ''' I2C Button/Switch Array Class provide event checking ability to derived class, should not use directly by end-user. The checking events include: - Button.EV_SINGLE_CLICK - Button.EV_DOUBLE_CLICK - Button.EV_LONG_PRESS - Button.EV_LEVEL_CHANGED Args: address(int): optional, the I2C address of the connected device. evt_en(bool): optional, default True True: provide event checking ability. False: used in poll environment, manually call :class:`ButtonTypedI2c.read`. ''' def __init__(self, address=0x03, evt_en=True): super(ButtonTypedI2c, self).__init__(0) self.bus = Bus() self._addr = address # Initialise the I2C button device self.dev_id = 0 self._probe_uid() self._version = 0 self.version() self._size = self.size() self._set_mode(True) self.__last_evt = None self.__last_evt = self.read() self.key_names = _grove_5way_tactile_keys if self._size == 6: self.key_names = _grove_6pos_dip_switch_keys self.__thrd_exit = False self.__thrd = None if not evt_en: return if self.__thrd is None or not self.__thrd.is_alive(): self.__thrd = threading.Thread( \ target = ButtonTypedI2c.__thrd_chk_evt, \ args = (self,)) self.__thrd.setDaemon(True) self.__thrd.start() def __del__(self): if not self.__thrd: return self.__thrd_exit = True while self.__thrd.isAlive(): time.sleep(_CYCLE_PERIOD / _CYCLE_UNIT) self.__thrd.join() # Thread to check events def __thrd_chk_evt(self): self.__last_time = time.time() while not self.__thrd_exit: # or self.__state != self.KEY_STATE_IDLE: t = time.time() dt, self.__last_time = t - self.__last_time, t evt = self.read() if not evt[0]: time.sleep(_CYCLE_PERIOD) continue for i in range(0, self.size()): if evt[i + 1] & ~self.EV_RAW_STATUS: pressed = bool(evt[i + 1] & self.EV_RAW_STATUS) self._index = i self._send_event(evt[i + 1], pressed, t) time.sleep(_CYCLE_PERIOD) def _probe_uid(self): ID_LEN = 4 for tr in range(4): v = self.bus.read_i2c_block_data(self._addr, _CMD_GET_DEV_ID, ID_LEN) # print("GET_DEV_ID = {}".format(v)) did = 0 for i in range(ID_LEN): did = (did >> 8) | (int(v[i]) << 24) # print("DEV_ID = {:8X}".format(did)) if (did >> 16) == VID_MULTI_SWITCH: self.dev_id = did return self.dev_id self.bus.read_byte(self._addr, True) def version(self): ''' Get the device firmware version. Returns: (int): firmware version, the first version is 1 ''' VER_LEN = 10 if not self.dev_id: return 0 v = self.bus.read_i2c_block_data(self._addr, _CMD_TEST_GET_VER, VER_LEN) # print("GET_VER = {}".format(str(v))) version = v[6] - ord('0') version = version * 10 + (v[8] - ord('0')) # print("version = {}".format(version)) self._version = version return self._version def size(self): ''' Get the button count the device have. Returns: (int): button count ''' if (self.dev_id >> 16) != VID_MULTI_SWITCH: return 0 if (self.dev_id & 0xFFFF) == PID_5_WAY_TACTILE_SWITCH: return 5 if (self.dev_id & 0xFFFF) == PID_6_POS_DIP_SWITCH: return 6 return 0 def name(self, index=None): ''' Get the device name or specified button name Args: index(int): optional, the index number of button to get name. if not specified, return the device name. Returns: (string): the name of the device or pecified button ''' if (self.dev_id >> 16) != VID_MULTI_SWITCH: return "Invalid dev" if not index is None: if index < 0 or index >= self._size: return "Invalid index" return self.key_names[index] if (self.dev_id & 0xFFFF) == PID_5_WAY_TACTILE_SWITCH: return NAME_5_WAY_SWITCH if (self.dev_id & 0xFFFF) == PID_6_POS_DIP_SWITCH: return NAME_6_POS_DIP_SWITCH return "Invalid dev" def _set_mode(self, enable): if not self.dev_id: return None v = _CMD_BLOCK_DET_MODE if enable: v = _CMD_EVENT_DET_MODE self.bus.write_byte(self._addr, v) return True def read(self): ''' Get the button array status Returns: (list): a list has the size button count + 1 item [0] indicate if there is a event (bit 0x80). bit 0x80 set if one or more the switches have event. bit 0x80 clear if no one has event. item [ 1 + `index` ] indicate the event of button specified by index, be bits combination of - Button.EV_LEVEL_CHANGED - Button.EV_SINGLE_CLICK - Button.EV_DOUBLE_CLICK - Button.EV_LONG_PRESS ''' EVT_LEN = 4 if not self.dev_id: return None size = EVT_LEN + self._size v = self.bus.read_i2c_block_data(self._addr, _CMD_GET_DEV_EVENT, size) if self._version > 1 or self.__last_evt is None: return v[EVT_LEN - 1:] # Fix: v0.1 will miss event BTN_EV_LEVEL_CHANGED # if this API called frequently. for i in range(self._size): if (v[EVT_LEN + i] ^ self.__last_evt[1 + i]) & self.EV_RAW_STATUS: v[EVT_LEN + i] |= Button.EV_LEVEL_CHANGED v[EVT_LEN - 1] |= 0x80 self.__last_evt = v[EVT_LEN - 1:] return v[EVT_LEN - 1:] def is_pressed(self, index=0): ''' Get the button status if it's being pressed ? :class:`ButtonTypedI2c.read` must be called before this api call when used with poll method object (created with evt_en = False). Args: index(int): optional, the index number of button to be checked. must be specified for this device. Returns: (bool): True if the button is being pressed. False if not. ''' return not bool(self.__last_evt[index + 1] & self.EV_RAW_STATUS)
class SGP30: def __init__(self): self.bus = Bus() # SGB30 i2c default address is 0x58 self.address = 0x58 self.crc_status = [0, 0] self.CO2eq = 0 self.TVOC = 0 self.CO2eq_raw = 0 self.TVOC_raw = 0 self.CO2eq_baseline = 0 self.TVOC_baseline = 0 ######################################### # Command functions # ######################################### # Init air quality command # A new “Init_air_quality” command has to be sent after every power-up or soft reset. def init_air_quality(self): command = ([0x20, 0x03], 0, 10) try: self.read_write(command) except Exception: # On fail return 0 print("sgp30 Init Fail!") return 0 else: print("sgp30 Init Ok!") # Command pass return 1 return 1 # Measure compensated Co2eq and TVOC values # Has to be sent regular intervals 1s to ensure proper operation of dynamic baseline correction algorithm def measure_air_quality(self): command = ([0x20, 0x08], 6, 12) data = self.read_write(command) if self.crc_status[0] == 0: print("Measurement CRC check failed", self.crc_status) self.CO2eq = 0 self.TVOC = 0 return 0 else: self.CO2eq = bytes_to_int(data[0:2]) self.TVOC = bytes_to_int(data[3:5]) return 1 # Get compensation baseline values # def get_baseline(self): command = ([0x20, 0x15], 6, 10) try: data = self.read_write(command) except Exception: # On fail return 0 print("get_baseline() => read_write() failed.") return 0 if self.crc_status[0] == 0: print("Basevalue read CRC check failed", self.crc_status) return 0 else: self.CO2eq_baseline = bytes_to_int(data[0:2]) self.TVOC_baseline = bytes_to_int(data[3:5]) return 1 # Set compensation baseline values # Sets also variables sgp30(Instance).CO2eq_baseline and sgp30(Instance).TVOC_baseline def set_baseline(self, message): command = ([0x20, 0x1e], 0, 10) formatted_data = [] # generate correct message format [HByte, LByte, CRC, HByte, LByte, CRC, ...] for number in message: tmp_bytes = int_to_bytes(number) crc = calc_crc8(tmp_bytes) formatted_data.extend(tmp_bytes) formatted_data.append(crc) # Extend command data with with message command[0].extend(formatted_data) try: self.read_write(command) except Exception: # On fail return 0 print("set_baseline() => read_write() failed.") return 0 else: self.TVOC_baseline = message[0] self.CO2eq_baseline = message[1] print("Compensation baseline values writen successfully.") return 1 # Set humidity compensation value # def set_humidity(self, message): command = ([0x20, 0x61], 0, 10) formatted_data = [] # generate correct message format [HByte, LByte, CRC, HByte, LByte, CRC, ...] for number in message: tmp_bytes = int_to_bytes(number) crc = calc_crc8(tmp_bytes) formatted_data.extend(tmp_bytes) formatted_data.append(crc) # Extend command data with with message command[0].extend(formatted_data) try: self.read_write(command) except Exception: # On fail return 0 print("set_humidity() => read_write() failed.") return 0 else: print("Humidity compensation value writen successfully.") return 1 # Measure test # The command “Measure_test” which is included for integration and production line testing runs an on-chip # self-test. In case of a successful self-test the sensor returns the fixed data pattern 0xD400 (with correct CRC) def measure_test(self): command = ([0x20, 0x32], 3, 220) data = self.read_write(command) if self.crc_status[0] == 0: print("Measurement CRC check failed", self.crc_status) return 0 else: print("On-chip self-test succesfull!") return bytes_to_int(data[0:2]) def get_feature_set_version(self): command = ([0x20, 0x2f], 3, 2) data = self.read_write(command) print("Product type: ", '{0:08b}'.format(data[0])[0:4]) print("Product version: ", '{0:08b}'.format(data[1]) + ", " + str(data[1])) def measure_raw_signals(self): command = ([0x20, 0x50], 6, 25) data = self.read_write(command) if self.crc_status[0] == 0: print("Measurement CRC check failed", self.crc_status) self.CO2eq_raw = 0 self.TVOC_raw = 0 return 0 else: self.CO2eq_raw = bytes_to_int(data[0:2]) self.TVOC_raw = bytes_to_int(data[3:5]) return 1 # Soft reset command # A sensor reset can be generated using the “General Call” mode according to I2C-bus specification. # It is important to understand that a reset generated in this way is not device specific. # All devices on the same I2C bus that support the General Call mode will perform a reset. def soft_reset(self): command = ([0x00, 0x06], 0, 10) self.read_write(command) # Get serial ID def get_serial_id(self): command = ([0x36, 0x82], 9, 10) data = self.read_write(command) if self.crc_status[0] == 0: print("Measurement CRC check failed", self.crc_status) return 0 else: print("Get serial succesfull!") print("Serial part 1: ", '{0:016b}'.format(bytes_to_int(data[0:2]))) print("Serial part 2: ", '{0:016b}'.format(bytes_to_int(data[3:5]))) print("Serial part 3: ", '{0:016b}'.format(bytes_to_int(data[7:9]))) return 1 ######################################### # read and write data to the sgp30 # ######################################### def read_write(self, command): if command[1] <= 0: # Write to I2C-bus # write_i2c_block_data(address, offset, [data_bytes]) # Note that second offset byte is [data_bytes][0] self.bus.write_i2c_block_data(self.address, command[0][0], command[0][1:]) sleep(command[2]/1000) return 1 else: # Read (Write and read) from I2C-Bus # write_i2c_block_data(address, offset, [data_bytes]) # Note that second offset byte is [data_bytes][0] # read_i2c_block_data(address, offset, number_of_data_bytes) self.bus.write_i2c_block_data(self.address, command[0][0], [command[0][1]]) sleep(command[2]/1000) data = self.bus.read_i2c_block_data(self.address, 0, command[1]) self.crc_status = validate_crc8(data) return data
class Grove12KeyCapTouchMpr121(): def __init__(self,bus_num = 1,addr = TOUCH_SENSOR_DEFAULT_ADDR): self.bus = Bus(bus_num) self.addr = addr self.threshold = 0 self.touch_flag = [0]*CHANNEL_NUM def sensor_init(self): self._set_mode(STOP_MODE) data = [0x23,0x10] self._set_global_param(data) self._set_debounce(0x22) self._set_mode(NORMAL_MODE) def set_threshold(self,threshold): self.threshold = threshold def wait_for_ready(self): time.sleep(.2) def _set_mode(self,mode): self.bus.write_byte_data(self.addr,MODE_CONFIG_REG_ADDR,mode) def _set_global_param(self,data): self.bus.write_i2c_block_data(self.addr,GLOBAL_PARAM_REG_ADDR_L,data) def _set_debounce(self,data): self.bus.write_byte_data(self.addr,SET_DEBOUNCE_REG_ADDR,data) def _check_status_register(self): data_status = self.bus.read_i2c_block_data(self.addr,TOUCH_STATUS_REG_ADDR_L,2) return data_status def get_filtered_touch_data(self,sensor_status): result_value = [] for i in range(CHANNEL_NUM): time.sleep(.01) if(sensor_status & (1<<i)): channel_data = self.bus.read_i2c_block_data(self.addr,FILTERED_DATA_REG_START_ADDR_L+2*i,2) result_value.append(channel_data[0] | channel_data[1]<<8 ) else: result_value.append(0) return result_value def listen_sensor_status(self): data = self._check_status_register() touch_status = data[0] | (data[1]<<8) touch_result_value = self.get_filtered_touch_data(touch_status) for i in range(CHANNEL_NUM): if(touch_result_value[i] < self.threshold ): touch_result_value[i] = 0 return touch_result_value def parse_and_print_result(self,result): for i in range(CHANNEL_NUM): if(result[i] != 0): if(0 == self.touch_flag[i]): self.touch_flag[i] = 1 print("Channel %d is pressed,value is %d" %(i,result[i])) else: if(1 == self.touch_flag[i]): self.touch_flag[i] = 0 print("Channel %d is released,value is %d" %(i,result[i]))
class ButtonTypedI2c(Button): def __init__(self, address=0x03): self.bus = Bus() self.addr = address self.dev_id = 0 self.val = 0 self.probeDevID() self.get_val() self.send_Byte(0x02) app1 = self.status_read() while 1: self.status_read() time.sleep(1.0) continue def set_devID(self, reg, size): self.bus.write_byte_data(self.addr, reg, size) def send_Byte(self, reg): self.bus.write_byte(self.addr, reg) def get_devID(self, data): return self.bus.read_byte(self.addr, data) def get_data(self, reg, len): return self.bus.read_i2c_block_data(self.addr, reg, len) def probeDevID(self): for i in range(4): id = self.get_data(0x00, 4) did = 0 for j in range(4): did = (did >> 8) | (int(id[j]) << 24) #print("DEV_ID = {:8X}".format(did)) if (did >> 16) == 0x2886: self.dev_id = did return self.dev_id self.get_devID(True) def get_val(self): if (self.dev_id & 0xFFFF) == 0x0002: self.val = 5 print("Grove 5_way tactile Switch Insert") self.key_names = grove_5way_tactile_keys return self.val elif (self.dev_id & 0xFFFF) == 0x0003: self.val = 6 print("Grove 6_pos dip Switch Insert") self.key_names = grove_6pos_dip_switch_keys return self.val def status_read(self): app = self.get_data(0x01, 4 + self.val) #print("get event ={}".format(app)) for i in range(0, self.val): print("{} : RAW- ".format(self.key_names[i]), end='') print("{} ".format(app[i + 4] & 1 and "HIGH" or "LOW")) if (self.dev_id & 0xFFFF) == 0x0002: print("{} ".format(app[i + 4] & 1 and "RELEASEND" or "PRESSED")) elif (self.dev_id & 0xFFFF) == 0x0003: print("{} ".format(app[i + 4] & 1 and "OFF" or "ON")) for i in range(0, self.val): if app[i + 4] & ~1: print("{} ".format(self.key_names[i])) print(": EVENT - ") if app[i + 4] & (1 << 1): print("SINGLE-CLICK") if app[i + 4] & (1 << 2): print("DOUBLE-CLICL") if app[i + 4] & (1 << 3): print("LONG-PRESS") if app[i + 4] & (1 << 4): print("LEVEL-CHANGED") print("") return app