DHT22 timing issues

Hey guys,

Strangely I can't find an answer to this one.

Quite simply I'm using a DHT22 and the "DHT.h" code as part of a weather station, the sensor works flawlessly however it is coursing my code to "hiccup" every 2 seconds which is coursing chaos with the wind speed (anemometer + interrupt) and serial coms.

There is a "dht.begin();" instruction which doesn't seem to do anything, if I include it or not the sensor still operates.

Is there anyway of maybe just running to code once per minute or better is there less disruptive code available.

As a last resort I will have to have a dedicated Arduino, maybe just a Uno chip + crystal to handle the DHT code and then send the data to the Mega via serial but that is just plain wrong.

Thanks in advance for any help.

PS How do we attach the example code to the forum questions?

You can always use a timer scheme from the BlinkWithoutDelay example to trigger a sample. Be aware that the sensor takes almost a half second to sample and output. For weather data, barometer, temp, and humidity readings can be spaced widely in time, a minute will do. Wind speed, for gust readings, should be faster.

I’ve had problems with several DHT22 sensors, mostly humidity. I changed to the Adafruit SHT31-D breakout and have been getting very good stability. It works quite well on a Nano that uses an RFM69CHW to send data from a remote aircraft to a ground station.

PS
Use the </> button.

Thank you so much for the reply.

I am using that very type of delay, in fact I’m updating the LCD every second.

Wind speed is simply triggering an interrupt that is counted over a 10 second period to give a kind of average. The wind was very accurate until I replaced the analogue humidity and temperature sensors with the DHT22.

If I could trigger the reading once a minute or at a present time I can work the timing out around that. It seems that the DHT.h library works in the background even if its not being used.

I wonder if it might be worthwhile trying to manually read the data from the sensor?

I’m sure others have had this same issue?

I would expect the wind speed interrupt is in conflict with the DHT22 operation. Try separating the events so that the DHT is not queried during the wind speed interval. Have you reduced the wind speed ISR to the bare minimum? Just set a volatile boolean flag meaning that a wind event has occurred which will be handled in loop().

Which pin are you using for the DHT data?

Yes the wind interrupt is very minimal


void interrupt () {

x++;

}


I’m not sure that I have any control over when to query the DHT, the DHT code just seems to do its own thing every 2 seconds,

Even if I run these lines every 10 seconds;

h = dht.readHumidity();

t = dht.readTemperature();

The DHT code still does something every 2 seconds in the background.

Some times the library code is not optimal for every
application. This is especially true for realtime evens.
You may have to stop one even while the other
is active.
Most of the library routines are written as though they
are the only processor activity. It is the job of the programmer
to find the balance. This might include modifying some
library code you got for free.
Dwight

I'm not aware of any DHT operation in the background. You will have to look at the .CPP file and/or watch the data pin with a scope to see if it's sending something when not queried. You could also try a different pin for DHT data. The DHT sensors are not very stable and you might want to consider the SHT31-D which communicates by I2C.

I'm running into a similar master timing problem. I'll try to come up with a sketch that simulates a master clock with multiple event triggers at different intervals. It will use millis() with switch/case and numerous event intervals.

What is your clock frequency?
It must be at least 16 MHz.

Explanation:
Conventional libraries uses digitalRead() function that is too slow with respect to time to measure.
This is a very bad solution that gives too many checksum error

First solution:
Use playground library (Rob Tillaert) that uses a modified version of digitanReadFast().

Second solution:
Read directly micro-controller registry . In this case you must use the Atmel name of I/O. See the micro-controler datasheet.

FYI

  • DigitalRead () ~ 60/80 clock cycles, depending if I/O is PWM capable or not.
  • Method Rob T ~ 30 clock cycles, not possible to make faster because Wiring/Arduino store in Flash with PROGMEN some variables used to convert Atmel_name → Wiring/Arduino_name
  • Reading micro registry = 8 clock cycles, totaly independant of PWM capability.

If you can modify the library avoid the millis () function which is also too slow.
In fact it is not useful to measure the length of 0 and 1. This is not a metrology year.

DHT22 give information “1” or “0” in the form of a pair one “0” plus one “1”.
The “0” time is constant, “1” time may be shorter or longer according to :
0 + 1_short = bit “0”
0 + 1_long = bit “1”.
You have just to test if “1” duration is longer or shorter than “0” duration.
Using variable used to control timeout monitoring is sufficient, Use one for while loop “0” and one for while loop “1”.
After the “1” detection you just have to compare if the one is smaller or larger than the 0 to find if you have information bit “0” or bit “1”.

Attachment : AM2302 (DHT22) datasheet.

AM2302.pdf (570 KB)

Thanks guys but this is getting way too complicated.

I have been using a Honeywell HIH4000-001 Humidity Sensor which has been working well for several months but is now reading massively low for some reason, I can simply read it via one of the analogue inputs. the temperature sensor is a LM35 which I do need to improve on so it can read negative temperatures.

I think realistically this might me the way to go. Life is just too short to pursue the DHT route

Thanks so much for your help it has been very much appreciated you have saved me hours of wasted time.

I would seriously look at the Adafruit SHT31-D Breakout Board. It has a temperature range of -40 to 125 °C and humidity from 0 to 100%. It is very stable and talks by I2C. It needs only two power wires and three data wires and works on either 3V3 or 5V0. It can also assume two different address, 0x44 an 0x45 with a single jumper. The Adafruit library is written just for this board. I'm running one at this moment and will implement two more next week.

Thanks guys but this is getting way too complicated.

You are not obligated to modify the library.
I gave the explanations for you to understand where is the difficulty with an AM2302.

You can use the playground library without having to change anything

It is much higher than that of adafruit for example.

Personal opinion :
If you change components as soon as a difficulty happens in 10 years you will not finish your project.
Aosong AM2302 (DHT22) is a great product.
You just have good library and that I am indicating is working fine.
It's just that, for me, it may be simpler but it works very fine (with a 16MHz xtall)

Nice job on the library. Would like to see the ZIP download feature like other github libraries?

You may be trading one problem for another in regards to the Adafruit SH31-D. It is a I2C bus device, which means that it is meant to be on a short bus. I2C isn't designed for long wires.

Not sure how your machine is built, but your wire lengths may become an issue. Breadboard use doesn't always translate into real world.