micropython / micropython

MicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems
https://micropython.org
Other
18.71k stars 7.48k forks source link

Unable to read DHT22-sensor on boot #2651

Open jonaslorander opened 7 years ago

jonaslorander commented 7 years ago

Hi,

I was having issues reading a DHT22-sensor in my main.py program. After some ivestigation I noticed that it only appear upon boot of my ESP8266 (NodeMCU hardware). I'm running MicroPython 1.8.6.

So for testing purposes I have this code in main.py:

import dht
import machine
import time

print("Starting DHT22.")
d = dht.DHT22(machine.Pin(4)) #, machine.Pin.IN, machine.Pin.PULL_UP))
while True:
    time.sleep(5)
    print("Measuring.")
    d.measure()
    print("Temperature: %3.1f °C" % d.temperature())
    print("   Humidity: %3.2f %% RH" % d.humidity())

When restarting my ESP the code will run automagically as it is in main.py, this is the output:

▒#5 ets_task(40100164, 3, 3fff8398, 4) Connecting to myapxxxxx Network config: ('192.168.0.179', '255.255.255.0', '192.168.0.1', '192.168.0.1') WebREPL daemon started on ws://192.168.4.1:8266 WebREPL daemon started on ws://192.168.0.179:8266 Started webrepl in normal mode Starting DHT22. Measuring. Traceback (most recent call last): File "main.py", line 10, in File "dht.py", line 13, in measure OSError: [Errno 110] ETIMEDOUT

But if I run the code manually once the ESP has booted with import main I get this (expected) result:

>>> import main Starting DHT22. Measuring. Temperature: 25.6 °C Humidity: 30.70 % RH Measuring. Temperature: 25.6 °C Humidity: 31.20 % RH Measuring. Temperature: 25.6 °C Humidity: 31.20 % RH Measuring. Temperature: 25.6 °C Humidity: 31.10 % RH Measuring. Temperature: 25.6 °C Humidity: 31.10 % RH Measuring. Temperature: 25.6 °C Humidity: 31.00 % RH Traceback (most recent call last): File "", line 1, in File "main.py", line 8, in KeyboardInterrupt: >>>

What is the problem here? Is the boot process not really completed when main.py executes? I've tried having a delay on 1 to 20 seconds before the while True: loop with no success. Isn't it possible to read a DHT-sensor upon boot?

dpgeorge commented 7 years ago

I can't reproduce this error. Using the exact main.py script above works ok for me with both STA and AP interfaces running, as well as WebREPL.

@jonaslorander what is in your boot.py file?

jonaslorander commented 7 years ago

Thats odd. Perhaps there is something wrong with my NodeMCU...? I will try another one this weekend. Or try deleting boot.py first.

This is my boot.py:

# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
import gc
import webrepl

gc.collect()

def do_connect():
    import network
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        confwifi = open('wifis.conf').readlines()
        aps = wlan.scan()

        for cw in confwifi:
            conf_ssid, conf_pass = cw.split(' , ')
            conf_ssid = conf_ssid.strip()
            conf_pass = conf_pass.strip()

            for ap in aps:
                ap_ssid = ap[0].decode("utf-8")

                if ap_ssid == conf_ssid:
                    print('Connecting to %s' % ap_ssid)
                    wlan.connect(conf_ssid, conf_pass) 

                    while not wlan.isconnected():
                        pass

                    break

            if wlan.isconnected():
                break

    if wlan.isconnected():            
        print('Network config:', wlan.ifconfig())
    else:
        print('Unable to find any known networks.')
        wlan.active(False)

do_connect()

webrepl.start()
jonaslorander commented 7 years ago

Removing my boot.py made no difference. But I made another discovery. If I reset my NodeMCU board with the hardware reset button the I get the error above. But if I do a soft reset with machine.reset() it works! MicrpPython executes main.py and it starts showing humidity and temperature values. There is something really strange going on here.

jonaslorander commented 7 years ago

I found a way around the issue. Encapsulating the measure() method in a try except clause seems to solve it. Apparently it is only the first call to measure() that fails.

This is the code I have working:

import dht
import machine
import time

print("Starting DHT22.")
d = dht.DHT22(machine.Pin(4))

while True:
    print("Measuring.")

    retry = 0
    while retry < 3:
        try:
            d.measure()
            break
        except:
            retry = retry + 1
            print(".", end = "")

    print("")

    if retry < 3:
        print("Temperature: %3.1f °C" % d.temperature())
        print("   Humidity: %3.1f %% RH" % d.humidity())

    time.sleep(5)

The output upon a hard reset is this:

Connecting to myapxxxxx
Network config: ('192.168.0.116', '255.255.255.0', '192.168.0.1', '192.168.0.1')
WebREPL daemon started on ws://192.168.4.1:8266
WebREPL daemon started on ws://192.168.0.116:8266
Started webrepl in normal mode
Starting DHT22.
Measuring.
.
Temperature: 25.2 °C
   Humidity: 25.0 % RH
Measuring.

Temperature: 25.2 °C
   Humidity: 25.3 % RH
Measuring.

Temperature: 25.2 °C
   Humidity: 25.1 % RH
Measuring.

Temperature: 25.2 °C
   Humidity: 24.8 % RH
Traceback (most recent call last):
  File "main.py", line 33, in <module>
KeyboardInterrupt: 

MicroPython v1.8.6-7-gefd0927 on 2016-11-10; ESP module with ESP8266
Type "help()" for more information.
>>> 

With this I can get going on my original application.

I don't know if I should leave this open or not. A team member can close the issue if they think it is solved. Since no one else seems to be able to reproduce it, it might be isolated to something at my end...

ghost commented 7 years ago

I was having the same problem. Solution for me was actually quite simple. According to the DHT22 Datasheet it's the sensing period is ~2s. So I figured the sensor might just not be ready to give measurements right after startup. Putting a time.sleep(5) before d.measure() solved it for me.

Just posting this to save someone else from wasting a couple of hours. ;).

jonaslorander commented 7 years ago

This problem occurs even when I have the sensor powered up for a long time and reset the ESP. But, perhaps the pins are toggling or something at startup that might trigger a reading from the DHT... I will be sticking with my workaround for now :)

andreasmarkussen commented 6 years ago

I am having a similar problem! Will try the loop suggestion. Thanks for sharing this! Has anyone tried to make a pull request with this functionality build into the measure procedure?

I am using a Lolin NodeMCU board - V2.

jperaltamalvar commented 5 years ago

I've had the same problem with an ESP32, and even with the workaround I didn't make it. It was working, then it was failing sometimes, and finally errors were too frequent. In my case reviewing the wiring did the trick. I guess there was a bad connection in the data pin.