I’m new to micro-controller programming and trying to take a temp and humidity reading from a DHT11 connected to my ESP8266 every 2 minutes. My initial attempt was a naive while loop with a sleep in each iteration... this locked the device but did take a reading every 2 minutes as expected. Obviously this is not a good approach, and I sense that I’m missing something fundamental in terms of how to program a continuous process on the ESP8266 with MicroPython. Any help would be greatly appreciated.
2 Answers
There is a Arduino example sketch which implements a solution to an analogous problem: "BlinkWithoutDelay". Although it's C++ as opposed to your python problem, the idea is still the same.
Instead of polling the sensor data and utime.sleep()
-ing until the next read, we can just repeadetly check the current time. If the current time minus the last time we did something exceeds a certain interval time, we do that thing and remember the time that we did. Else, we just continue to do different stuff.
As in a micropython blog post, we can do:
import dht
import machine
import utime
d = dht.DHT11(machine.Pin(4))
# keep track of the last time we did something
last_measurement_ms = 0
# define in what intervals we want to do something
INTERVAL = 5000 # do something every 5000 ms
# main "loop".
while True:
# has enough time elapsed? we need to use ticks_diff here
# as the documentation states.
#(https://docs.micropython.org/en/latest/pyboard/library/utime.html)
if utime.ticks_diff(utime.ticks_ms(), last_measurement_ms) >= INTERVAL:
# yes, do a measurement now.
d.measure()
temp = d.temperature()
print("Temperature is %d." % (temp))
#save the current time.
last_measurement_ms = utime.ticks_ms()
# do the stuff you would do normally.
# this will be spammed, as there is nothing else to do
print("Normal loop")
Note that I don't have an actual ESP8266 with the micropython firmware on it to validate this, but you should get the general idea.

- 5,188
- 3
- 28
- 61
A different approach is to let the machine "deep-sleep" between readings.
Then, if you have the RST pin connected to Pin 16, it can automatically wake (and take the next measurement).
I've been doing this, and my main.py
looks something like:
import wifi
import mqtt
import dht
import time
# This function will wait for the wifi to connect, or timeout
# after 30 seconds.
wifi.connect()
# This import/function inits the sensor, and gets data from it
result = dht.sensor.measure()
# In my case, I'm pushing the data to an MQTT broker - this
# function connects to the broker and sends the relevant data.
mqtt.send(result)
# We need to sleep here, otherwise our push to the broker may not
# complete before we deepsleep below.
time.sleep(5)
# This function will stop all processing, and then try to wake
# after the given number of microseconds. This value should be 2
# minutes.
esp.deepsleep(1000000 * 60 * 2)
Things to note.
- You must have Pin 16 wired to the RST pin.
- I've left out the wifi, dht and mqtt modules - they will vary according to your requirements (such as the credentials, or indeed if you are using something other than MQTT).
- You must have the
time.sleep()
call, else the ESP8266 may sleep before the message is sent. It also gives some time toCtrl-C
when connected by serial port and stop the reboot loop.
Obviously, if you have other things you need to do on the device (other than just wake up, read and send data), then you'll want to do something else.

- 35,041
- 6
- 86
- 121