--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import, division, print_function, unicode_literals
+
+import time
+import pigpio
+
+
+class DHT11(object):
+ """
+ The DHT11 class is a stripped version of the DHT22 sensor code by joan2937.
+ You can find the initial implementation here:
+ - https://github.com/srounet/pigpio/tree/master/EXAMPLES/Python/DHT22_AM2302_SENSOR
+
+ example code:
+ >>> pi = pigpio.pi()
+ >>> sensor = DHT11(pi, 4) # 4 is the data GPIO pin connected to your sensor
+ >>> for response in sensor:
+ .... print("Temperature: {}".format(response['temperature']))
+ .... print("Humidity: {}".format(response['humidity']))
+ """
+
+ def __init__(self, pi, gpio):
+ """
+ pi (pigpio): an instance of pigpio
+ gpio (int): gpio pin number
+ """
+ self.pi = pi
+ self.gpio = gpio
+ self.high_tick = 0
+ self.bit = 40
+ self.temperature = 0
+ self.humidity = 0
+ self.either_edge_cb = None
+ self.setup()
+
+ def setup(self):
+ """
+ Clears the internal gpio pull-up/down resistor.
+ Kills any watchdogs.
+ """
+ self.pi.set_pull_up_down(self.gpio, pigpio.PUD_OFF)
+ self.pi.set_watchdog(self.gpio, 0)
+ self.register_callbacks()
+
+ def register_callbacks(self):
+ """
+ Monitors RISING_EDGE changes using callback.
+ """
+ self.either_edge_cb = self.pi.callback(
+ self.gpio,
+ pigpio.EITHER_EDGE,
+ self.either_edge_callback
+ )
+
+ def either_edge_callback(self, gpio, level, tick):
+ """
+ Either Edge callbacks, called each time the gpio edge changes.
+ Accumulate the 40 data bits from the dht11 sensor.
+ """
+ level_handlers = {
+ pigpio.FALLING_EDGE: self._edge_FALL,
+ pigpio.RISING_EDGE: self._edge_RISE,
+ pigpio.EITHER_EDGE: self._edge_EITHER
+ }
+ handler = level_handlers[level]
+ diff = pigpio.tickDiff(self.high_tick, tick)
+ handler(tick, diff)
+
+ def _edge_RISE(self, tick, diff):
+ """
+ Handle Rise signal.
+ """
+ val = 0
+ if diff >= 50:
+ val = 1
+ if diff >= 200: # Bad bit?
+ self.checksum = 256 # Force bad checksum
+
+ if self.bit >= 40: # Message complete
+ self.bit = 40
+ elif self.bit >= 32: # In checksum byte
+ self.checksum = (self.checksum << 1) + val
+ if self.bit == 39:
+ # 40th bit received
+ self.pi.set_watchdog(self.gpio, 0)
+ total = self.humidity + self.temperature
+ # is checksum ok ?
+ if not (total & 255) == self.checksum:
+ raise
+ elif 16 <= self.bit < 24: # in temperature byte
+ self.temperature = (self.temperature << 1) + val
+ elif 0 <= self.bit < 8: # in humidity byte
+ self.humidity = (self.humidity << 1) + val
+ else: # skip header bits
+ pass
+ self.bit += 1
+
+ def _edge_FALL(self, tick, diff):
+ """
+ Handle Fall signal.
+ """
+ self.high_tick = tick
+ if diff <= 250000:
+ return
+ self.bit = -2
+ self.checksum = 0
+ self.temperature = 0
+ self.humidity = 0
+
+ def _edge_EITHER(self, tick, diff):
+ """
+ Handle Either signal.
+ """
+ self.pi.set_watchdog(self.gpio, 0)
+
+ def read(self):
+ """
+ Start reading over DHT11 sensor.
+ """
+ self.pi.write(self.gpio, pigpio.LOW)
+ time.sleep(0.017) # 17 ms
+ self.pi.set_mode(self.gpio, pigpio.INPUT)
+ self.pi.set_watchdog(self.gpio, 200)
+ time.sleep(0.2)
+
+ def close(self):
+ """
+ Stop reading sensor, remove callbacks.
+ """
+ self.pi.set_watchdog(self.gpio, 0)
+ if self.either_edge_cb:
+ self.either_edge_cb.cancel()
+ self.either_edge_cb = None
+
+ def __iter__(self):
+ """
+ Support the iterator protocol.
+ """
+ return self
+
+ def next(self):
+ """
+ Call the read method and return temperature and humidity informations.
+ """
+ self.read()
+ response = {
+ 'humidity': self.humidity,
+ 'temperature': self.temperature
+ }
+ return response
+
+
+if __name__ == '__main__':
+ pi = pigpio.pi()
+ sensor = DHT11(pi, 4)
+ for d in sensor:
+ print("temperature: {}".format(d['temperature']))
+ print("humidity: {}".format(d['humidity']))
+ time.sleep(1)
+ sensor.close()
+