class GroveUltrasonicRanger(object): def __init__(self, pin): self.dio = GPIO(pin) def _get_distance(self): self.dio.dir(GPIO.OUT) self.dio.write(0) usleep(2) self.dio.write(1) usleep(10) self.dio.write(0) self.dio.dir(GPIO.IN) t0 = time.time() count = 0 while count < _TIMEOUT1: if self.dio.read(): break count += 1 if count >= _TIMEOUT1: return None t1 = time.time() count = 0 while count < _TIMEOUT2: if not self.dio.read(): break count += 1 if count >= _TIMEOUT2: return None t2 = time.time() dt = int((t1 - t0) * 1000000) if dt > 530: return None distance = ((t2 - t1) * 1000000 / 29 / 2) # cm return distance def get_distance(self): while True: dist = self._get_distance() if dist: return dist def on(self): self.write(1) def off(self): self.write(0)
class Ultrasonic(object): def __init__(self, pin): #Digital Port self.dio = GPIO(pin) self._TIMEOUT1 = 1000 self._TIMEOUT2 = 10000 def usleep(self, x): sleep(x / 1000000.0) def _get_distance(self): self.dio.dir(GPIO.OUT) self.dio.write(0) self.usleep(2) self.dio.write(1) self.usleep(10) self.dio.write(0) self.dio.dir(GPIO.IN) t0 = time() count = 0 while count < self._TIMEOUT1: if self.dio.read(): break count += 1 if count >= self._TIMEOUT1: return None t1 = time() count = 0 while count < self._TIMEOUT2: if not self.dio.read(): break count += 1 if count >= self._TIMEOUT2: return None t2 = time() dt = int((t1 - t0) * 1000000) if dt > 530: return None distance = ((t2 - t1) * 1000000 / 29 / 2) # cm return distance def read(self): while True: dist = self._get_distance() if dist: return dist
class GroveUltrasonicRanger(object): def __init__(self, pin): # Register a single pin for ultrasonic snesor self.dio = GPIO(pin) def _get_distance(self): # OUT mode (trigger) # sends out a short pulse (low-high-low) self.dio.dir(GPIO.OUT) self.dio.write(0) usleep(2) self.dio.write(1) usleep(10) self.dio.write(0) # IN mode (echo) self.dio.dir(GPIO.IN) t0 = time.time() count = 0 while count < _TIMEOUT1: if self.dio.read(): break count += 1 if count >= _TIMEOUT1: return None t1 = time.time() count = 0 while count < _TIMEOUT2: if not self.dio.read(): break count += 1 if count >= _TIMEOUT2: return None t2 = time.time() dt = int((t1 - t0) * 1000000) if dt > 530: return None distance = ((t2 - t1) * 1000000 / 29 / 2) # cm return distance def get_distance(self): while True: dist = self._get_distance() if dist: return dist
class SensorDistancia(object): def __init__(self, pin): self.distancia = GPIO(pin) def _get_distance(self): usleep = lambda x: time.sleep(x / 1000000.0) _TIMEOUT1 = 1000 _TIMEOUT2 = 10000 self.distancia.dir(GPIO.OUT) self.distancia.write(0) usleep(2) self.distancia.write(1) usleep(10) self.distancia.write(0) self.distancia.dir(GPIO.IN) t0 = time.time() count = 0 while count < _TIMEOUT1: if self.distancia.read(): break count += 1 if count >= _TIMEOUT1: return None t1 = time.time() count = 0 while count < _TIMEOUT2: if not self.distancia.read(): break count += 1 if count >= _TIMEOUT2: return None t2 = time.time() dt = int((t1 - t0) * 1000000) if dt > 530: return None distance = ((t2 - t1) * 1000000 / 29 / 2) # cm return distance def get_distance(self): while True: dist = self._get_distance() if dist: return dist
class DHT(object): DHT_TYPE = {'DHT11': '11', 'DHT22': '22', 'DHT10': '10'} DEFAULT_ADDR = 0x38 RESET_REG_ADDR = 0xba MAX_CNT = 320 PULSES_CNT = 41 def __init__(self, dht_type, pin=12, bus_num=1): if dht_type != self.DHT_TYPE['DHT11'] and dht_type != self.DHT_TYPE[ 'DHT22'] and dht_type != self.DHT_TYPE['DHT10']: print('ERROR: Please use 11|22|10 as dht type.') exit(1) self.dht_type = dht_type if dht_type == self.DHT_TYPE['DHT10']: self.bus = Bus(bus_num) self.addr = self.DEFAULT_ADDR self._dht10_init() else: self.pin = GPIO(pin, GPIO.OUT) self._last_temp = 0.0 self._last_humi = 0.0 @property def dht_type(self): return self._dht_type @dht_type.setter def dht_type(self, type): self._dht_type = type ######################## dht10 ############################ def _dht10_start_mess(self): reg_set = [0x33, 0x00] self.bus.write_i2c_block_data(self.addr, 0xac, reg_set) def _dht10_reset(self): self.bus.write_byte(self.addr, self.RESET_REG_ADDR) def _dht10_set_system_cfg(self): reg_set = [0x08, 0x00] self.bus.write_i2c_block_data(self.addr, 0xe1, reg_set) def _dht10_read_status(self): return self.bus.read_byte_data(self.addr, 0) def _dht10_init(self): time.sleep(.5) self._dht10_reset() # delay is needed after reset time.sleep(.3) self._dht10_set_system_cfg() status = self._dht10_read_status() # we must check the calibrate flag, bit[3] : 1 for calibrated ok,0 for Not calibrated. while status & 0x08 != 0x08: print("try calibrated again!n\n") self._dht10_reset() time.sleep(.5) self.bus.dth10_set_system_cfg() status = self._dht10_read_status() time.sleep(.5) ######################################################### def _read(self): if self.dht_type == self.DHT_TYPE['DHT10']: t = 0 h = 0 self._dht10_start_mess() time.sleep(.075) # we must check the device busy flag, bit[7] : 1 for busy ,0 for idle. while (self._dht10_read_status() & 0x80) != 0: time.sleep(.5) print("wait for device not busy") from smbus2 import SMBus, i2c_msg, SMBusWrapper with SMBusWrapper(1) as bus: msg = i2c_msg.read(self.addr, 6) data = bus.i2c_rdwr(msg) data = list(msg) t = (t | data[1]) << 8 t = (t | data[2]) << 8 t = (t | data[3]) >> 4 h = (h | data[3]) << 8 h = (h | data[4]) << 8 h = (h | data[5]) & 0xfffff t = t * 100.0 / 1024 / 1024 h = h * 200.0 / 1024 / 1024 - 50 return t, h # Send Falling signal to trigger sensor output data # Wait for 20ms to collect 42 bytes data else: self.pin.dir(GPIO.OUT) self.pin.write(1) time.sleep(.2) self.pin.write(0) time.sleep(.018) self.pin.dir(GPIO.IN) # a short delay needed for i in range(10): pass # pullup by host 20-40 us count = 0 while self.pin.read(): count += 1 if count > self.MAX_CNT: # print("pullup by host 20-40us failed") return None, "pullup by host 20-40us failed" pulse_cnt = [0] * (2 * self.PULSES_CNT) fix_crc = False for i in range(0, self.PULSES_CNT * 2, 2): while not self.pin.read(): pulse_cnt[i] += 1 if pulse_cnt[i] > self.MAX_CNT: # print("pulldown by DHT timeout %d" % i) return None, "pulldown by DHT timeout %d" % i while self.pin.read(): pulse_cnt[i + 1] += 1 if pulse_cnt[i + 1] > self.MAX_CNT: # print("pullup by DHT timeout %d" % (i + 1)) if i == (self.PULSES_CNT - 1) * 2: # fix_crc = True # break pass return None, "pullup by DHT timeout %d" % i total_cnt = 0 for i in range(2, 2 * self.PULSES_CNT, 2): total_cnt += pulse_cnt[i] # Low level ( 50 us) average counter average_cnt = total_cnt / (self.PULSES_CNT - 1) # print("low level average loop = %d" % average_cnt) data = '' for i in range(3, 2 * self.PULSES_CNT, 2): if pulse_cnt[i] > average_cnt: data += '1' else: data += '0' data0 = int(data[0:8], 2) data1 = int(data[8:16], 2) data2 = int(data[16:24], 2) data3 = int(data[24:32], 2) data4 = int(data[32:40], 2) if fix_crc and data4 != ((data0 + data1 + data2 + data3) & 0xFF): data4 = data4 ^ 0x01 data = data[0:self.PULSES_CNT - 2] + ('1' if data4 & 0x01 else '0') if data4 == ((data0 + data1 + data2 + data3) & 0xFF): if self._dht_type == self.DHT_TYPE['DHT11']: humi = int(data0) temp = int(data2) elif self._dht_type == self.DHT_TYPE['DHT22']: humi = float(int(data[0:16], 2) * 0.1) temp = float( int(data[17:32], 2) * 0.2 * (0.5 - int(data[16], 2))) else: # print("checksum error!") return None, "checksum error!" return humi, temp def read(self, retries=15): for i in range(retries): humi, temp = self._read() if not humi is None: break if humi is None: return self._last_humi, self._last_temp self._last_humi, self._last_temp = humi, temp return humi, temp
class Grove4DigitDisplay(object): colon_index = 1 def __init__(self, clk, dio, brightness=BRIGHT_DEFAULT): self.brightness = brightness self.clk = GPIO(clk, direction=GPIO.OUT) self.dio = GPIO(dio, direction=GPIO.OUT) self.data = [0] * 4 self.show_colon = False def clear(self): self.show_colon = False self.data = [0] * 4 self._show() def show(self, data): if type(data) is str: for i, c in enumerate(data): if c in charmap: self.data[i] = charmap[c] else: self.data[i] = 0 if i == self.colon_index and self.show_colon: self.data[i] |= 0x80 if i == 3: break elif type(data) is int: self.data = [0, 0, 0, charmap['0']] if data < 0: negative = True data = -data else: negative = False index = 3 while data != 0: self.data[index] = charmap[str(data % 10)] index -= 1 if index < 0: break data = int(data / 10) if negative: if index >= 0: self.data[index] = charmap['-'] else: self.data = charmap['_'] + [charmap['9']] * 3 else: raise ValueError('Not support {}'.format(type(data))) self._show() def _show(self): with self: self._transfer(ADDR_AUTO) with self: self._transfer(STARTADDR) for i in range(4): self._transfer(self.data[i]) with self: self._transfer(0x88 + self.brightness) def update(self, index, value): if index < 0 or index > 4: return if value in charmap: self.data[index] = charmap[value] else: self.data[index] = 0 if index == self.colon_index and self.show_colon: self.data[index] |= 0x80 with self: self._transfer(ADDR_FIXED) with self: self._transfer(STARTADDR | index) self._transfer(self.data[index]) with self: self._transfer(0x88 + self.brightness) def set_brightness(self, brightness): if brightness > 7: brightness = 7 self.brightness = brightness self._show() def set_colon(self, enable): self.show_colon = enable if self.show_colon: self.data[self.colon_index] |= 0x80 else: self.data[self.colon_index] &= 0x7F self._show() def _transfer(self, data): for _ in range(8): self.clk.write(0) if data & 0x01: self.dio.write(1) else: self.dio.write(0) data >>= 1 time.sleep(0.000001) self.clk.write(1) time.sleep(0.000001) self.clk.write(0) self.dio.write(1) self.clk.write(1) self.dio.dir(GPIO.IN) while self.dio.read(): time.sleep(0.001) if self.dio.read(): self.dio.dir(GPIO.OUT) self.dio.write(0) self.dio.dir(GPIO.IN) self.dio.dir(GPIO.OUT) def _start(self): self.clk.write(1) self.dio.write(1) self.dio.write(0) self.clk.write(0) def _stop(self): self.clk.write(0) self.dio.write(0) self.clk.write(1) self.dio.write(1) def __enter__(self): self._start() def __exit__(self, exc_type, exc_val, exc_tb): self._stop()
class UltrasonicRanger(object): """ [Digital GPIO] Ultra Soonic Ranger class for: Ultra Sonic Ranger (https://wiki.seeedstudio.com/Grove-Ultrasonic_Ranger/) Args: pin(int): number of digital pin/channel the sensor connected. """ def __init__(self, pin): self.dio =GPIO(pin) def get_distance(self): self.dio.dir(GPIO.OUT) self.dio.write(0) usleep(2) self.dio.write(1) usleep(10) self.dio.write(0) self.dio.dir(GPIO.IN) t0 = time.time() count = 0 while count < _TIMEOUT1: if self.dio.read(): break count += 1 if count >= _TIMEOUT1: return None t1 = time.time() count = 0 while count < _TIMEOUT2: if not self.dio.read(): break count += 1 if count >= _TIMEOUT2: return None t2 = time.time() dt = int((t1 - t0) * 1000000) if dt > 530: return None distance = ((t2 - t1) * 1000000 / 29 / 2) # cm return round(distance, 1) def convert_distance_to_water_level(self): distance = self.get_distance() if distance is None: return -1 absolute_distance_cm = distance - _MIN_WATER_LEVEL_CM distance_percentage = (absolute_distance_cm * 100) / _MAX_WATER_LEVEL_CM water_level_percentage = 100 - distance_percentage return round(water_level_percentage, 1)