adafruit / Adafruit_CircuitPython_DHT

CircuitPython support for DHT11 and DHT22 type temperature/humidity devices
MIT License
182 stars 64 forks source link

Reading DHT failing: "Checksum did not validate." #15

Closed larsks closed 4 years ago

larsks commented 5 years ago

I'm running CircuitPython (https://github.com/adafruit/circuitpython/commit/29334511956ab1d4ef04d3dcca72e90b4b932d4a) on a Wemos D1 Mini, using revision da125e7d24f5c1b000a171e10ecc2ec4a9ca518b of the DHT module. When I run this code:

Adafruit CircuitPython 4.0.0-alpha.1-100-gd8c8406f0 on 2018-10-12; ESP module with ESP8266
>>> import board
>>> import dht
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: no module named 'dht'
>>> import adafruit_dht
>>> d = adafruit_dht.DHT22(board.GPIO4)
>>> d.measure()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "adafruit_dht.py", line 178, in measure
RuntimeError: Checksum did not validate. Try again.

If I add a print(pulses) around line 178, I see:

array('H', [67, 71, 64, 76, 53, 79, 55, 79, 55, 79, 55, 79, 55, 79,
56, 78, 59, 26, 63, 22, 63, 71, 63, 22, 59, 30, 56, 25, 63, 71, 63,
25, 65, 22, 58, 27, 62, 22, 63, 22, 64, 21, 59, 26, 63, 22, 63, 22,
63, 26, 63, 23, 64, 20, 59, 26, 63, 22, 63, 22, 59, 27, 62, 22, 67,
22, 63, 22, 59, 26, 63, 22, 63, 22, 59, 26, 63, 23, 62, 22, 54])

This works correctly with upstream micropython v1.9.3 (but fails in v1.9.4 apparently due to https://github.com/micropython/micropython/issues/4233).

ladyada commented 5 years ago

what if you measure a few times? like in a loop, does it ever work?

ladyada commented 5 years ago

(note it may not work because of ESP8266's RTOS, its not great at precision timing stuff)

larsks commented 5 years ago

It seems to fail reliably. I tried it in a loop like this:


import board
import adafruit_dht
import time

d = adafruit_dht.DHT22(board.GPIO4)

def checkdht():
    for i in range(10):
        try:
            d.measure()
            t = d.temperature
            print('got temp:', t)
        except RuntimeError:
            print('Failed')

        time.sleep(3)

It fails every time. It seems to work reliably under micropython 1.9.3. I can try a different dht sensor later this evening just to make sure there isn't something odd going on with the hardware.

larsks commented 5 years ago

I see the same behavior on another board as well.

jerryneedell commented 5 years ago

FWIW - I just tried a DHT22 on an Adafruit Feathere Huzzah ESP8266 with the current CP master build (I also tried it on one from a few weeks ago - same result)


Adafruit CircuitPython 4.0.0-alpha.1-99-g293345119 on 2018-10-13; ESP module with ESP8266
>>> 

>>> 
>>> import board
>>> import adafruit_dht
>>> d = adafruit_dht.DHT22(board.GPIO13)
>>> d.measure()
>>> d.temperature
18.1
>>> d.humidity
72.4
>>> 

Here is a test script I use

from board import GPIO13
import adafruit_dht as dht
import time

sensor=dht.DHT22(GPIO13)
while True:
    print(sensor.temperature,sensor.humidity)
    time.sleep(1)

>>> Adafruit CircuitPython 4.0.0-alpha.1-99-g293345119 on 2018-10-13; ESP module with ESP8266
>>> 
>>> 
>>> import dht22_test
18.1 72.4
18.0 73.0
18.0 72.9
18.0 72.9
18.0 72.9

>>> 

I also tried you r test code (added a call to checkdht)

import board
import adafruit_dht
import time

d = adafruit_dht.DHT22(board.GPIO13)

def checkdht():
    for i in range(10):
        try:
            d.measure()
            t = d.temperature
            print('got temp:', t)
        except RuntimeError:
            print('Failed')
        time.sleep(3)

while True:
    checkdht()
>>> import dht22_issue
got temp: 18.0
got temp: 18.1
got temp: 18.1
got temp: 18.1
got temp: 18.1
got temp: 18.1
got temp: 18.1
got temp: 18.1
got temp: 18.1
got temp: 18.1

>>> 

I am used to seeing occasional bad reading -- failed checksums with the dht22 but it usually works - most of the time - I just catch the erros and continue on. For the tests I ran this morning I had not errors at all.

jerryneedell commented 5 years ago

just to be sure- I re-updated my repo and rebuilt - now have same build as OP -- all still works.

Press any key to enter the REPL. Use CTRL-D to soft reset.

Adafruit CircuitPython 4.0.0-alpha.1-99-g293345119 on 2018-10-13; ESP module with ESP8266
>>> import dht22_test  (my test script)
18.1 72.5
18.2 71.9
18.2 71.8
18.2 71.8
18.2 71.8
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "dht22_test.py", line 8, in <module>
KeyboardInterrupt:
>>> import dht22_issue  ((this is OP test code)
got temp: 18.3
got temp: 18.3
got temp: 18.3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "dht22_issue.py", line 18, in <module>
  File "dht22_issue.py", line 15, in checkdht
KeyboardInterrupt:
>>> 
jerryneedell commented 5 years ago

Where should we go with this - I was not able to reproduce it on an ESP8266 ?

larsks commented 5 years ago

I don't know. I can reproduce it on multiple boards, but they're all the same sort of Wemos D1 mini clone. They work fine both with micropython 1.9.3 and with the esp-open-rtos example code. I'm not sure what it is about recent CircuitPython/MicroPython that changed. Since this isn't impacting the adafruit boards I understand that this isn't going to be a priority.

You can go ahead and close this if you think we've hit a wall in terms of diagnostics. I'll try to poke at it a bit in my spare time. If I ever do figure it out I'll submit a PR.

jerryneedell commented 5 years ago

Have you tried it with MicroPython 1.9.4? That is the release CircuitPython has merged. edited t add: Ah I see above that it does not work with 1.9.4 so that may explain why it does not work with the current CircuitPython.

Still does not identify the root cause but it is consistent.

jerryneedell commented 5 years ago

Also, there have been some probably unrelated updates since that version of the DHT library. It might be worth trying the latest release.

edited to add -- likely irrelevant -- now that I understand that is doesn't to work on MP 1.9.4 it looks like the focus should be on that but it appears to only impact the WEMOS D1 -- no idea why.

jerryneedell commented 5 years ago

@larsks What DHT sensor are you using -- It was not clear from the linked discussions fi you have a pullup resistor on the DHT22 data line. I use a 10K resistor on mine. Are there any other sensors connected to your board - especially I2C since it looks like D4 is also the I2C SDA line.

jerryneedell commented 5 years ago

FYI - I tried a DHT22 on my Feather Huzzah ESP8266 with Micropython 1.9.4 and it works:


MicroPython v1.9.4-679-ge328a5d46 on 2018-10-30; ESP module with ESP8266
Type "help()" for more information.
>>> import machine,dht
>>> d = dht.DHT22(machine.Pin(4))
>>> d.measure()
>>> d.temperature()
19.3
>>> d.humidity()
57.6
>>> 

This does appear to be specific to the WEMOS D1 and I don't have one to experiment with. For this test, I did use Pin 4 as was reported to fail for the WEMOS D1. I do have a 10K pullup on the Data pin.

larsks commented 5 years ago

The plot thickens:

I have a number of boards that the wired version of the DHT22 sensor soldered on. These are the ones experiencing a problem. They don't have an external pullup attached, although in theory the internal pullups on the esp should be sufficient.

I have a few spares of the pin version of the DHT22 sitting around, so I grabbed one of those so I could try with and without an external pullup...and I was unable to reproduce the problem regardless of how I wired it.

I'm going to close this issue for now as having too many unknowns. Frustrating! But at this point I think I don't know enough about what's going on. Maybe some quality time with an oscilloscope would shed some light on the situation.

jerryneedell commented 5 years ago

puzzling -- I just saw that the guide https://learn.adafruit.com/dht/connecting-to-a-dhtxx-sensor now says that both the dht22 and am2302 have internal pullups! I don't know if that was changes since I first started using these or I just missed it ... I tried it on Micropython 1.9.4 as above without the pull-up and it still works.

jerryneedell commented 5 years ago

I just measured the resistance between Vin and Data on the DHT22 and it is 4.7K ohms !! For sanity, I checked a DHT11 and it is Open so a pullup is needed there as the guide says.

larsks commented 5 years ago

This has been fixed upstream in https://github.com/micropython/micropython/pull/4415.

tannewt commented 5 years ago

@larsks Why reopen? That fix is in micropython, not a Python library.

larsks commented 5 years ago

Will, it was a fix to the problem of dht modules not working correctly. If you don't think it's relevant to this issue, close it back up!

kattni commented 4 years ago

Closing.