DHT22.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 # 2014-07-11 DHT22.py
00004 
00005 import time
00006 import atexit
00007 
00008 import pigpio
00009 
00010 class sensor:
00011    """
00012    A class to read relative humidity and temperature from the
00013    DHT22 sensor.  The sensor is also known as the AM2302.
00014 
00015    The sensor can be powered from the Pi 3V3 or the Pi 5V rail.
00016 
00017    Powering from the 3V3 rail is simpler and safer.  You may need
00018    to power from 5V if the sensor is connected via a long cable.
00019 
00020    For 3V3 operation connect pin 1 to 3V3 and pin 4 to ground.
00021 
00022    Connect pin 2 to a gpio.
00023 
00024    For 5V operation connect pin 1 to 5V and pin 4 to ground.
00025 
00026    The following pin 2 connection works for me.  Use at YOUR OWN RISK.
00027 
00028    5V--5K_resistor--+--10K_resistor--Ground
00029                     |
00030    DHT22 pin 2 -----+
00031                     |
00032    gpio ------------+
00033    """
00034 
00035    def __init__(self, pi, gpio, LED=None, power=None):
00036       """
00037       Instantiate with the Pi and gpio to which the DHT22 output
00038       pin is connected.
00039 
00040       Optionally a LED may be specified.  This will be blinked for
00041       each successful reading.
00042 
00043       Optionally a gpio used to power the sensor may be specified.
00044       This gpio will be set high to power the sensor.  If the sensor
00045       locks it will be power cycled to restart the readings.
00046 
00047       Taking readings more often than about once every two seconds will
00048       eventually cause the DHT22 to hang.  A 3 second interval seems OK.
00049       """
00050 
00051       self.pi = pi
00052       self.gpio = gpio
00053       self.LED = LED
00054       self.power = power
00055 
00056       if power is not None:
00057          pi.write(power, 1)  # Switch sensor on.
00058          time.sleep(2)
00059 
00060       self.powered = True
00061 
00062       self.cb = None
00063 
00064       atexit.register(self.cancel)
00065 
00066       self.bad_CS = 0  # Bad checksum count.
00067       self.bad_SM = 0  # Short message count.
00068       self.bad_MM = 0  # Missing message count.
00069       self.bad_SR = 0  # Sensor reset count.
00070 
00071       # Power cycle if timeout > MAX_TIMEOUTS.
00072       self.no_response = 0
00073       self.MAX_NO_RESPONSE = 2
00074 
00075       self.rhum = -999
00076       self.temp = -999
00077 
00078       self.tov = None
00079 
00080       self.high_tick = 0
00081       self.bit = 40
00082 
00083       pi.set_pull_up_down(gpio, pigpio.PUD_OFF)
00084 
00085       pi.set_watchdog(gpio, 0)  # Kill any watchdogs.
00086 
00087       self.cb = pi.callback(gpio, pigpio.EITHER_EDGE, self._cb)
00088 
00089    def _cb(self, gpio, level, tick):
00090       """
00091       Accumulate the 40 data bits.  Format into 5 bytes, humidity high,
00092       humidity low, temperature high, temperature low, checksum.
00093       """
00094       diff = pigpio.tickDiff(self.high_tick, tick)
00095 
00096       if level == 0:
00097 
00098          # Edge length determines if bit is 1 or 0.
00099 
00100          if diff >= 50:
00101             val = 1
00102             if diff >= 200:   # Bad bit?
00103                self.CS = 256  # Force bad checksum.
00104          else:
00105             val = 0
00106 
00107          if self.bit >= 40:  # Message complete.
00108             self.bit = 40
00109 
00110          elif self.bit >= 32:  # In checksum byte.
00111             self.CS  = (self.CS << 1)  + val
00112 
00113             if self.bit == 39:
00114 
00115                # 40th bit received.
00116 
00117                self.pi.set_watchdog(self.gpio, 0)
00118 
00119                self.no_response = 0
00120 
00121                total = self.hH + self.hL + self.tH + self.tL
00122 
00123                if (total & 255) == self.CS:  # Is checksum ok?
00124 
00125                   self.rhum = ((self.hH << 8) + self.hL) * 0.1
00126 
00127                   if self.tH & 128:  # Negative temperature.
00128                      mult = -0.1
00129                      self.tH = self.tH & 127
00130                   else:
00131                      mult = 0.1
00132 
00133                   self.temp = ((self.tH << 8) + self.tL) * mult
00134 
00135                   self.tov = time.time()
00136 
00137                   if self.LED is not None:
00138                      self.pi.write(self.LED, 0)
00139 
00140                else:
00141 
00142                   self.bad_CS += 1
00143 
00144          elif self.bit >= 24:  # in temp low byte
00145             self.tL = (self.tL << 1) + val
00146 
00147          elif self.bit >= 16:  # in temp high byte
00148             self.tH = (self.tH << 1) + val
00149 
00150          elif self.bit >= 8:  # in humidity low byte
00151             self.hL = (self.hL << 1) + val
00152 
00153          elif self.bit >= 0:  # in humidity high byte
00154             self.hH = (self.hH << 1) + val
00155 
00156          else:               # header bits
00157             pass
00158 
00159          self.bit += 1
00160 
00161       elif level == 1:
00162          self.high_tick = tick
00163          if diff > 250000:
00164             self.bit = -2
00165             self.hH = 0
00166             self.hL = 0
00167             self.tH = 0
00168             self.tL = 0
00169             self.CS = 0
00170 
00171       else:  # level == pigpio.TIMEOUT:
00172          self.pi.set_watchdog(self.gpio, 0)
00173          if self.bit < 8:       # Too few data bits received.
00174             self.bad_MM += 1    # Bump missing message count.
00175             self.no_response += 1
00176             if self.no_response > self.MAX_NO_RESPONSE:
00177                self.no_response = 0
00178                self.bad_SR += 1  # Bump sensor reset count.
00179                if self.power is not None:
00180                   self.powered = False
00181                   self.pi.write(self.power, 0)
00182                   time.sleep(2)
00183                   self.pi.write(self.power, 1)
00184                   time.sleep(2)
00185                   self.powered = True
00186          elif self.bit < 39:    # Short message receieved.
00187             self.bad_SM += 1    # Bump short message count.
00188             self.no_response = 0
00189 
00190          else:                  # Full message received.
00191             self.no_response = 0
00192 
00193    def temperature(self):
00194       """Return current temperature."""
00195       return self.temp
00196 
00197    def humidity(self):
00198       """Return current relative humidity."""
00199       return self.rhum
00200 
00201    def staleness(self):
00202       """Return time since measurement made."""
00203       if self.tov is not None:
00204          return time.time() - self.tov
00205       else:
00206          return -999
00207 
00208    def bad_checksum(self):
00209       """Return count of messages received with bad checksums."""
00210       return self.bad_CS
00211 
00212    def short_message(self):
00213       """Return count of short messages."""
00214       return self.bad_SM
00215 
00216    def missing_message(self):
00217       """Return count of missing messages."""
00218       return self.bad_MM
00219 
00220    def sensor_resets(self):
00221       """Return count of power cycles because of sensor hangs."""
00222       return self.bad_SR
00223 
00224    def trigger(self):
00225       """Trigger a new relative humidity and temperature reading."""
00226       if self.powered:
00227          if self.LED is not None:
00228             self.pi.write(self.LED, 1)
00229 
00230          self.pi.write(self.gpio, pigpio.LOW)
00231          time.sleep(0.017)  # 17 ms
00232          self.pi.set_mode(self.gpio, pigpio.INPUT)
00233          self.pi.set_watchdog(self.gpio, 200)
00234 
00235    def cancel(self):
00236       """Cancel the DHT22 sensor."""
00237 
00238       self.pi.set_watchdog(self.gpio, 0)
00239 
00240       if self.cb is not None:
00241          self.cb.cancel()
00242          self.cb = None
00243 
00244 if __name__ == "__main__":
00245 
00246    import time
00247 
00248    import pigpio
00249 
00250    import DHT22
00251 
00252    # Intervals of about 2 seconds or less will eventually hang the DHT22.
00253    INTERVAL = 3
00254 
00255    pi = pigpio.pi()
00256 
00257    s = DHT22.sensor(pi, 22, LED=16, power=8)
00258 
00259    r = 0
00260 
00261    next_reading = time.time()
00262 
00263    while True:
00264 
00265       r += 1
00266 
00267       s.trigger()
00268 
00269       time.sleep(0.2)
00270 
00271       print("{} {} {} {:3.2f} {} {} {} {}".format(
00272          r, s.humidity(), s.temperature(), s.staleness(),
00273          s.bad_checksum(), s.short_message(), s.missing_message(),
00274          s.sensor_resets()))
00275 
00276       next_reading += INTERVAL
00277 
00278       time.sleep(next_reading-time.time())  # Overall INTERVAL second polling.
00279 
00280    s.cancel()
00281 
00282    pi.stop()
00283 


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Thu Jun 6 2019 20:43:57