adafruit/Adafruit_Python_DHT

Raspberry Pi GPIO17 with DHT22 no longer working

kowenhouston opened this issue · 25 comments

Hi There,

I have a few raspberry pi's wired with DHT22 sensors. It would be very expensive for me to wire them all back up.

This is a working raspberry pi with raspbian:

  • 4.1.20-v7+ #867 SMP Wed Mar 23 20:12:32 GMT 2016 armv7l GNU/Linux
  • Debian 7.11
  • Python 2.7.3
root@localhost:~# python AdafruitDHT.py 22 17
Temp=24.2*  Humidity=29.9%

The non working raspberry pi with rasbian is:

  • 4.9.13-v7+ #974 SMP Wed Mar 1 20:09:48 GMT 2017 armv7l GNU/Linux
  • Debian 7.11
  • Python 2.7.3
root@localhost:~# python AdafruitDHT.py 22 17
Traceback (most recent call last):
  File "AdafruitDHT.py", line 41, in <module>
    humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_DHT/common.py", line 90, in read_retry
    humidity, temperature = read(sensor, pin, platform)
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_DHT/common.py", line 77, in read
    return platform.read(sensor, pin)
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_DHT/Beaglebone_Black.py", line 206, in read
    raise ValueError('Pin must be a valid GPIO identifier like P9_12 or GPIO1_28.')
ValueError: Pin must be a valid GPIO identifier like P9_12 or GPIO1_28.

The only difference between the two Raspberry Pis is that I ran rpi-update on one, which is now not working. The are both wired up identically, have the identical image (however I updated one).

My Wiring looks like this:
GPIO17 / Raspberry Pi Pin 11 - DHT22 Pin 2
+5VDC / Raspberry Pi Pin 2 - DHT22 Pin 1
GND / Raspberry Pi Pin 6 - DHT22 Pin 4

hiya, yep some serious breaking changes in latest raspbian. best suggestion is to go back to the previous version for now!

Hey, The reason for updating was because I wanted to be able to use the Raspberry Pi 2 v1.2, Is there a version that works both on the Raspberry Pi 2 v1.2 and will allow me to use this library on GPIO 17?

I tried dropping back to this version

Commits on Sep 22, 2016
@popcornmix
platform: Enable support for Pi2+
21505f3fb5d8e2a5abbf95baf441a7a6415d4a82

rpi-update 21505f3fb5d8e2a5abbf95baf441a7a6415d4a82

Which still gives me an error, but it's different again.

python AdafruitDHT.py 22 17
Traceback (most recent call last):
  File "AdafruitDHT.py", line 41, in <module>
    humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_DHT/common.py", line 90, in read_retry
    humidity, temperature = read(sensor, pin, platform)
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_DHT/common.py", line 76, in read
    platform = get_platform()
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_DHT/common.py", line 51, in get_platform
    import Raspberry_Pi_2
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_DHT/Raspberry_Pi_2.py", line 22, in <module>
    import Raspberry_Pi_2_Driver as driver
ImportError: No module named Raspberry_Pi_2_Driver

Ok, so I figured out the answer. This should allow the GPIO port 17 to work with the DHT sensor and the image to be used on the Raspberry Pi 2 v1.2

Downgrade the version to 4.4.50-v7+:

Commits on Feb 21, 2017
@popcornmix
kernel: Bump to 4.4.50

sudo rpi-update 52241088c1da59a359110d39c1875cda56496764
sudo reboot

Then when the Pi is back online make sure the build packages are up to date:

sudo apt-get install build-essential python-dev

Uninstall the DHT Package:

sudo pip uninstall Adafruit_Python_DHT

Remove all cached DHT Packages

sudo rm -Rf /usr/local/lib/python2.7/dist-packages/Adafruit_*

And reinstall the DHT Package:

sudo pip install Adafruit_Python_DHT

Result:

root@localhost:~# python AdafruitDHT.py 22 17
Temp=28.1*  Humidity=46.2%
  • 4.4.50-v7+ #970 SMP Mon Feb 20 19:18:29 GMT 2017 armv7l GNU/Linux
  • Debian 7.11
  • Python 2.7.3

hi im using pi 3, I have the similar issue ImportError: No module named Raspberry_Pi_2_Driver, how to solve it?

Hey! I've intensively searched for information and such for these errors and I've come to a conclusion that this library doesn't work correctly in Raspberry Pi 3, right?
I've bough one last week and couldn't make it work with DHT11, however it worked fine with other sensors (and codes).

I tried dowgrading its version as kowenhouston suggested, but I still get Raspberry_PI_2_Driver erro, within or without examples folder.

I found this issue was happening to every GPIO on the latest RPi3 version - got the RPi3 a month ago, and today tried to hook up 4 AM2302 sensors to every GPIO I could - none of them would work. But after following @kowenhouston 's advice, they're all working perfectly. Hopefully these keywords help the next person find this issue on Google!

I have the same issue I believe.

The DHT22.py file reports this error: ...Non-ASCII character '\xa3'... (related to line 86)

line 86 of DHT22.py: temperature = int_t #dht11 0..50*C

How can I resolve this issue? I had a few other errors which were resolved with proper indentation
of the python code (I didn't know python was this strict with it's syntax). I followed a youtube tutorial to try and get the sensor working. I got the DHT22.py code from github, placed it in the same folder as the sensor program and used it as an import in the sensor program. But what I got was errors unlike in the tutorial.

'\xa3' refers to the pound(#) sign.

...I took down all the comments.
Then it reported an error on the first line, that it couldn't find pyb from the import pyb line.
And then I found it !

...I get different code when I open the file from my windows computer than I do when open it from the raspi ?!? It's the same zip file from the same url address ?!?

@Twisis what DHT22.py file are you using? There is no DHT22.py file in this repository so I don't know which repo you got your file from. If you can give me the link to the file's repository I can take a look at the original code. But without seeing that, there's not much to work with since as I said yesterday the error refers to the # symbol but your response then goes on to talk about an error referring pyb or a micropython file that is again not within this repository.

If you can point me in the direction of the files you are using here on github I'd be happy to take a look at them and see if I can be of more help.

This is the address of the file used: http://abyz.me.uk/rpi/pigpio/code/DHT22_py.zip

When I used the link through the Raspberry Pi, opened the zip file and then opened the DHT22.py text file I got the following code:

`import pyb
from pyb import Pin
from pyb import ExtInt

We need to use global properties here as any allocation of a memory (aka declaration of a variable)

during the read cycle causes non-acceptable delay and we are loosing data than

data = None
timer = None
micros = None
dhttype = 0 #0=DHT11 1=DHT21/DHT22

FALL_EDGES = 42 # we have 42 falling edges during data receive

times = list(range(FALL_EDGES))
index = 0

The interrupt handler

def edge(line):
global index
global times
global micros
times[index] = micros.counter()
if index < (FALL_EDGES - 1): # Avoid overflow of the buffer in case of any noise on the line
index += 1

def init(timer_id = 2, data_pin = 'Y2', the_dhttype='DHT22'):
global data
global micros
global timer
global dhttype

if(the_dhttype=='DHT11'):
dhttype = 0
else:
dhttype = 1

# Configure the pid for data communication
data = Pin(data_pin)
# Save the ID of the timer we are going to use
timer = timer_id
# setup the 1uS timer
micros = pyb.Timer(timer, prescaler=83, period=0x3fffffff) # 1MHz ~ 1uS
# Prepare interrupt handler
ExtInt(data, ExtInt.IRQ_FALLING, Pin.PULL_UP, None)
ExtInt(data, ExtInt.IRQ_FALLING, Pin.PULL_UP, edge)

Start signal

def do_measurement():
global data
global micros
global index
# Send the START signal
data.init(Pin.OUT_PP)
data.low()
micros.counter(0)
while micros.counter() < 25000:
pass
data.high()
micros.counter(0)
while micros.counter() < 20:
pass
# Activate reading on the data pin
index = 0
data.init(Pin.IN, Pin.PULL_UP)
# Till 5mS the measurement must be over
pyb.delay(5)

Parse the data read from the sensor

def process_data():
global dhttype
global times
i = 2 # We ignore the first two falling edges as it is a respomse on the start signal
result_i = 0
result = list([0, 0, 0, 0, 0])
while i < FALL_EDGES:
result[result_i] <<= 1
if times[i] - times[i - 1] > 100:
result[result_i] += 1
if (i % 8) == 1:
result_i += 1
i += 1
[int_rh, dec_rh, int_t, dec_t, csum] = result

if dhttype==0:		# dht11		
humidity = int_rh 	
# dht11 20% ~ 90%

temperature = int_t 	
# dht11 0..50°C

# dht21,dht22
else:	
humidity = ((int_rh * 256) + dec_rh)/10 
temperature = (((int_t & 0x7F) * 256) + dec_t)/10
if (int_t & 0x80) > 0:
	temperature *= -1
     
comp_sum = int_rh + dec_rh + int_t + dec_t
if (comp_sum & 0xFF) != csum:
    raise ValueError('Checksum does not match')
return (humidity, temperature)

def measure():
do_measurement()
if index != (FALL_EDGES -1):
raise ValueError('Data transfer failed: %s falling edges only' % str(index))
return process_data()

#using:
#import DHT22
#DHT22.init()
#DHT22.measure()
`

When I opened the same link on my Windows 10 PC, the DHT22.py file contained the following code:

`#!/usr/bin/env python

2014-07-11 DHT22.py

import time
import atexit

import pigpio

class sensor:
"""
A class to read relative humidity and temperature from the
DHT22 sensor. The sensor is also known as the AM2302.

The sensor can be powered from the Pi 3V3 or the Pi 5V rail.

Powering from the 3V3 rail is simpler and safer. You may need
to power from 5V if the sensor is connected via a long cable.

For 3V3 operation connect pin 1 to 3V3 and pin 4 to ground.

Connect pin 2 to a gpio.

For 5V operation connect pin 1 to 5V and pin 4 to ground.

The following pin 2 connection works for me. Use at YOUR OWN RISK.

5V--5K_resistor--+--10K_resistor--Ground
|
DHT22 pin 2 -----+
|
gpio ------------+
"""

def init(self, pi, gpio, LED=None, power=None):
"""
Instantiate with the Pi and gpio to which the DHT22 output
pin is connected.

  Optionally a LED may be specified.  This will be blinked for
  each successful reading.

  Optionally a gpio used to power the sensor may be specified.
  This gpio will be set high to power the sensor.  If the sensor
  locks it will be power cycled to restart the readings.

  Taking readings more often than about once every two seconds will
  eventually cause the DHT22 to hang.  A 3 second interval seems OK.
  """

  self.pi = pi
  self.gpio = gpio
  self.LED = LED
  self.power = power

  if power is not None:
     pi.write(power, 1) # Switch sensor on.
     time.sleep(2)

  self.powered = True

  self.cb = None

  atexit.register(self.cancel)

  self.bad_CS = 0 # Bad checksum count.
  self.bad_SM = 0 # Short message count.
  self.bad_MM = 0 # Missing message count.
  self.bad_SR = 0 # Sensor reset count.

  # Power cycle if timeout > MAX_TIMEOUTS.
  self.no_response = 0
  self.MAX_NO_RESPONSE = 2

  self.rhum = -999
  self.temp = -999

  self.tov = None

  self.high_tick = 0
  self.bit = 40

  pi.set_pull_up_down(gpio, pigpio.PUD_OFF)

  pi.set_watchdog(gpio, 0) # Kill any watchdogs.

  self.cb = pi.callback(gpio, pigpio.EITHER_EDGE, self._cb)

def _cb(self, gpio, level, tick):
"""
Accumulate the 40 data bits. Format into 5 bytes, humidity high,
humidity low, temperature high, temperature low, checksum.
"""
diff = pigpio.tickDiff(self.high_tick, tick)

  if level == 0:

     # Edge length determines if bit is 1 or 0.

     if diff >= 50:
        val = 1
        if diff >= 200: # Bad bit?
           self.CS = 256 # Force bad checksum.
     else:
        val = 0

     if self.bit >= 40: # Message complete.
        self.bit = 40

     elif self.bit >= 32: # In checksum byte.
        self.CS  = (self.CS<<1)  + val

        if self.bit == 39:

           # 40th bit received.

           self.pi.set_watchdog(self.gpio, 0)

           self.no_response = 0

           total = self.hH + self.hL + self.tH + self.tL

           if (total & 255) == self.CS: # Is checksum ok?

              self.rhum = ((self.hH<<8) + self.hL) * 0.1

              if self.tH & 128: # Negative temperature.
                 mult = -0.1
                 self.tH = self.tH & 127
              else:
                 mult = 0.1

              self.temp = ((self.tH<<8) + self.tL) * mult

              self.tov = time.time()

              if self.LED is not None:
                 self.pi.write(self.LED, 0)

           else:

              self.bad_CS += 1

     elif self.bit >=24: # in temp low byte
        self.tL = (self.tL<<1) + val

     elif self.bit >=16: # in temp high byte
        self.tH = (self.tH<<1) + val

     elif self.bit >= 8: # in humidity low byte
        self.hL = (self.hL<<1) + val

     elif self.bit >= 0: # in humidity high byte
        self.hH = (self.hH<<1) + val

     else:               # header bits
        pass

     self.bit += 1

  elif level == 1:
     self.high_tick = tick
     if diff > 250000:
        self.bit = -2
        self.hH = 0
        self.hL = 0
        self.tH = 0
        self.tL = 0
        self.CS = 0

  else: # level == pigpio.TIMEOUT:
     self.pi.set_watchdog(self.gpio, 0)
     if self.bit < 8:       # Too few data bits received.
        self.bad_MM += 1    # Bump missing message count.
        self.no_response += 1
        if self.no_response > self.MAX_NO_RESPONSE:
           self.no_response = 0
           self.bad_SR += 1 # Bump sensor reset count.
           if self.power is not None:
              self.powered = False
              self.pi.write(self.power, 0)
              time.sleep(2)
              self.pi.write(self.power, 1)
              time.sleep(2)
              self.powered = True
     elif self.bit < 39:    # Short message receieved.
        self.bad_SM += 1    # Bump short message count.
        self.no_response = 0

     else:                  # Full message received.
        self.no_response = 0

def temperature(self):
"""Return current temperature."""
return self.temp

def humidity(self):
"""Return current relative humidity."""
return self.rhum

def staleness(self):
"""Return time since measurement made."""
if self.tov is not None:
return time.time() - self.tov
else:
return -999

def bad_checksum(self):
"""Return count of messages received with bad checksums."""
return self.bad_CS

def short_message(self):
"""Return count of short messages."""
return self.bad_SM

def missing_message(self):
"""Return count of missing messages."""
return self.bad_MM

def sensor_resets(self):
"""Return count of power cycles because of sensor hangs."""
return self.bad_SR

def trigger(self):
"""Trigger a new relative humidity and temperature reading."""
if self.powered:
if self.LED is not None:
self.pi.write(self.LED, 1)

     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)

def cancel(self):
"""Cancel the DHT22 sensor."""

  self.pi.set_watchdog(self.gpio, 0)

  if self.cb != None:
     self.cb.cancel()
     self.cb = None

if name == "main":

import time

import pigpio

import DHT22

Intervals of about 2 seconds or less will eventually hang the DHT22.

INTERVAL=3

pi = pigpio.pi()

s = DHT22.sensor(pi, 22, LED=16, power=8)

r = 0

next_reading = time.time()

while True:

  r += 1

  s.trigger()

  time.sleep(0.2)

  print("{} {} {} {:3.2f} {} {} {} {}".format(
     r, s.humidity(), s.temperature(), s.staleness(),
     s.bad_checksum(), s.short_message(), s.missing_message(),
     s.sensor_resets()))

  next_reading += INTERVAL

  time.sleep(next_reading-time.time()) # Overall INTERVAL second polling.

s.cancel()

pi.stop()

`

I don't know why the code looks like that when I add it.

First thing of note, that file is not from github, as you said in your initial post.

Secondly, if you are posting python code you should use the Markdown styling:

    ```python
    <your code here>
    ```

With your code in between it.

Thirdly the first of the two files you copied and pasted the code above are not from that link you shared. Even if you think it's the same file and it is what you see on your Raspberry Pi there's no way it is from the same link. There are references of the dht11 in the first set of code while there is nothing in the second version that you say is the same file opened in Windows. That first set of code once again refers to the Micropython project library and if you are trying to run code from that you should try running it with the Adafruit MicroPython tool.

I'm pretty sure this mix up and blending of code is where you're problem is stemming from. You are somehow mixing multiple files that are not alike and expecting them to run through a regular python build. This would make sense since you received an error about pyb, especially since you probably don't have that library installed or if you do it's not within your regular python lib directory.

I am at Wits end.. HELP. I have tried everything to get a DHT22/AM2302 working on a Pi 3B+ with latest Stretch loaded. I have not downgraded as mentioned above yet and that will be next if someone says it will work on latest Pi. I followed Tony D video and code from https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git.
Even formatted card with fresh OS and reinstalled required code.

2.7 and 3.5 return same results " Failed to get reading. Try Again!"

@jevescio So you are using the code from this repository since the link you shared is to the outdated Adafruit Repo that links to this one?

Also you aren't getting an error like what folks above were getting. The library is working correctly as it was written, you are just not catching a reading which is why it's giving you that result. Can you post the exact code that you are using?

@geofbaum I am not getting same error seems to be beyond the above issues but still not reading sensor. I am just using the example code now to try simple read to see if working.
https://github.com/adafruit/Adafruit_Python_DHT
installed from there also setup.py for both 2.7 and 3.5

i even tried the http://abyz.me.uk/rpi/pigpio/examples.html#Python%20code before i formatted and started over.

@jevescio I can confirm it works on a RaspPi3 with Stretch as I just double checked it with one of mine this morning. It should work with either Python 2 or Python 3 if they are set up properly and the Adafruit_DHT is setup for both properly as well. Open a Python 2.7 or Python 3.4 terminal window and test this code.

import sys
import RPi.GPIO as GPIO
import Adafruit_DHT

RH, T =  Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 23) 
#  23  in the last line of code referring to GPIO 23 which is pin 16 I believe

# Make sure to comment out the print line that does not apply to the version your testing
# for Python 2
print str(RH), str(T)
# for Python 3
print(str(RH), str(T))

Before you say anything yes, I know this isn't any of the examples from this library but it's the code that I've used personally before so I know it works. It will work in a script and it can be used in conjunction if you want with other code to send data to something like ThingSpeak. I can also confirm that this works with both the older version of the AM2301/DHT21, AM2302/DHT22, a breakout board version of the DHT22, and the new version the AM2320.

@Twisis and @jevescio I can only assume that you guys have fixed the problems you had or have given up regarding the issues you faced?

@geofbaum Been out of town and will test your suggestion tonight. I also got new DHT22 just to try in-case the other is bad. Will let you know findings.
Thanks for all your help

@jevescio No worries, just wanted to see how things had progressed if they had. Hopefully when you test it, things will work out better!

I got it working. The issue was I received two different texts of code when using the raspberry pi vs. my pc to download from the same link. Why? I have no clue.

I just transferred the file downloaded from my pc to the pi and DHT22.py worked when imported.

@Twisis Good to hear you got it working.

@geofbaum I got this working with the new sensors. I must have had 2 bad sensors

Again, thanks for all your support

@jevescio Good to hear and you're welcome! Glad to be able to help when I can.