ESP8266 – DHT11 issue

I have recently run into issues with the DHT11. It turns out that the issue is the time that a call to pinMode takes in the DHT11 library. In a small program pinMode returns as fast as 2.5-5 microseconds. In my large program it can take as long as 37 microseconds!!! This causes the code to overrun the timing at the start of the sequence when telling the DHT11 to start sending data. A call to expectPulse(LOW) finds that the line has already gone high and returns 0 immediately. The mainline code interprets this as a timeout (which also returns 0 from expectPulse()).

My initial response was to edit the code to change some of the timings but it was hard to make it correct for both the small program (fast execution) and large program (slow).

However, I recently discovered that the ESP8266 has fast instruction RAM (IRAM) and slower flash storage. I suspected that the routines are being pushed out of IRAM & consequently slowing down quite badly. So I modified the DHT.CPP to include a directive to ensure that the two timing critical routines (DHT::read and DHT::expectPulse) were both run from IRAM…

CODE: SELECT ALLboolean __attribute__((section(".iram.text"))) DHT::read(bool force) { ...
and
uint32_t __attribute__((section(".iram.text"))) DHT::expectPulse(bool level) {...

So far, no more problems! :)

 

Post-script to my previous post – Whilst the code above does seem to fix the problems with the DHT11, it doesn’t restore the timing of the pinMode function to the fastest that I’ve seen (2.5 microseconds). It takes it down to about 16 microseconds which is fast enough to fix the problem.

I’m not entirely sure why pinMode is so slow, except that I’m using the paho PubSub client and the slow down is definitely connected with subscribing to topics. Whether this pushes some code out of the fast memory, or if there is some interaction going on, I don’t know. But if I remove all but one subscription call – 2.5 microseconds again!!

Odd.

I have been running an ESP8266-01 with a DHT11 for several weeks continuously with no problems, using teh library with the 3rd option DHT dht(DHTPIN, DHTTYPE, 15); but not sure if that made a difference.
Now I am trying to use a DHT11 on a Wemos D1.
Did nt use the 3rd option so just DHT dht(DHTPIN, DHTTYPE);
That worked without problems till I started adding to the program, making it slightly bigger. Then most of my readings failed (someone else in this thread described that too). It is OK in the first reading after start, but then the majority fails. Adding parameter ’15’ did not make a difference. When I run the slightly smaller program again…. works like a charm, bigger one doesnt

JayEmSydney wrote:……

However, I recently discovered that the ESP8266 has fast instruction RAM (IRAM) and slower flash storage. I suspected that the routines are being pushed out of IRAM & consequently slowing down quite badly. So I modified the DHT.CPP to include a directive to ensure that the two timing critical routines (DHT::read and DHT::expectPulse) were both run from IRAM…

CODE: SELECT ALLboolean __attribute__((section(".iram.text"))) DHT::read(bool force) { ...
and
uint32_t __attribute__((section(".iram.text"))) DHT::expectPulse(bool level) {...

So far, no more problems! :)

That helped indeed a lot. Before maybe 1 out of 50 readings would NOT generate a failed to read error, and after your change about 1 out of 20 WOULD generate an error. Still not ideal, but a lot better

– See more at: http://www.esp8266.com/viewtopic.php?f=32&t=4210&p=57237#p57237

ESP8266 – DHT11 issue was last modified: July 13th, 2017 by Jovan Stosic