Arduino Forum

Development => Other Software Development => Topic started by: robtillaart on Apr 14, 2011, 11:21 pm

Title: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Apr 14, 2011, 11:21 pm
update: As the DHTLib is used more and more on ARM processors I added a separate repository for the stable 0.1.13 version of the DHT library on github. URL: https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable

Last week I posted a DHT class on the playground - http://arduino.cc/playground/Main/DHTLib - that supports both DHT11 and DHT22 sensors.

Although the protocol / handshake is the same for both sensors the dataformats used differ unfortunately.  The DHT22 has a wider range and higher resolution. The class is rewritten completely from scratch but inspired by earlier work of George Hadjikyriacou (see also - http://arduino.cc/playground/Main/DHT11Lib ) . The class has two read functions called read11(PIN) and read22(PIN) to read the different sensors. This way one instance of the class can serve multiple, and even mixed sensors. The code of the lib is straightforward and can be stripped if one only has DHT11 or only DHT22's.

As always, comments and remarks are welcome.


update 2013-08-26: support for DHT21


update 2014-06-01: improved timing  -> 0.1.10 version


update 2014-06-26: DHT33/44 support  -> 0.1.13 version

latest version - https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib - 

Note: Attached 0.1.13 version is (for now) latest that is compatible with pre 1.0 Arduino. It is the preferred version. (versions after 0.1.13 are exploring optimizations)
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: graynomad on Apr 15, 2011, 03:33 am
I have no immediate need to use these sensors but can certainly see some in my future so this will be very useful.

I may have to strip it down to the basics for a tiny85 if that's possible (I'll look at the code when the time comes).

Thanks.

______
Rob
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: GaryP on Apr 15, 2011, 10:54 am
Postman just dropped a notification, my order is waiting at the post office., My DHT11 will be tested this weekend.
Finally, I almost forget that it was on its way...

Cheers,
Kari
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: GaryP on Apr 15, 2011, 10:12 pm
OK!

Get the package from post office, and just for curiosity ( http://arduino.cc/forum/index.php/topic,58585.0.html ) I had to check this component.
And it has four pins, no marking for nro 1 or any other.

Datasheet is not helping either, it shows similar component, and I have a problem with reading through all that text, how to identify pin nro 1.
Any tips? Thanks!

Cheers,
Kari

EDIT. Find it! And it works. I'm in a hurry until tomorrow, so I just tested it with the first code found...
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: simkard on Apr 16, 2011, 10:45 am
Hi,

This is the good pinout for DHTxx components (which is strangely not written in the datasheet ...)
(http://imbx.us/HMI6.jpg)


See ya !
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: TerryKing on Apr 21, 2011, 05:10 pm
Rob, Thanks for the great work on this (and other things)  .... Now I can really try mine out !! (I read your code and you do good work.. real return codes!)..

BTW (Disclaimer) I have both types available in my online shop:
http://arduino-direct.com/sunshop/ (http://arduino-direct.com/sunshop/)

I'm looking at sourcing other air environment sensors, and any suggestions would be appreciated...

Adder: Rob, may I use your Playground notes in my Wiki?? I'm trying to help users get many different input and output devices working on Arduino:
http://arduino-info.wikispaces.com/
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Apr 21, 2011, 09:35 pm
Hi Terry,

Thanks for all complements, part of the kudos need to go to Simkard as he is the one who tested my code and gave me needed feedback. As you can see on the playground article there are still a few things needed to be tested - esp negative temperatures for the DHT22 - and I'm considdering to give both temp and humidity the value -500 or so if there is a problem reading the sensor. Now they keep the last value, so if someone doesn't check the return value of the read function (s)he might assume that the reading was OK as there is a valid looking temp/hum.

Good to know you have those sensors in your shop. The URL doesn't work for me (but I'll find them anyway)

It's OK to make a copy of the playground article, but please put a reference in it to the playground (I can do that in the code =>  good idea, thanks, welcome) as I will update only the playground article.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: TerryKing on Apr 21, 2011, 09:49 pm

...
It's OK to make a copy of the playground article, but please put a reference in it to the playground.


OK, I'll only copy the overview for people starting out with this.  The details and examples and updates will be seen through the Playground link.

I'd like to end up with something like this I did for the DS18B20 : http://arduino-info.wikispaces.com/Brick-Temperature-DS18B20 (http://arduino-info.wikispaces.com/Brick-Temperature-DS18B20)

Here's my first pass: http://arduino-info.wikispaces.com/TemperatureHumidity (http://arduino-info.wikispaces.com/TemperatureHumidity)  PLEASE critique / comment!!

Thanks!
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Apr 21, 2011, 10:01 pm
I've updated the article so that the lib will include a reference to the playground.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: TerryKing on Apr 21, 2011, 10:33 pm
Rob, I don't see your combination library here: http://arduino.cc/playground/Main/InterfacingWithHardware#envtop (http://arduino.cc/playground/Main/InterfacingWithHardware#envtop)

...and there's a confusing mix of stuff there. (Can we just say your's is the best ??  8)  )
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Apr 21, 2011, 11:25 pm
Its under Humidity

    * DHT_lib One library that supports both DHT11 and DHT 22   <<<<<<<<<<<<<<<<<< that one

This is the direct URL - http://arduino.cc/playground/Main/DHTLib

Don't know if mine is the best, best is a subjective term at best (oops recursion) and it allways depends on the project context what is the best match.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: cbiale on Aug 09, 2011, 03:07 pm
Ustedes usan la linea de datos conectada directamente a un puerto?. And not use a resistor entre la linea de datos y Vcc.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Aug 09, 2011, 08:33 pm
Quote
Ustedes usan la linea de datos conectada directamente a un puerto?. And not use a resistor entre la linea de datos y Vcc.
You use the data line connected directly to a port?. And not use a resistor between the Vcc and data line.


No I did not use a resistor between the data line and the Vcc. But in my project the lines were very short. If your lines are longer you could try a 4K7 resistor (similar to I2C).

Regards,
Rob
Translation by Google translate


No, no hizo uso de una resistencia entre la línea de datos y la Vcc. Pero en mi proyecto de las líneas eran muy cortos. Si las líneas son más largas que podría tratar de una resistencia de 4K7 (similar a I2C).

Saludos,
robar
Traducción de Google Translate
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: StaticDet5 on Sep 03, 2011, 10:57 pm
I'm trying to build a simple sensor upload to Pachube.  I've been troubleshooting this for awhile, and it seems that the problem is with the DHT22 readings, not with the push to Pachube.
I'm reading the data from the DHT22 correctly:

Quote
+++++++++++++++++++++++++++++++++++++++++++++++++
OK,   47.2,   26.0
sync status code <OK == 200> => 200
data count=> 4
<id>,<value>
0,654
1,712
2,1
3,1

That's my serial output.
The line after the "+"s is the checksum and humidity and temperature read from the DHT22.  The two lines below that are link messages regarding my connection to Pachube.  The final 5 lines deal with the data being sent to Pachube.  The first two pieces (0 and 1) of data are analog reads from a light sensor and a motion sensor connected to analog lines.  The two items following that (2,3) are the temperature and humidity reads from the DHT22.
I can read the DHT22 in the first portion of my code.  I cannot read them in the second portion of my code.  Why?
I've tried various methods of placing the initial DHT22 data into variables, and printing those variables.  Inevitably the serial monitor prints out a "1" when it is trying to send the data feed to Pachube.

Am I wrong?  Am I attacking this the wrong way, and instead should be looking at the Pachube end of things?


Code: [Select]
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
*  Sensors:  DHT22 dataline connected to pin 7.  Suggested 4.7k Pull-up used
             Analog Pin 0 is a photocell to detect light levels
             Analog Pin 1 is a motion sensor

* Based on code:
* Created 22 April 2011
* By Jeffrey Sun
* http://code.google.com/p/pachubelibrary/
* and
* robtillart
* http://arduino.cc/forum/index.php/topic,58531.0.html
* http://arduino.cc/playground/Main/DHTLib

*/
#include <dht.h>
#include "ERxPachube.h"
#include <Ethernet.h>
#include <SPI.h>

dht DHT;
#define DHT22_PIN 7
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x21, 0xE3 };
byte ip[] = { 192, 168, 1, 20   };                  // no DHCP so we set our own IP address

int Temp;
int Humidity;
int OldTemp = Temp;
int OldHumidity = Humidity;

#define PACHUBE_API_KEY "PACHUBE API KEY" // fill in your API key PACHUBE_API_KEY
#define PACHUBE_FEED_ID 34665 // fill in your feed id

ERxPachubeDataOut dataout(PACHUBE_API_KEY, PACHUBE_FEED_ID);

void PrintDataStream(const ERxPachube& pachube);

void setup() {

Serial.begin(9600);
Ethernet.begin(mac, ip);

dataout.addData(0);
dataout.addData(1);
dataout.addData(2);
       dataout.addData(3);
}

void loop() {

Serial.println("+++++++++++++++++++++++++++++++++++++++++++++++++");
float fSensorData = 15.23;
       int chk = DHT.read22(DHT22_PIN);
       switch (chk)
       {
         case 0:  Serial.print("OK,\t"); break;
         case -1: Serial.print("Checksum error,\t"); break;
         case -2: Serial.print("Time out error,\t"); break;
         default: Serial.print("Unknown error,\t"); break;
         }
       // DISPLAY DATA
       Temp = (DHT.temperature, 1);
       Humidity = (DHT.humidity, 1);
       //Serial.print(Temp);
       //Serial.print(",\t");
       //Serial.println(Humidity);
       Serial.print(DHT.humidity, 1);
       Serial.print(",\t");
       Serial.println(DHT.temperature, 1);
dataout.updateData(0, analogRead(0));
dataout.updateData(1, analogRead(1));
dataout.updateData(2, (DHT.temperature,1));
       dataout.updateData(3, (DHT.humidity,1));
int status = dataout.updatePachube();

Serial.print("sync status code <OK == 200> => ");
Serial.println(status);

PrintDataStream(dataout);
       OldTemp = Temp;
       OldHumidity = Humidity;
delay(30000);
}

void PrintDataStream(const ERxPachube& pachube)
{
unsigned int count = pachube.countDatastreams();
Serial.print("data count=> ");
Serial.println(count);

Serial.println("<id>,<value>");
for(unsigned int i = 0; i < count; i++)
{
Serial.print(pachube.getIdByIndex(i));
Serial.print(",");
Serial.print(pachube.getValueByIndex(i));
Serial.println();
}
}
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: StaticDet5 on Sep 03, 2011, 10:59 pm
Possibly related, maybe not:
I'm getting a fair number of checksum errors (Approximately 1 in 10).  Is there a way to reduce that number?  Any suggestions?
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Sep 04, 2011, 01:45 pm

Probably your sample frequency is too high, IIRC the datasheet advices 2000 millis between samples.
Can that be the problem?
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: StaticDet5 on Sep 06, 2011, 03:23 pm
A quick update:
I started playing around a bit more and fixed the problem.   It seems that i needed to drop the comma after the sensor request (dht.temperature) instead of (dht.temperature, 1).  I'm not sure why that matters.   I'm getting serial prints using the previuos codes.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: StaticDet5 on Sep 06, 2011, 04:10 pm
Sorry, missed a comment in between.

I'm pretty sure I'm sampling every thirty seconds.  However, I just realized that my code is getting the data several times in each iteration.  I'd think that this would simply get the old values, but perhaps not.  I've done some code revisions.  I also changed the temperature format to the US standard Fahrenheit, to allow my girlfriend to use the system.

Right now the system is working.  I'm still getting checksum errors at about half the rate.

Code: [Select]
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
*  Sensors:  DHT22 dataline connected to pin 7.  Suggested 4.7k Pull-up used
              Analog Pin 0 is a photocell to detect light levels
              Analog Pin 1 is a motion sensor

* Based on code:
* Created 22 April 2011
* By Jeffrey Sun
* http://code.google.com/p/pachubelibrary/
* and
* robtillart
* http://arduino.cc/forum/index.php/topic,58531.0.html
* http://arduino.cc/playground/Main/DHTLib

*/
#include <dht.h>
#include "ERxPachube.h"
#include <Ethernet.h>
#include <SPI.h>

dht DHT;
#define DHT22_PIN 7
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x21, 0xE3 };
byte ip[] = { 192, 168, 1, 20   };                  // no DHCP so we set our own IP address

float TempC = (DHT.temperature, 1);
float Humidity =(DHT.humidity, 1);
float TempF;
float OldTemp = TempF;
float OldHumidity = Humidity;

#define PACHUBE_API_KEY "Your API Key HERE" // fill in your API key PACHUBE_API_KEY
#define PACHUBE_FEED_ID 34665 // fill in your feed id

ERxPachubeDataOut dataout(PACHUBE_API_KEY, PACHUBE_FEED_ID);

void PrintDataStream(const ERxPachube& pachube);

void setup() {

Serial.begin(9600);
Ethernet.begin(mac, ip);

dataout.addData(0);
dataout.addData(1);
dataout.addData(2);
        dataout.addData(3);
}

void loop() {

Serial.println("+++++++++++++++++++++++++++++++++++++++++++++++++");
float fSensorData = 15.23;
        int chk = DHT.read22(DHT22_PIN);
        switch (chk)
        {
          case 0:  Serial.print("OK,\t"); TempC = (DHT.temperature); Humidity = (DHT.humidity); break;
          case -1: Serial.print("Checksum error,\t"); break;
          case -2: Serial.print("Time out error,\t"); break;
          default: Serial.print("Unknown error,\t"); break;
          }
        // DISPLAY DATA
        //Temp = (DHT.temperature, 1);
        //Humidity = (DHT.humidity, 1);
        //int(Temp);
        //int(Humidity);
        //Serial.print(Temp);
        //Serial.print(",\t");
        //Serial.println(Humidity);
        TempF = float((TempC * float(1.8))+32);
        //Serial.print(DHT.humidity, 1);
        //Serial.print(",\t");
        //Serial.println(TempC);
        //Serial.println(TempF);
       
dataout.updateData(0, analogRead(0));
dataout.updateData(1, analogRead(1));
//dataout.updateData(2, (DHT.temperature,1));
        //dataout.updateData(3, (DHT.humidity,1));
        dataout.updateData(2, TempF);
        dataout.updateData(3, Humidity);
int status = dataout.updatePachube();

Serial.print("sync status code <OK == 200> => ");
Serial.println(status);

PrintDataStream(dataout);
        OldTemp = TempF;
        OldHumidity = Humidity;
delay(30000);
}

void PrintDataStream(const ERxPachube& pachube)
{
unsigned int count = pachube.countDatastreams();
Serial.print("data count=> ");
Serial.println(count);

Serial.println("<id>,<value>");
for(unsigned int i = 0; i < count; i++)
{
Serial.print(pachube.getIdByIndex(i));
Serial.print(",");
Serial.print(pachube.getValueByIndex(i));
Serial.println();
}
}
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Sep 06, 2011, 07:38 pm

The statement "float TempC = (DHT.temperature, 1); "  makes little sense,
You copied it from :   Serial.println(DHT.temperature, 1);    where it means    print the float DHT.temperature with one decimal  You cannot copy that into an assigment,


Here a patched (& stripped) version of your code, not tried as I don't have the pachube lib and sensor nearby to rebuild your sketch.
Let me know how it works...
Code: [Select]

#include <dht.h>
#include "ERxPachube.h"
#include <Ethernet.h>
#include <SPI.h>

dht DHT;
#define DHT22_PIN 7
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x00, 0x21, 0xE3 };
byte ip[] = {
  192, 168, 1, 20   };                  // no DHCP so we set our own IP address

float TempC = 0;
float Humidity = 0;
float TempF = 0;
float OldTemp = 0;
float OldHumidity = 0;

#define PACHUBE_API_KEY "Your API Key HERE" // fill in your API key PACHUBE_API_KEY
#define PACHUBE_FEED_ID 34665 // fill in your feed id

ERxPachubeDataOut dataout(PACHUBE_API_KEY, PACHUBE_FEED_ID);

void PrintDataStream(const ERxPachube& pachube);

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip);

  dataout.addData(0);
  dataout.addData(1);
  dataout.addData(2);
  dataout.addData(3);
}

void loop() {

  Serial.println("+++++++++++++++++++++++++++++++++++++++++++++++++");
  float fSensorData = 15.23;
  int chk = DHT.read22(DHT22_PIN);
  switch (chk)
  {
  case 0: 
    Serial.print("OK,\t");
    TempC = DHT.temperature;
    Humidity = DHT.humidity;
    break;
  case -1:
    Serial.print("Checksum error,\t");
    break;
  case -2:
    Serial.print("Time out error,\t");
    break;
  default:
    Serial.print("Unknown error,\t");
    break;
  }
 
  TempF = float((TempC * float(1.8))+32);

  dataout.updateData(0, analogRead(0));
  dataout.updateData(1, analogRead(1));
  dataout.updateData(2, TempF);
  dataout.updateData(3, Humidity);
 
  int status = dataout.updatePachube();

  Serial.print("sync status code <OK == 200> => ");
  Serial.println(status);

  PrintDataStream(dataout);
  OldTemp = TempF;
  OldHumidity = Humidity;
  delay(30000);
}

void PrintDataStream(const ERxPachube& pachube)
{
  unsigned int count = pachube.countDatastreams();
  Serial.print("data count=> ");
  Serial.println(count);

  Serial.println("<id>,<value>");
  for(unsigned int i = 0; i < count; i++)
  {
    Serial.print(pachube.getIdByIndex(i));
    Serial.print(",");
    Serial.print(pachube.getValueByIndex(i));
    Serial.println();
  }
}


Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: StaticDet5 on Sep 07, 2011, 10:19 am
robtillaart,
Thank you very much!
I'm in the process of trying to reduce the number of erroneous readings with the DHT22 sensor.  It seems that a 1 in 10 error rate is something to actually shoot for.  Some of my test runs are scoring an error rate of closer to 4 in 10 or higher.

Has anyone had any success reducing the error rate with this sensor?  I've placed the filter capacitor across the power and ground pins, but that didn't seem to have much of an effect.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: StaticDet5 on Sep 07, 2011, 09:22 pm
More of an update:
I added in batch of code that records how often the system is getting Checksum errors.  I then left the system running while I went to sleep.  Lo and Behold, the error rate is consistently 45%, and I'm frequently getting abberant readings of ~55f (~12c).  The room is clearly not that cold.

I know you're not supposed to check the sensor more often than every 2 seconds.  I rewrote robtillaart's code a little bit (Which is like having a 4th grader trying to follow Da Vinci, his code is much more succinct):
Code: [Select]

#include <dht.h>
#include "ERxPachube.h"
#include <Ethernet.h>
#include <SPI.h>

dht DHT;
#define DHT22_PIN 7
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x00, 0x21, 0xE3 };
byte ip[] = {
  192, 168, 1, 20   };                  // no DHCP so we set our own IP address

float TempC = 0;
float Humidity = 0;
float TempF = 0;
float OldTemp = 0;
float OldHumidity = 0;
float error = 0;
float run = 0;
float errorPerc = 0;

#define PACHUBE_API_KEY "Your API Here" // fill in your API key PACHUBE_API_KEY
#define PACHUBE_FEED_ID 34665 // fill in your feed id

ERxPachubeDataOut dataout(PACHUBE_API_KEY, PACHUBE_FEED_ID);

void PrintDataStream(const ERxPachube& pachube);

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip);

  dataout.addData(0);
  dataout.addData(1);
  dataout.addData(2);
  dataout.addData(3);
}

void loop() {

  Serial.println("+++++++++++++++++++++++++++++++++++++++++++++++++");
  float fSensorData = 15.23;
  int chk = DHT.read22(DHT22_PIN);
  delay(10000);
  switch (chk)
  {
  case 0: 
    Serial.print("OK,\t");
    TempC = DHT.temperature;
    //Humidity = DHT.humidity;
    break;
  case -1:
    Serial.print("Checksum error,\t");
    error = error +1;
    break;
  case -2:
    Serial.print("Time out error,\t");
    break;
  default:
    Serial.print("Unknown error,\t");
    break;
  }
 
  TempF = float((TempC * float(1.8))+32);
  if (TempF > 150)
  {
    TempF = OldTemp;
  }
  delay(20000);
  int chk2 = DHT.read22(DHT22_PIN);
  delay(10000);
  switch (chk2)
  {
  case 0: 
    Serial.print("OK,\t");
    //TempC = DHT.temperature;
    Humidity = DHT.humidity;
    break;
  case -1:
    Serial.print("Checksum error,\t");
    error = error + 1;
    break;
  case -2:
    Serial.print("Time out error,\t");
    break;
  default:
    Serial.print("Unknown error,\t");
    break;
  }
  if (Humidity > 101)
  {
    Humidity = OldHumidity;
  }
 

  dataout.updateData(0, analogRead(0));
  dataout.updateData(1, analogRead(1));
  dataout.updateData(2, TempF);
  dataout.updateData(3, Humidity);
 
  int status = dataout.updatePachube();

  Serial.print("sync status code <OK == 200> => ");
  Serial.println(status);

  PrintDataStream(dataout);
  if (TempF < 150)
  {
    OldTemp = TempF;
  }
  if (Humidity < 101)
  {
    OldHumidity = Humidity;
  }
 
  run = run+2;
  errorPerc = error / run;
  Serial.print(errorPerc);
  Serial.println("% errors");
  delay(20000);
}

void PrintDataStream(const ERxPachube& pachube)
{
  unsigned int count = pachube.countDatastreams();
  Serial.print("data count=> ");
  Serial.println(count);

  Serial.println("<id>,<value>");
  for(unsigned int i = 0; i < count; i++)
  {
    Serial.print(pachube.getIdByIndex(i));
    Serial.print(",");
    Serial.print(pachube.getValueByIndex(i));
    Serial.println();
  }
}


I'm trying to send information my environmental conditions to Pachube every minute.  That's the goal.
I'm wondering about the requests to the sensor.  The
int chk = DHT.read22(DHT22_PIN);
and subsequent "case" check, is that a request from the sensor?
When I'm asking the sensor for the current humidity and temperature, are those two different requests?  Should I space these out as much as possible?  (This is what I did in the code above).
Or does the
int chk = DHT.read22(DHT22_PIN);
request call all the sensor information, and load it into the Arduino memory, waiting for the DHT.temperature and DHT.humidity calls?

Does anyone else have a similar error rate?  That's what I'm really trying to drive down.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Sep 07, 2011, 09:48 pm

int chk = DHT.read22(DHT22_PIN);

The read22() call tries to read data from the sensor and fills the variables DHT.temperature and DHT.humidity. The return value tells if something went wrong during that "exercise". Some people work with the "good weather" scenario and leave out all the checks, that's a design choice.

Quote
When I'm asking the sensor for the current humidity and temperature, are those two different requests?

NO, if you do a read22() both temperature and humidity are read. They can be obtained by reading the members DHT.temperature and DHT.humidity

Quote
Or does the
int chk = DHT.read22(DHT22_PIN);
request call all the sensor information, and load it into the Arduino memory, waiting for the DHT.temperature and DHT.humidity calls?

Yes, if you dive into the code of the library (don't be afraid ;) , you see that temp and humidity are both filled in the read22() call.

MY errorrate with this sensor was definitely lower, no figures at hand.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: StaticDet5 on Sep 10, 2011, 09:51 am
I've posted on the retailer's website.  I'll let you folks know what develops.
Thanks again!
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: olliduino on Sep 22, 2011, 12:21 pm


Here's my first pass: http://arduino-info.wikispaces.com/TemperatureHumidity (http://arduino-info.wikispaces.com/TemperatureHumidity)  PLEASE critique / comment!!



Hi Terry, i´m new with Arduino and my first project is building a temperature-regulator. just i see your project and take parts from your code, but i can not see negative values on my display. have you got an idea, which part i must change? Sorry, i´m newbie and my english is not the best, but i hope, you or everyone can help...

thank you

olli

Code: [Select]


/*
Basierend auf einen Artikel auf dieser Seite:
http://arduino-info.wikispaces.com/PROJECT-Temp-Humidity-Display

den aktuellen Stand findest Du hier:
http://alturl.com/rpods
*/

/*-----( Import needed libraries )-----*/
#include <dht11.h>
#include <Wire.h>
#include <LiquidCrystal.h>
/*-----( Declare objects )-----*/
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //##### DFRobot LCD Keypadshield V1.0
// legt die pins auf dem shield fest

/* begin des tastatur-bereichs */
int lcd_key = 0; // legt nutzung der tasten fest und dann die tasten selber
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
/* ab hier: einlesen der werte der tasten (wiederstands gebilde mit
unterschiedlichen spannungswerten zu jeder taste...*/

int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons
since it will be the most likely result
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE; // when all others fail, return this...
}
/* das wars mit dem tastatur-bereich */

dht11 DHT11;
/*-----( Declare Constants, Pin Numbers )-----*/
#define DHT11PIN 2

float alarmwert (20);

void setup() /*----( SETUP: RUNS ONCE )----*/
{
Serial.begin(9600);
lcd.begin(16,2); //##### Display Size for DFRobot LCD Keypadshield V1.0
lcd.home ();
lcd.println ("Olliduino "); //##### schreibe willkommensnachricht und springe eine zeile weiter
lcd.setCursor (0,1);
lcd.print ("2011 by olli "); //##### schreibe willkommensnachricht
lcd.home ();
delay(3000);
lcd.clear ();

}/*--(end setup )---*/
 

void loop() /*----( LOOP: RUNS CONSTANTLY )----*/
{

// digitalWrite(13, HIGH);


int chk = DHT11.read(DHT11PIN);

Serial.println("---------------------------"); //der Lesbarkeit erstmal eine Zeile
switch (chk) // teste, ob ueberhaupt daten fliessen
{
case 0: Serial.println("DHT11 ist OK");
Serial.print ("gelieferter Wert: ");
Serial.println ((float)DHT11.temperature,1);
break;
case -1: Serial.println("Checksum error"); break;
case -2: Serial.println("Time out error"); break;
default: Serial.println("Unknown error"); break;
}
Serial.print((float)alarmwert, 1);
Serial.println("C Darunter-Gibt-es-ALARM-Temperatur");
Serial.print((float)DHT11.temperature,1);
Serial.println("C IST-Temperatur");
if ( DHT11.temperature < alarmwert )
{
digitalWrite(13, HIGH);
Serial.println("### !!! Alarm erreicht !!! ###");
lcd.setCursor (15,0); //##### schreibe ab zeichen 14 in zeile 1 (zeile 1 ist gleich 0)
lcd.print("!");
lcd.setCursor (0,1);
}
else
{
digitalWrite(13, LOW);
Serial.println("Alarm nicht erreicht, alles OK");
lcd.setCursor (15,0); //##### schreibe ab zeichen 14 in zeile 1 (zeile 1 ist gleich 0)
lcd.print("*");
lcd.setCursor (0,1);
}


//lcd.noAutoscroll();
lcd.setCursor (0,1);
lcd.print(alarmwert,0);
lcd.print("Cs ");
lcd.print((float)DHT11.temperature,1);
lcd.print("Ci ");
lcd.print((float)DHT11.humidity,1);
lcd.print("%");

digitalWrite(13, LOW);

delay(1000);




// jetzt lesen wir noch die tasten ein und machen was draus

lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action
{
case btnRIGHT:
{
lcd.setCursor (0,0);
lcd.print("> ");
break;
}
case btnLEFT:
{
lcd.setCursor (0,0);
lcd.print("<");
break;
}
case btnUP:
{
alarmwert = alarmwert + 1;
lcd.setCursor (0,0);
lcd.print("^");
break;
}
case btnDOWN:
{
alarmwert = alarmwert - 1;
lcd.setCursor (0,0);
lcd.print("v");
break;
}
case btnSELECT:
{
lcd.setCursor (0,0);
lcd.print("*");
break;
}
case btnNONE:
{
lcd.setCursor (0,0);
lcd.print(" ");
break;
}
}










}
/* --(end main loop )-- */

Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Dec 31, 2011, 04:58 pm

updated the code to support Arduino 1.0 - as allways comments still welcome
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: alobar on Feb 13, 2012, 08:45 am
Hi Rob,
Thank you so much for writing such an easy to use library!
I wanted to ask you a question if I may -
I'm using the DHT-11,
I tried supplying it with different voltages (3V, 3.3V, 5V - using the
Arduino Uno's 3V,5V and the Arduino Fio's 3.3V power supply)
and for each voltage there are different readings for the temperature and humidity (a
very big difference between 3V and 5V).
what is the correct voltage that it should be supplied with?
(or  is there a way to work around this?)
according to the datasheet it can be supplied with 3V - 5.5V.

thanks!
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Feb 13, 2012, 08:57 pm
Quote
I wanted to ask you a question if I may -


you may,

Quote
I tried supplying it with different voltages (3V, 3.3V, 5V - using the
Arduino Uno's 3V,5V and the Arduino Fio's 3.3V power supply)
and for each voltage there are different readings for the temperature and humidity (a
very big difference between 3V and 5V).
what is the correct voltage that it should be supplied with?Ac


As you say according to the datasheet, any voltage between 3 and 5.5V should work. I only can confirm that the readings makes good sense at 5Volt.

Quote
(or  is there a way to work around this?)

External powersupply for the sensor? does also make sense if the sensor is a bit further away, long wires.


If you use 3.5 volt and you take longer delays between the readings, does the accuracy of the reading increase?
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: froglips on Mar 16, 2012, 05:18 pm
I just wanted to say THANK YOU for all of the work! I just received a Freetronics Eleven and the DHT22 sensor. I tried the Library suggested, but just kept getting error during the compile process. And then I found your tutorial!!! Although it took me a bit to figure out how to create the Library from your work, once I did, everything started working. Now I am trying to figure out how to combine the Dew Point and C to F conversion from the DHT11 sketch with the DHT22 sketch so I can have the most information from just the one sketch.

Thanks again,
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: zoid_berg on Jun 18, 2012, 10:35 am
Hi all,
At first I want to thank you for the library. Very nice and succint.

However, I noticed that in about 50% of all cases I'm getting a checksum error. This happens both, using 3.3V or 5V power supply. 
Does anyone now whether this is a hardware problem (low cost sensor?) or a timing problem while retrieving the data from the sensor?
I read that someone else also had this problem. Any solution? Typical situation :

DHT22,    Checksum error,   48.7,   1665.4
DHT22,    Checksum error,   48.7,   1665.4
DHT22,    Checksum error,   48.1,   846.2
DHT22,    Checksum error,   48.1,   846.2
DHT22,    OK,   48.5,   27.0
DHT22,    Checksum error,   48.4,   846.2
DHT22,    OK,   48.5,   27.0
DHT22,    Checksum error,   48.4,   846.2
DHT22,    OK,   48.5,   27.0
DHT22,    OK,   48.3,   27.0

Thanks for any help!
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Jun 19, 2012, 06:51 pm
Quote
Any solution?

You might need a pull up resistor (eg 4K) between +5V and the dataline.

How long is the line between the arduino and the sensor?

Rob
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Jul 09, 2012, 08:50 pm
updated the code to 0.1.03;

+ added code to reflect faulty reading in temperature (-999)  and humidity (-999)  if there is a timeout. So if a sketch does not test the return value of read11() or read22() you will still see it clearly.

As allways comments still welcome
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: tochinet on Oct 09, 2012, 03:45 pm
One suggestion for the code is to replace or augment the read11 and read22 routines by one unique read routine that would detect which one it is and return 11 or 22 in chk.

I'm not sure it is _so_ easy, but for example, having both [2] and [4] zero with a DHT22 should almost never happen, right ?

They are the lsB if I get it right, so humidity has to be 25.6, 51.2 or 76.8 for byte[4] to be zero.
Then in that case temperature has to be precisely 25.6 etc.
Pretty unusual.

To be even more confident, there could be a "confidence" variable based on previous measurements:
increase/decrease  a uint8_t counter for every non/zero value with saturation @ +127/-128, so DHT11 goes from zero @reset to -128 and DHT22 to +127.

Another thing is to replace the double by an int in tenths of degrees. So for DHT11 it would return array[0]*10;
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Oct 14, 2012, 02:44 pm
Quote
One suggestion for the code is to replace or augment the read11 and read22 routines by one unique read routine that would detect which one it is and return 11 or 22 in chk

Don't mix error state with configuration information. That said, one could make a function int determine() that does just that. Typically it is called just once and remembered - you just needs one byte to keep the 11/22 flag of 8 sensors.

Quote
I'm not sure it is _so_ easy, but for example, having both [2] and [4] zero with a DHT22 should almost never happen, right ?

possible but one could only account readings for which [2] and [4] are zero AND the checksum is OK.

Assuming a valid reading, both numbers have one decimal place 0..9 =>10 possible values. This implies that the chance would be about one in hundred for an individual reading to have two 0's as decimal. That is a small chance but too big imho to make a reliable determine() function, it is definitely not deterministic. Multiple readings with will improve this number but as the device needs 2 seconds between readings so determine() function becomes quite time consuming.

Note that especially for the DHT11 one can use a (running) average to get a higher precision - and thus decimal places ).
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: jrbenito on Nov 29, 2012, 05:48 pm
Hi robtllaart


updated the code to 0.1.03;

+ added code to reflect faulty reading in temperature (-999)  and humidity (-999)  if there is a timeout. So if a sketch does not test the return value of read11() or read22() you will still see it clearly.

As allways comments still welcome


I would change the follow code in read22() and read11() functions from

Code: [Select]

int rv = read(pin);
        if (rv != 0)
    {


to

Code: [Select]

int rv = read(pin);
        if (rv != DHTLIB_OK)
    {


No functionally change but improves readability.

Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Nov 29, 2012, 07:26 pm
That is very keen eye!  I will change it asap

Thanks,
Rob
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Nov 29, 2012, 07:50 pm
updated on the playground to version 0.1.04

+ added the rv != DHTLIB_OK as suggested by jrbenito (thanks)
+ added #define DHTLIB_INVALID_VALUE  -999  to remove that magic number from the lib too.

Rob
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: jrbenito on Nov 29, 2012, 09:23 pm


+ added #define DHTLIB_INVALID_VALUE  -999  to remove that magic number from the lib too.

Rob


Wow! Very good too.

Thanks for this code and best regards,
Benito.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: RoseMan on Dec 23, 2012, 04:44 pm
Hi,

Nice library.  However, it does not work correctly for negative temperatures.  I'm using version 0.1.04.  When a negative temperature is measured the class will return DHTLIB_ERROR_CHECKSUM.  The problem is at line 74 in dht.cpp.  Here bits[2] is modified, which makes the checksum calculation incorrect.  There are, of course, many ways to fix the problem.  I have fixed it by changing the code in the following way.

Old Code:
Code: [Select]
        int sign = 1;
        if (bits[2] & 0x80) // negative temperature
        {
                bits[2] = bits[2] & 0x7F;
                sign = -1;
        }
        temperature = sign * word(bits[2], bits[3]) * 0.1;


New Code:
Code: [Select]

        if (bits[2] & 0x80) // negative temperature
        {
                temperature = word(bits[2]&0x7F, bits[3]) * 0.1;
                temperature = -1.0 * temperature;
        }
        else
        {
                temperature = word(bits[2], bits[3]) * 0.1;
        }


Thanks for the library, and with this fix it is just perfect for me!
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Dec 23, 2012, 05:16 pm

Thanks for this feedback, I'll fix it a.s.a.p.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Dec 23, 2012, 05:39 pm
- http://playground.arduino.cc//Main/DHTLib -

updated the playground article to include the patch above.

Thanks again!
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: markruys on Jun 11, 2013, 12:14 am
No idea why someone wants to write code if there already exists a perfectly fine library... but... I just checked in a DHT library with the following features:
  - Support for DHT11 and DHT22, AM2302, RHT03
  - Auto detect sensor model
  - Very low memory footprint
  - Very small code

https://github.com/markruys/arduino-DHT

Maybe useful for someone - feel free to report bugs.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Jun 11, 2013, 07:04 pm
Well done Mark,

Looked at your code and it looks like a decent piece of work. It is similar to a version I'm working on and yes I better stop with that version ;)

The difference between your code and mine is that your code encapsulated an individual sensor while mine encapsulates the handshake so multiple sensors use one instance.
Footprint will differ too but not measured. I like the auto-detect functionality, well done

There is one improvement I want to propose to your class which I had build in my draft. If there is a time-out I would return the previous values instead of NaN. The error flag should still be the same. To do this the results temperature & humidity should have class scope.

If the program requests the temperature too fast it just gets the prev value which is seldom far from the actual value (instead of a NaN)

something like this
Code: [Select]


DHT::DHT_t DHT::read()
{
 // don't poll the sensor too often
 // - Max sample rate DHT11 is 1 Hz   (duty cycle 1000 ms)
 // - Max sample rate DHT22 is 0.5 Hz (duty cycle 2000 ms)

 unsigned long startTime = millis();
 if ( (startTime - lastReadTime) < getMinimalDelay()  )   // use the internal function
 {
  results.error = ERROR_TOO_QUICK;
  return results;  // returns previous temperature and humidity
 }
 lastReadTime = startTime;

 results.error = ERROR_NONE;
 results.temperature = NAN;
 results.humidity = NAN;
 // Request sample
 ...


the way I coded the interface was 3 public functions

Code: [Select]

float DHT::getHumidity()
{
 if ( millis() - lastReadTime > 2000 || status != ERROR_NONE )  // time to refresh or to retry
 {
   status = read();  // fetch new hum & temp
 }
 else
 {
   lastReadTime  = millis();
 }
 return humidity;
}


float DHT::getTemperature()
{
 if ( millis() - lastReadTime > 2000 || status != ERROR_NONE )
 {
   status = read(); // status and read() are private
 }
 else
 {
   lastReadTime  = millis();
 }
 return temperature;  // private member
}

float DHT::getStatus()
{
  status = read();  // fetch new data
}


typing this you could also add the "retry" condition.

my 2 cents,
regards / groeten,
Rob

Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: MarsWarrior on Jun 11, 2013, 09:53 pm
Just a few questions while checking both DHT versions:

Rob:
- Has a delay of 20msec for both DHT11 and DHT22.
- Uses a counter in the while to break out of the while in case the pin does not change

Mark:
- Has a delay of 18msec for the DHT11 and 800usec for the DHT22.
- Uses an endless while loop, so if the pin does not change --> Arduino in endless loop!

Further:
- I am using multiple DHT22's on different pins. Which library would be most RAM efficient?
- Is the 800usec the right delay for the DHT22? If so, it saves me 5*19msec = 75msec of doing nothing, which is a lot using NilRTOS/ChibiOS RTOSses...

Please comment  8)
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Jun 11, 2013, 10:44 pm
Quote
Rob:
- Has a delay of 20msec for both DHT11 and DHT22.
- Uses a counter in the while to break out of the while in case the pin does not change

The counter makes the loop fool proof.
The 20 mSec is to make code as similar as possible for both sensors, Mark optimizes the code to the detail of the datasheet which is good better ;)


Quote
I am using multiple DHT22's on different pins. Which library would be most RAM efficient?

Not tested, I expect the lib from mark be smaller for a single sensor but my lib can support multiple with one instance. Somewhere there must be a break even point.
It would be very informative if you could provide some numbers

Quote
- Is the 800usec the right delay for the DHT22? If so, it saves me 5*19msec = 75msec of doing nothing, which is a lot using NilRTOS/ChibiOS RTOSses...

800usec - check datasheet.

In an RTOS one should schedule another thread when delay is called, to return /test later. In pseudocode
Code: [Select]
delay(uint32_t ms)
{
  wakeUpThisThread(ms);
  switchThread();
}

This way one could always use the waiting time effective. (disclaimer, no RTOS expert)
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: markruys on Jun 11, 2013, 11:01 pm
Thanks Rob for your suggestions. I just commited a new version of the library with the following changes:


Code example:
Code: [Select]

#include "DHT.h"

DHT dht = DHT(2); // data pin 2, auto detect DHT model

void setup()
{
  dht.setup();
}

void loop()
{
  delay(dht.getMinimalDelay());

  Serial.print(dht.getHumidity(), 1);
  Serial.print("\t");
  Serial.println(dht.getTemperature(), 1);
}
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: markruys on Jun 11, 2013, 11:12 pm

Just a few questions while checking both DHT versions:

Rob:
- Has a delay of 20msec for both DHT11 and DHT22.
- Uses a counter in the while to break out of the while in case the pin does not change

Mark:
- Has a delay of 18msec for the DHT11 and 800usec for the DHT22.
- Uses an endless while loop, so if the pin does not change --> Arduino in endless loop!

Further:
- I am using multiple DHT22's on different pins. Which library would be most RAM efficient?
- Is the 800usec the right delay for the DHT22? If so, it saves me 5*19msec = 75msec of doing nothing, which is a lot using NilRTOS/ChibiOS RTOSses...

Please comment  8)




Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: MarsWarrior on Jun 12, 2013, 09:16 am


  • 800usec for a DHT22 is according to the datasheets I found. And it works.

Nice. Will try with the current lib I'm using!
Quote

  • My library won't hang. The endless loop you mention has a return statement which is called after 85 usec.

  • Per DHT instance, you need 18 bytes of data, perhaps a little more overhead, I would need to measure to give a hard number. So no problem to run a lot of DHT sensors (tried two myself). The advantage of having an instance per sensor is that you can read out them in parallel. On the other hand, it would be straightforward to alter setup() to something like setup(pin, model) and then you could reuse the instance. But not sure if the effort is worth the 18*(sensor-1) bytes...


Ah! You are right, I misread some of the C++ code  :smiley-zipper:
18 bytes is not very much indeed. Thanx!
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: markruys on Jun 12, 2013, 08:38 pm
Rob Tillaart suggested that I created a another thread for the new library, so I did: http://forum.arduino.cc/index.php?topic=171677.0 (http://forum.arduino.cc/index.php?topic=171677.0). This way we keep this thread focussed on Rob's great work.

I reworked my library and just commited all my changes for some more features.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: sanhardik on Jun 15, 2013, 12:11 pm
Hello Rob,
I tried this library on Arduino Due and it seems since its SAM series processor the includes for AVR wont work (avr/io.h etc).
Can you suggest changes to make this library compile and work on Arduino Due boards .

Thanks for the help
Title: Re: Class for both DHT11, DHT21 and DHT 22 (temperature & humidity)
Post by: robtillaart on Aug 26, 2013, 02:36 pm
Added support for the DHT21 (AM2301) today - http://playground.arduino.cc/Main/DHTLib -

datasheet DHT21: - http://www.electrodragon.com/w/images/6/6f/DHT21.pdf -
Seen at: - http://www.electrodragon.com/?product=am2301-dht21-digital-temperature-humidity-sensor -

The DHT21 has the same handshake as the DHT11 and DHT22. The translation to real values (TEMP/RH) is different again.
As I do not have the sensor yet I have not tested it, so all feedback is welcome.

As always remarks and feedback is welcome.
Title: Re: Class for both DHT11 and DHT 22 (temperature & humidity)
Post by: robtillaart on Aug 27, 2013, 01:08 pm
Sorry for the late reaction, I missed it somehow.


Hello Rob,
I tried this library on Arduino Due and it seems since its SAM series processor the includes for AVR wont work (avr/io.h etc).
Can you suggest changes to make this library compile and work on Arduino Due boards .

Thanks for the help


I have no Due operational, but you should check the private read() function.
It uses a  #define TIMEOUT 10000  which is tuned for the 16Mhz UNO. so it will trigger too fast on an DUE.
As the Due is 84 MHz ==> 5.25 x as fast, you should adjust the TIMEOUT to 60000 (at least)

A more permanent solution should derive a clock dependant timeout like this

Code: [Select]

#define TIMEOUT (F_CPU/1600)


please give it a try.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Sep 13, 2013, 01:58 pm
update:
Got mail today, DHT21 testing is in progress, the code in the lib seems not to decode right.

The decoding was based upon this hint from the datasheet:
"DATA=8 bit integral RH data+8 bit decimal RH data+8 bit integral T data+8 bit decimal T data+8 bit check-sum "
HEX dumps of received bytes have a correct CRC. A new decoding scheme is derived from the dumps and currently under test.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: wifialex on Sep 15, 2013, 03:25 am
I have some problems with the library.
I have an arduino due and an am2301 sensor (DHT21).
The temperature at the moment that I tested the sensor was more or less 22 degrees.
I set up: #define TIMEOUT 52500 in dht.cpp

Data showned in dht_test.ino is:
Humidity  2.3
Temperature 0.9

Any idea??
Thanks!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Sep 15, 2013, 04:21 pm

I have some problems with the library.
I have an arduino due and an am2301 sensor (DHT21).
The temperature at the moment that I tested the sensor was more or less 22 degrees.
I set up: #define TIMEOUT 52500 in dht.cpp

Data showned in dht_test.ino is:
Humidity  2.3
Temperature 0.9

Any idea??
Thanks!


Yes, the code for the support of the DHT21 is experimental, based on hints in a datasheet (link see a few pages above) and just does not work yet.

Can you please access the DHT21 as if it was a DHT22 so use read22(pin) instead of read21(pin)?

I have strong indications that the formula for DHT21 and DHT22 are identical although the datasheet hinted otherwise.
I have no confirmation yet and maybe you can confirm (as I do not have the DHT21 myself).

When my assumption is confirmed I can update the code.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: wifialex on Sep 16, 2013, 12:45 am
I have just checked it using dht22 read.
The measures are closed to real but there are errors:
Humidity is lower than real
Temperature is higher than real
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Sep 16, 2013, 03:32 pm
Can you give exact figures, lower and higher are too subjective.

Low humidity is often mentioned as problem with the DHT sensors, temperature can depend on air flow but should be within 3C. In your code you can add an offset to adjust the temp to the real value. For humidity this will probably not work.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: wifialex on Sep 23, 2013, 12:08 am
First of all, sorry for my delayed answer, but I was very busy.
The first one pic sensor was calibrated two months ago, so it should be very accurate.
The second one pic is DHT21 data
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Sep 23, 2013, 11:13 am
This proves that the DHT21 uses the same conversion as the DHT22. I will update the playground and the lib.
The delta in temperature is within acceptable errors. You might add an offset to adjust.

Thanks for testing,
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: wifialex on Sep 26, 2013, 09:52 pm
You are welcome, I added an offset -2º in temperature data
Thanks!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: miniwark on Nov 19, 2013, 03:22 pm
How did this library compare with the popular Adafruit one ?
https://github.com/adafruit/DHT-sensor-library

In any case, maybe you add their lib to the other "Library list".
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 25, 2013, 09:50 pm

You are welcome, I added an offset -2º in temperature data
Thanks!


Do you (or others)  think the library should support for a corrective offset?

e.g.  
Code: [Select]
void setTempOffset(float delta);
float getTempOffset();
void setHumOffset(float delta);
float getHumOffset();

or in the constructor...

will work better if the library uses an object per sensor iso one object for all sensors. need a rewrite... something like  
DHT22 sensor1(pin, offset);
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 26, 2013, 07:04 pm
Updated the playground to version 0.1.08
major change - support for DUE (adaptive TIMEOUT).
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: derrick345 on Dec 10, 2013, 04:15 am
     Greetings,
Thanks for the work. I am having problems with compiling the code. I have an UDOO and I am attempting to execute the code on the DUE side. I get the following error though. Any help would be greatly appreciated.

V/r

Derrick

Quote

DHT/dht.cpp.o: In function `dht::read(unsigned char)':
/home/ubuntu/Arduino/libraries/DHT/dht.cpp:116: multiple definition of `dht::read(unsigned char)'
dht.cpp.o:dht.cpp:116: first defined here
DHT/dht.cpp.o: In function `dht::read22(unsigned char)':
/home/ubuntu/Arduino/libraries/DHT/dht.cpp:78: multiple definition of `dht::read22(unsigned char)'
dht.cpp.o:dht.cpp:78: first defined here
DHT/dht.cpp.o: In function `dht::read21(unsigned char)':
/home/ubuntu/Arduino/libraries/DHT/dht.cpp:70: multiple definition of `dht::read21(unsigned char)'
dht.cpp.o:dht.cpp:70: first defined here
DHT/dht.cpp.o: In function `dht::read11(unsigned char)':
/home/ubuntu/Arduino/libraries/DHT/dht.cpp:42: multiple definition of `dht::read11(unsigned char)'
dht.cpp.o:dht.cpp:42: first defined here
/opt/arduino-1.5.4/hardware/tools/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/thumb/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): warning: undefined reference to `_sbrk'
collect2: ld returned 1 exit status

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 10, 2013, 08:39 am
do you have the lib included twice?
copied it to 2 locations?  (sketch folder , library folder, arduino lib folder?)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: derrick345 on Dec 11, 2013, 10:17 pm
    Thanks for the reply,
Apparently, it  was Arduino IDE issue. Initially, I placed the sketch in the same place as I did the libs. Once I changed that the sketched worked.  I tried the latetst lib and code for the DHT22, and I noticed that it did not execute at all. Is it suppose to work with the DUE? IT compiled fine however, there is no output from the Arduino serial monitor even though there are serial print functions listed. Even if something was wrong with the libs, those statements should print.  Not sure if it is a UDOO, DUE, or library thing.
V/r
Derrick
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 12, 2013, 06:54 pm
Can you post the code you used?

Do you check the return values the library gives for read?

If you use DHT11 in your code and sample a DHT22 (HW) you should get some values back.
Can you try that?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: perrociego on Dec 15, 2013, 08:22 pm
Hi Rob:

Thank you for your easy and great code. I´m learning a lot.

By the way:  
Doesnt if ((micros() - t) > 40) {} require something like else return DHTLIB_ERROR_TIMEOUT; ?

Also, isnt bits() a Byte?

Regards:
Marcelo from Buenos Aires



Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 15, 2013, 08:50 pm

By the way: 
Doesnt if ((micros() - t) > 40) {} require something like else return DHTLIB_ERROR_TIMEOUT; ?


HI Marcello,

This line of code sets a 1 bit on a specific bit position (the cnt'th bit).

As the bits are preset to 0 on all bit positions they do not need to be explicitly cleared, e.g. like the code below would do.
Code: [Select]

if ((micros() - t) > 40) bitset(bits[idx], cnt);
else bitclear(bits[idx], cnt)


The timeout is guarded by the loops above this line with the variable loopCnt.

I have thought about a version of the DHT lib where timing and timeout is replaced by a proper call to micros(); That way the protocol would work on faster or slower CPU's. Problem with micros() however is that for a 16Mhz Arduino it has a granularity of 4 uSec. An 8MHZ version would have a micros() granularity of 8 or maybe even more. That would make it hard to do the short timing. (Imagine a tiny85 working on 1 MHz => would not work)
For the faster processors like the DUE, the lib would work probably better with micros() for timekeeping.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: perrociego on Dec 15, 2013, 09:46 pm
HI Rob:

Of course.

I was looking at the code again. Get that. Going to change my question.

But you go too fast.  :smiley-eek:

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 15, 2013, 09:51 pm
you will pick up speed as long as you keep asking questions! (no there ain't no bad questions, only bad answers)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Feb 08, 2014, 02:27 pm
Updated the playground to version 0.1.09
+ reduced the foot print with 30 bytes.
  - predecrement in timeoutloops
  - use of mask to build up bytes.

+ added time measurement in the DHT22 example sketch.
   On average a reading takes 24- 25 milliseconds, most of this time is the wake up call.
   Should be investigated as this is now 80% of the blocking time.

- http://playground.arduino.cc//Main/DHTLib -
- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib - (code only)

Recently confirmed to work on:  Digistump Digix   84 MHz Clock Speed too.
- http://forum.arduino.cc/index.php?topic=215336 -


Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Burn-In on Feb 11, 2014, 10:09 pm
I've copy+paste the code for the dht.h and dht.cpp from github. But if i use it for my scetch i have this strange "\stray" errors.

.../dht.h:1: error: stray '\357' in program
.../dht.h:1: error: stray '\273' in program
.../dht.h:1: error: stray '\277' in program

I think it means there is an error in the dht.h file. Isn't it?
With the older revision of the library everything was fine.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Feb 11, 2014, 10:23 pm
cannot replicate your error.

Can you zip the dht.h that fails and attach it in a post here  ?
Are you on windows mac unix?
What editor (settings) are you using?  ==> is the file changed to UTF-8 format instead of ASCII?


link to the previous version 1.0.8 - https://github.com/RobTillaart/Arduino/blob/4126dfc63a3dc645bfc518e0cefe3cda653903cf/libraries/DHTlib/dht.h -
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Burn-In on Feb 12, 2014, 11:41 am
Hi Rob,
thanks for reply.
You had the right instinct. :)
There was the same 3 characters in both files too much. The files was changed to UTF-8 and everything seems ok.

Many thanks .
Joerg
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Feb 12, 2014, 06:22 pm
You're welcome.

please let me know if any other issues pop up.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: joergsh on Mar 12, 2014, 11:09 am
Hello,
at first many thanks for this great lib.

I tested it on a pro mini with 3,3v and 16MHz and it works fine.

For safety work i bought some 3,3V 8 MHz boards but run in trouble with the 8 MHz.

Could You please help me to make it work with please :)  I choose the right board, serial and one wire sensors works fine.

So could I make changes to make it run with 8MHz 328p?

Thanks in advance and regards

Joerg
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 12, 2014, 04:43 pm

Code: [Select]
[code] but run in trouble with the 8 MHz.[/code]
Can you explain the kind of trouble you have?
What output did your sketch generate?
(Please post it here for others reference - I know you mailed it to me)

Have you tried to run the examples?

You mailed me you renamed the lib because of a name conflict, please can you move the other lib from the libraries folder and use the original name.




Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: joergsh on Mar 12, 2014, 06:33 pm
ok for better verification I build a simple sketch based on yours:
Code: [Select]

//
//    FILE: dht_test.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.07
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
//     URL: http://arduino.cc/playground/Main/DHTLib
//
// Released to the public domain
//

#include <dht.h>

dht DHT;

#define DHT22_PIN 2

void setup()
{
  Serial.begin(9600);
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT_LIB_VERSION);
  Serial.println();
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}

void loop()
{
  // READ DATA
  Serial.print("DHT22, \t");
  int chk = DHT.read22(DHT22_PIN);
  switch (chk)
  {
    case DHTLIB_OK: 
Serial.print("OK,\t");
break;
    case DHTLIB_ERROR_CHECKSUM:
Serial.print("Checksum error,\t");
break;
    case DHTLIB_ERROR_TIMEOUT:
Serial.print("Time out error,\t");
break;
    default:
Serial.print("Unknown error,\t");
break;
  }
  // DISPLAY DATA
  Serial.print(DHT.humidity, 1);
  Serial.print(",\t");
  Serial.println(DHT.temperature, 1);

  delay(1000);



}
//
// END OF FILE
//



Output is:

Quote

Read sensor: Time out error<\r>
<\n>Humidity (%): 0.00<\r>
<\n>Temperature (??C): 0.00<\r>
<\n>Temperature (??F): 32.00<\r>
<\n>Temperature (??K): 273.15<\r>
<\n>Dew Point (??C): nan<\r>
<\n>Dew PointFast (??C): nan<\r>





Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 12, 2014, 07:00 pm
do you have a pull up resistor (4K7 or 10K) on the dataline?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: joergsh on Mar 12, 2014, 07:02 pm
I have 4k7 on data line and it works fine with a pro mini with 16 MHz
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: bevangg on May 04, 2014, 07:09 pm
Thanks, worked for me, used a 10k
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: joergsh on May 04, 2014, 07:11 pm
with 8 MHz ?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: bevangg on May 04, 2014, 07:13 pm
Sorry no, using nano @16mhz, was getting odd / erroneous readings from dht11, 10k pullup and it works
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on May 05, 2014, 08:37 pm
@bevangg
how long/short are your wires?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: bevangg on May 05, 2014, 09:47 pm
Hi see attached images (right click and view in new tab, they are too big for the forum viewer), the DHT11 is on a prototyping board and is wired using very short connections. I have not got around to trimming the resistor pins and probably won't bother as it is a prototype at this stage. Since putting the 10k pull-up resistor on it readings have  been consistently accurate (95% as a guess) and not wildly variant as it was before ie temperature showing 120 centigrade. The nano can't adequately supply so many relays and sensors when connected over usb hence the power supply module as the voltage drops to 3.7 which is not enough for the 433mhz receiver to function. The DHT11 does not seem to be affected by the voltage at all. All parts were bought at banggood.com, cheap, quality and fast delivery (relatively by chinese standards). The whole lot in the shots including the nano cost £12.50. The relays can be controlled by the sensors, the rtc  or over the internet using lightwaverf.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on May 06, 2014, 09:07 pm
With 4 relay's you definitely need an additional power supply!  in fact even with one you need to have it.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Reavstone on May 29, 2014, 10:03 pm
Hello where can I download this library?

Thanks.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on May 30, 2014, 08:48 pm
some explanations - http://playground.arduino.cc/Main/DHTLib -
latest code - https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib -
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Reavstone on May 30, 2014, 11:25 pm
I was reading that but I dont seem to find the "download link" for the library, normally on the other libraries I have, I downloaded them.
can you please help me?
What to I need to do in order to have this library?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on May 31, 2014, 12:30 pm
There is one download link for all my libraries on github (up a few levels)
Better learn to work with git to keep up to date with the latest versiob

Or find attached the DHT part only 1.0.9 version.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 01, 2014, 10:42 am
Major update of the DHT library to version 0.1.10

+ improved the WAKEUPSIGNAL
    - 20 -> 18 milliseconds for the DHT11
    - 20 -> 1 millisecond for DHT21 / 22   
    this greatly reduces the blocking fetch from 25 -> 6 milliseconds  ( NOT for the DHT11 )

+ improved the TIMEOUT calculation to fail faster in case of time out
   (tested with no sensor connected to UNO)
   - version 0.1.09 - timeout took ~70.4  milliseconds
   - version 0.1.10 - DHT11 timeout takes ~20.1 milliseconds
   - version 0.1.10 - DHT22 timeout takes ~3.1 milliseconds
      partly of course because the wakeup for the DHT22 is  shorter!

+ some small coding style improvements.

links:
- http://playground.arduino.cc//Main/DHTLib -
- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib - (code only)

As always comments and remarks are welcome.

Please let me know if the new timings has become too critical!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 02, 2014, 08:57 pm
FYI
latest version  0.1.10  confirmed to work on
- UNO, MEGA2560, DUE
- Digistump Digix (84 MHz) - without a level shifter ! using the level shifter caused missing bits or time outs.

Code: (output DUE test) [Select]

DHT TEST PROGRAM
LIBRARY VERSION: 0.1.11

Type, status, Humidity (%), Temperature (C) Time (us)
DHT22, OK, 55.2, 21.0, 4705
DHT22, OK, 55.0, 21.0, 4406
DHT22, OK, 54.8, 21.0, 4315
DHT22, OK, 54.6, 20.9, 4361
DHT22, OK, 54.5, 21.0, 4360
DHT22, OK, 54.5, 21.0, 4364
DHT22, OK, 54.5, 21.0, 4367
DHT22, Time out error, -999.0, -999.0, 2640
DHT22, OK, 54.8, 21.0, 4309
DHT22, OK, 55.7, 21.0, 4216
DHT22, OK, 55.6, 21.0, 4108
...

Note the fetch time ~4.4 millis and a timeout  ~2.7 millis.

Note the 0.1.11 version is functional identical to 0.1.10 (not released)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Clemens on Jun 10, 2014, 04:58 pm
Is this lib also usable for the DHT33 ?

I found an interesting comparison of different temperature sensors: DHT11, DHT22, DHT33, DS18x20, TMP36, Thermistor 
http://playground.boxtec.ch/doku.php/sensors/temp-hum_sensors_compared

The authors point to your lib, Rob, and write "for all DHT sensors". They say also the DHT33 has a build in DS18B20 but I don't know if they uses a DS18B20-lib for reading DHT33's  temperature or your DHT33-lib for temperature and humidity.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 10, 2014, 08:00 pm
Thanks for the link, indeed very interesting!

I am not familiar with the DHT33, do you have a link to a datasheet?
Then I can check if the data format is compatible with the DHT11-21-22 .
If so I can add it to the library,
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 10, 2014, 08:13 pm
found datasheet for the DHT33 aka RHT04

- http://sensorguys.com/wp-content/uploads/2014/05/Digital-humidity-and-temperature-sensor-RHT04.pdf -

The OEM is here - http://www.humiditycn.com/ -

Handshake is similar to the DHT22 so you should be able to use the DHT33 (RHT04) by using the DHT22 calls.

nevertheless as it is a separate type I will update the library this week (if time permits)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 10, 2014, 08:49 pm
There also exist a DHT44  - http://shop.boxtec.ch/digital-humidity-temperature-sensor-dht44-rht05-p-40846.html -

According to the site the DHTlib does works with it....  Time to rethink the library ...


Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Clemens on Jun 11, 2014, 03:32 pm
Thanks, Rob, to catch this also. Indeed it seems they have tested both, the
DHT33 and the DHT44 with your lib, for the last one they write expicitally "The DHT44 is fully compatible with the Arduini library linked below." Nice job to write working code for a pice you do not know that it exists! ;-)

There is also a dicussion about power saving techniques and the DS18B20 on https://lowpowerlab.com/forum/index.php/topic,219.msg1092.html#msg1092. Because the DHTxx-lib is working for the  DHT33, which has a DS18B20 built in the discussion could be interesting her also. About power saving--and using a power saving lib like LowPower http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/ or Narcoleptic https://code.google.com/p/narcoleptic/ -- you can read in the linked posting

Quote
For example, be sure to put the ?C back to sleep while it waits the 750ms needed for the DS18B20s to do their 12-bit conversion, and make sure the DS18B20s all convert at the same time to minimise the number of times the ?C has to wake-up.


Seems that you hitting the 750 ms massively with your lib. Or is "fetch time" and "timeout" an other concept than the "conversion time"? Your can read often about the 750 ms, but it is perhaps a conservative rough estimate or could you find any hinf for this in any datasheet?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 11, 2014, 07:50 pm
Quote
Seems that you hitting the 750 ms massively with your lib. Or is "fetch time" and "timeout" an other concept than the "conversion time"? Your can read often about the 750 ms, but it is perhaps a conservative rough estimate or could you find any hinf for this in any datasheet?


That are typically things to find out when investigating such a sensor.

<warning assumptions ahead>

the DHT33 uses a 12 bit DS18B20 (needs 750 ms) but can be read by the DHTlib (~25 ms or even ~5ms),
how can one implement this:
1) keep on reading the DS18B20 sensor and return the last valid value as DHTxx  (not power efficient but fast)
2) the sensor starts a new DS18B20 read after the last value has been fetched (fast but the returned value might be outdated)
3) the DS18B20 is read when the DHT is asked for => a delay is needed.

So only an elaborate test will learn how the library could behave. Especially the last update of the lib which optimizes timing might be critical for the DS18 based sensors. We'll see.

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 11, 2014, 08:25 pm

Thanks, Rob, to catch this also. Indeed it seems they have tested both, the
DHT33 and the DHT44 with your lib, for the last one they write expicitally "The DHT44 is fully compatible with the Arduini library linked below." Nice job to write working code for a pice you do not know that it exists! ;-)


Yesterday I contacted the people of - http://shop.boxtec.ch/temperature-c-39_71.html - and I just got an answer.

We are going to do additional testing for the DHT33 and DHT44 to optimize the support for these two "newbies" in the DHTlib.
So expect a new version of the DHTlib in 4-6 weeks (best guess).
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 19, 2014, 11:43 pm
Yesterday I got a DHT33 and a DHT44 from boxtec.ch  (thank you !) to test them and add support in the DHTlib. The sensors are also known as the RHT04 and RHT05.

The DHT33 just looks like the DHT22 from the outside, but where my DHT22 is white this one is grey. So far I found no difference while testing but as the DHT33 is DS18B20 based internally it might be more accurate. See the comparison paper mention above by Clemens.

The DHT44 is from the outside a quite different sensor. It includes  a wire 40 cm (1.3 ft) and two mounting options (one see picture below )
(http://cdn.boxtec.ch/images/47071.jpg)
image courtesy boxtec.ch

First tests show both the sensors work very well with the latest version of the library, with the optimized wakeup timing.
So integrating them is not a hard job - to be released end next week I hope - but I have to think about the footprint of the lib.

As there are 4 sensors { 21, 22, 33, 44 } that work with identical code, and one that is different { 11 } So I want to make a generic DHT.read(pin) function, and still support the read11() read22() read21() methods. Probably add read33() and read44() for completeness. As the compiler only include the methods actually used this should not be a problem.

Work to be done ;)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 26, 2014, 09:10 pm
Major update of the DHT library to version 0.1.13

Version 0.1.11 and 0.1.12 are development versions that are not archived.

+ added support for DHT33
+ added support for DHT44
+ added test sketches
+ refactored codestyle + footprint + interface (still backwards compatible)

links:
- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib - (code only)

Note: playground version is not updated...

As always comments and remarks are welcome.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 29, 2014, 02:31 pm
The playground is now also updated to the 0.1.13 version.
Note: the 0.1.11 and 0.1.12 version are not released (development versions)

Confirmed to work, also for negative temperatures (bug introduced in 0.1.12)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: facundoo on Jun 29, 2014, 03:40 pm
I have a problem with DHT22.
I have a DHT11 and DHT22, when I connect the circuit starts well DHT11, but DHT22 shows 0 Temp and 0 Humedity.
Only if I connect to the PC and ask the Arduino software that shows what you hear by the USB port, there begins Mega2560 and DHT22 begins to read well.

What I can do to solve this problem start?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 29, 2014, 06:56 pm
Quote
What I can do to solve this problem start?

Some questions:

How do you power the Arduino if not connected to the PC?
Are there besides DHT11/22 other devices connected?
How are the DHT's connected? which pins?
Which version of the DHT library do you use? Adafruit? my DHT lib?


Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: facundoo on Jun 30, 2014, 04:44 pm
Connected 9v.
DS1302 and LCD TFT
DHT11 in pin 8 and DHT22 in pin 9
DHT-master.rar (Written by Mark Ruys)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: rrjwilson on Sep 02, 2014, 06:24 pm
I'm sure I'm doing something stupid but I've ran out of sensible ideas now  :~

Hardware
Arduino 2560
RHT03
10k resistor
I'm using the adafruit wiring to link a RHT03 (DHT22) to my 2560.


Software
I am using the example code from within the github examples folder apart from the default switch clause will print the chk value also. I have also changed the timeout values within dht.cpp to be different to allow me to see where its failing.

Code: [Select]

while(digitalRead(pin) == LOW)
{
  if (--loopCnt == 0) return -100; //DHTLIB_ERROR_TIMEOUT;
}

loopCnt = DHTLIB_TIMEOUT;
while(digitalRead(pin) == HIGH)
{
  if (--loopCnt == 0) return -101; //DHTLIB_ERROR_TIMEOUT;
}

// READ THE OUTPUT - 40 BITS => 5 BYTES
for (uint8_t i = 40; i != 0; i--)
{
  loopCnt = DHTLIB_TIMEOUT;
  while(digitalRead(pin) == LOW)
  {
    if (--loopCnt == 0) return -102; //DHTLIB_ERROR_TIMEOUT;
  }

  uint32_t t = micros();

  loopCnt = DHTLIB_TIMEOUT;
  while(digitalRead(pin) == HIGH)
  {
    if (--loopCnt == 0) return -103; //DHTLIB_ERROR_TIMEOUT;
  }

  if ((micros() - t) > 40)
  {
    bits[idx] |= mask;
  }
  mask >>= 1;
  if (mask == 0)   // next byte?
  {
    mask = 128;
    idx++;
  }
}


I am never receiving a reading only timeout values and the timeout values fluctuate pattern wise.
I receive two patterns of four readings but these patterns do not have an occurrence pattern.
Quote
Unknown -101 -999.0% -999.0*C
Unknown -101 -999.0% -999.0*C
Unknown -101 -999.0% -999.0*C
Unknown -102 -999.0% -999.0*C

Quote
Unknown -101 -999.0% -999.0*C
Unknown -101 -999.0% -999.0*C
Unknown -102 -999.0% -999.0*C
Unknown -102 -999.0% -999.0*C


I'm going to get the multimeter out now and see if I can see anything weird but I'm just losing hope now.
Any ideas what could be inhibiting?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Sep 02, 2014, 07:14 pm
how long are your wires?

The 5V pin of the DHT22 should be connected directly to 5V  not through a 10K

only the data line needs a 10K pullup (if lines are > 1 meter a 4K7 could be used.)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: rrjwilson on Sep 03, 2014, 10:25 am
Solved it within a few minutes of getting out the multimeter  :)
Thank you Rob

You were right to suspect power with the leads and such.
Leads are 10cm from power pins to breadboard then another 10cm to DHT22.
10k is connected between power line and signal only.
The arduino is running over USB which I thought maybe a problem but it is producing 5.3V directly (not sure how that works  :smiley-eek: ). I've  found that my breadboard has rather high resistance along its power tracks (~10M) so I've moved the wires on the breadboard to be closer together rather than trust the rail to provide power properly.

So if DHTLib is producing nothing but timeout errors and you know everything is connected right and you are using an example sketch CHECK voltage at the chip.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: rsl_ on Sep 25, 2014, 10:22 pm
Hi everyone.

I've just improved this great library.
1. Arduino port working on "open collector" mode (high level made only with resistor).
2. Using internal ATMega pull-up resistor instead of external.

So now you don't need resistor and level shifter.
I've checked code with DHT11 and Arduino nano, please check with other devices.

Changed file: Arduino\libraries\DHTlib\dht.cpp

Code: [Select]

//
//    FILE: dht.cpp
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.13
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
//     URL: http://arduino.cc/playground/Main/DHTLib
//
// HISTORY:
// 0.1.13 fix negative temperature
// 0.1.12 support DHT33 and DHT44 initial version
// 0.1.11 renamed DHTLIB_TIMEOUT
// 0.1.10 optimized faster WAKEUP + TIMEOUT
// 0.1.09 optimize size: timeout check + use of mask
// 0.1.08 added formula for timeout based upon clockspeed
// 0.1.07 added support for DHT21
// 0.1.06 minimize footprint (2012-12-27)
// 0.1.05 fixed negative temperature bug (thanks to Roseman)
// 0.1.04 improved readability of code using DHTLIB_OK in code
// 0.1.03 added error values for temp and humidity when read failed
// 0.1.02 added error codes
// 0.1.01 added support for Arduino 1.0, fixed typos (31/12/2011)
// 0.1.0 by Rob Tillaart (01/04/2011)
//
// inspired by DHT11 library
//
// Released to the public domain
//

#include "dht.h"

/////////////////////////////////////////////////////
//
// PUBLIC
//

// return values:
// DHTLIB_OK
// DHTLIB_ERROR_CHECKSUM
// DHTLIB_ERROR_TIMEOUT
int dht::read11(uint8_t pin)
{
    // READ VALUES
    int rv = _readSensor(pin, DHTLIB_DHT11_WAKEUP);
    if (rv != DHTLIB_OK)
    {
        humidity    = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
        temperature = DHTLIB_INVALID_VALUE; // invalid value
        return rv;
    }

    // CONVERT AND STORE
    humidity    = bits[0];  // bits[1] == 0;
    temperature = bits[2];  // bits[3] == 0;

    // TEST CHECKSUM
    // bits[1] && bits[3] both 0
    uint8_t sum = bits[0] + bits[2];
    if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;

    return DHTLIB_OK;
}


// return values:
// DHTLIB_OK
// DHTLIB_ERROR_CHECKSUM
// DHTLIB_ERROR_TIMEOUT
int dht::read(uint8_t pin)
{
    // READ VALUES
    int rv = _readSensor(pin, DHTLIB_DHT_WAKEUP);
    if (rv != DHTLIB_OK)
    {
        humidity    = DHTLIB_INVALID_VALUE;  // invalid value, or is NaN prefered?
        temperature = DHTLIB_INVALID_VALUE;  // invalid value
        return rv; // propagate error value
    }

    // CONVERT AND STORE
    humidity = word(bits[0], bits[1]) * 0.1;
    temperature = word(bits[2] & 0x7F, bits[3]) * 0.1;
    if (bits[2] & 0x80)  // negative temperature
    {
        temperature = -temperature;
    }

    // TEST CHECKSUM
    uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];
    if (bits[4] != sum)
    {
        return DHTLIB_ERROR_CHECKSUM;
    }
    return DHTLIB_OK;
}

/////////////////////////////////////////////////////
//
// PRIVATE
//

// return values:
// DHTLIB_OK
// DHTLIB_ERROR_TIMEOUT
int dht::_readSensor(uint8_t pin, uint8_t wakeupDelay)
{
    // INIT BUFFERVAR TO RECEIVE DATA
    uint8_t mask = 128;
    uint8_t idx = 0;

    // EMPTY BUFFER
    for (uint8_t i = 0; i < 5; i++) bits[i] = 0;

    // REQUEST SAMPLE
    digitalWrite(pin, LOW);
    pinMode(pin, OUTPUT);
    delay(wakeupDelay);
    pinMode(pin, INPUT);
    digitalWrite(pin, HIGH);
    delayMicroseconds(40);

    // GET ACKNOWLEDGE or TIMEOUT
    uint16_t loopCnt = DHTLIB_TIMEOUT;
    while(digitalRead(pin) == LOW)
    {
        if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;
    }

    loopCnt = DHTLIB_TIMEOUT;
    while(digitalRead(pin) == HIGH)
    {
        if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;
    }

    // READ THE OUTPUT - 40 BITS => 5 BYTES
    for (uint8_t i = 40; i != 0; i--)
    {
        loopCnt = DHTLIB_TIMEOUT;
        while(digitalRead(pin) == LOW)
        {
            if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;
        }

        uint32_t t = micros();

        loopCnt = DHTLIB_TIMEOUT;
        while(digitalRead(pin) == HIGH)
        {
            if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;
        }

        if ((micros() - t) > 40)
        {
            bits[idx] |= mask;
        }
        mask >>= 1;
        if (mask == 0)   // next byte?
        {
            mask = 128;
            idx++;
        }
    }

    return DHTLIB_OK;
}
//
// END OF FILE
//
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Sep 25, 2014, 10:38 pm

interesting idea

    pinMode(pin, INPUT);
    digitalWrite(pin, HIGH);

could be

    pinMode(pin, INPUT_PULLUP);  // does in fact the same

- http://arduino.cc/en/Tutorial/InputPullupSerial -

Problem could be the length of the wire, some people use 20 or 50 mtr cable to connect a DHT and adjust the resistor to get a "sharp edge" in the signal. With the internal pullup it is not possible to adjust for the cable length.

So for now, I will not add it to the library as it restricts its usage.
(BTW an extra digitalWrite() statement ==> need to adjust timing of delayMicroseconds)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 04, 2014, 06:19 pm
FYI
I'm working on a new version - 0.2.00 - of my DHT library.   

The list of changes under investigation:
- breaking interface, read() functions return an int8_t (char) instead of int  ==> smaller footprint
- DHTLIB_INVALID_VALUE changed to -127  (was -999) to fit in int8_t
- uses lower level port manipulation instead of digitalRead(). ==> faster ==> support lower MHz possible
- removed micros() from code ==> smaller footprint  (Thanks 68tjs for this idea)

wrt footprint: test-sketch dropped from 5642 bytes (0.1.13)  to 5484 bytes (0.2.00) = -158 bytes
runtime is not faster, it should use a few bytes less RAM (not measured)

I am also thinking of one class per sensor implementation (now it is one class for many sensors) because that will allow every sensor to have an offset for both temperature and humidity. ==> calibration. On the other hand it would increase the code and not everyone needs the offset. Opinions?


I will make a 0.1.14 soon that includes all except the breaking interface.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: 68tjs on Oct 04, 2014, 10:17 pm
I agree for one class per sensor

DHT11 has too bad performances versus DHT22 .
DHT22 cost only more 2$ !!!!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 05, 2014, 10:53 am
Update of the DHT library to version 0.1.14

+ replace digital read with faster (~3x) code
   => more robust low MHz machines.
  => reduced footprint - test sketch from 5462 (0.1.13) to 5552 (0.1.14)

links:
- http://playground.arduino.cc//Main/DHTLib -
- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib - (code only)

As always comments and remarks are welcome.


update: 0.1.15 is under test
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: 68tjs on Oct 05, 2014, 04:41 pm
I think we don't have the same reading of the datasheet about Tgo.
For me, perhaps I mistake,  Tgo is not a constant time, it depends of batch fab and can be comprise between 20 µs and 200µs with "a center value" of 30µs !
So with a constant delay of 40 µS :
- If actual Tgo = 100µs, even if the D.U.T. is in his specs, you will have TIMEOUT or CHECK_SUM_ERROR.
- If actual Tgo is 20µs you will loss 20µs (25 %) in detection of the LOW binary element in acknowledge phase.

Personally I replace
Quote
delay(40);

by:
Quote
while(digitalRead(pin) == HIGH )  { /*do nothing*/ }

With this code I am absolutely no dependent  of individual sensor's wakeup time.

The datasheet are available at :
http://forum.arduino.cc/index.php?topic=269216.msg1906338#msg1906338
DHT11 = AM2301
DHT22 = AM2302

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 05, 2014, 05:26 pm
You might be right, although I do not recall problems in this phase.

Quote
- If actual Tgo = 100µs, even if the D.U.T. is in his specs, you will have TIMEOUT or CHECK_SUM_ERROR.

That would be a TIMEOUT in detecting the LOW

Quote
- If actual Tgo is 20µs you will loss 20µs (25 %) in detection of the LOW binary element in acknowledge phase.

right but I do not consider this a problem as I only detect a LOW phase shorter than TIMEOUT followed by a HIGH shorter than TIMEOUT. I do not measure their time.

I am currently testing the 0.1.15 version of the library, which removed the use of micros and uses a comparison between loopCountLOW and loopCountHIGH. So far this seems less stable than the version using micros (0.1.14).   4 errors in 9000 reads versus 0 errors in 10000 reads; very few but too much.

I will add your code proposal to the lib under test to see if it improves behaviour (or size). Will take some time
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: 68tjs on Oct 05, 2014, 07:15 pm
Maybe I'm warped by 40 years of special design in electronics where it was a requirement to optimize designs.
I caught the optimization virus  and now that I'm retired I can not prevent myself from continue :smiley-mr-green: .
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 05, 2014, 08:02 pm
Your proposed code seems to work as well as the hard coded 40 uSec delay.
Code size shrunk 6 bytes, so if nothing special happens it will probably stay in the lib.

However the loopCounter compare  still seems less reliable than working with micros() .
In my current test run  : 1 CRC error in 3800 reads (not bad but too much)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: 68tjs on Oct 05, 2014, 08:32 pm

However the loopCounter compare  still seems less reliable than working with micros() .

With what condition in the while:  digitalRead or your new method.
With digitalRead there is no margin.  So detections of "Short One" is very delicate.
During  "Short One" detection  the loop is traversed only 2 or 3 times. With only 2 or 3 turn it is possible to make false measures.

I  have great hope in your new method for direct manipulating bit.
It will be the main improvement.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 05, 2014, 08:35 pm
sneak preview from the 0.1.15beta version
Code: [Select]

// return values:
// DHTLIB_OK
// DHTLIB_ERROR_TIMEOUT
int dht::_readSensor(uint8_t pin, uint8_t wakeupDelay)
{
    // INIT BUFFERVAR TO RECEIVE DATA
    uint8_t mask = 128;
    uint8_t idx = 0;

    // replace digitalRead() with Direct Port Reads.
    // reduces footprint ~100 bytes => portability issue?
    // direct port read is about 3x faster
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
    volatile uint8_t *PIR = portInputRegister(port);

    // EMPTY BUFFER
    for (uint8_t i = 0; i < 5; i++) bits[i] = 0;

    // REQUEST SAMPLE
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW); // T-be
    delay(wakeupDelay);
    digitalWrite(pin, HIGH); // T-go
    // delayMicroseconds(40);
    pinMode(pin, INPUT);
    uint16_t loopCntHIGH = DHTLIB_TIMEOUT*2;  // 200uSec max
    while ((*PIR & bit) != LOW )
    {
        if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT;
    }
   
    // GET ACKNOWLEDGE or TIMEOUT
    uint16_t loopCntLOW = DHTLIB_TIMEOUT;
    while ((*PIR & bit) == LOW )  // T-rel
    {
        if (--loopCntLOW == 0) return DHTLIB_ERROR_TIMEOUT;
    }

    loopCntHIGH = DHTLIB_TIMEOUT;
    while ((*PIR & bit) != LOW )  // T-reh
    {
        if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT;
    }

    // READ THE OUTPUT - 40 BITS => 5 BYTES
    for (uint8_t i = 40; i != 0; i--)
    {
        loopCntLOW = DHTLIB_TIMEOUT;
        while ((*PIR & bit) == LOW )
        {
            if (--loopCntLOW == 0) return DHTLIB_ERROR_TIMEOUT;
        }

        loopCntHIGH = DHTLIB_TIMEOUT;
        while ((*PIR & bit) != LOW )
        {
            if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT;
        }

        if (loopCntLOW >= loopCntHIGH) // inverted as we count down...
        {
            bits[idx] |= mask;
        }
        mask >>= 1;
        if (mask == 0)   // next byte
        {
            mask = 128;
            idx++;
        }
    }
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);

    return DHTLIB_OK;
}
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 05, 2014, 08:57 pm
Note the actions after the 2 loops
Code: [Select]
        if (loopCntLOW >= loopCntHIGH) // inverted as we count down...
        {
            bits[idx] |= mask;
        }
        mask >>= 1;
        if (mask == 0)   // next byte
        {
            mask = 128;
            idx++;
        }

are "subtracted" from the loopCntLOW loops resulting in "closer" values.

A possible solution is to detect that loopCntHIGH is equal to loopCntLOW while in the high loop. Than one could start the setting of the 1 bit already. Drawback is that the state is less defined, where to continue.

main difference:
The loopCount compare is a relative test and the micros() compare is an absolute test of only the HIGH part.

Another solution is to see what absolute values loopCountHIGH has, it should have a bimodal distribution .
Discriminating between the  26uSec loops and the 70uSec loops is easier than discriminating between 50 and 70uSec

to be continued.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 05, 2014, 09:45 pm
Quote
Another solution is to see what absolute values loopCountHIGH has, it should have a bimodal distribution .
Discriminating between the  26uSec loops (==ZERO) and the 70uSec loops (==ONE)  is easier than discriminating between 50 and 70uSec


added some print statements : (short test 200 reads)
The HIGH period in terms of loops have a variation of ~10
ZERO = 22 - 30
ONE = 82 - 89

The low period varies between 46 - 54

TIMEOUT = 400 ===>  TIMEOUT/9 == 45 might be a good divider...   (but not today ;)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 07, 2014, 12:29 pm
Some experiments and insights further:

clocking in bits with micros()
- When using micros() there are 2 micros() calls needed and a 32 bits compare. 16 an 8 Mhz have proven to work reliable. (16Mhz experiment 20K reads -> 0 errors) At clock speeds of 4 MHz and lower the duration of the calls to micros() add up to approx the time of a bit, especially if additional interrupts take time. Therefore for 4Mhz and lower the micros() way will not work.
Extrapolated duration of call to micros()
16 MHz - 3.5 uS
8MHz - 7 uS
4MHz - 14 uS  => 2 calls ~ 28uSec ~~> ZERO HIGH time


clocking in bits with loop counts
- compare loop counts is simpler and faster (only 16 bit compare) thus more suitable for lower [sub 8Mhz] clock speeds. I have no experimental confirmation yet.
- loop counts show quite some variation (see post above) and are therefore less reliable (16 Mhz experiment gave 4 errors in 10K reads)  An interrupt (e.g. Serial) during HIGH period will decrease the HIGH counter which can result in recognizing a ONE as a ZERO. An interrupt during LOW period will decrease LOW counter which can result in recognizing a ZERO as a ONE. At lower clock speeds the effects of interrupts will increase as they are processed slower.
- comparing the loop count of the high period against a fixed threshold can fail for the same reason, however only if the interrupt is in the high period so chance is 2x lower but still.  (16 Mhz experiment gave 0 errors in 10K reads). This threshold can be calculated during the first part of the readSensor function. [Threshold == acknowledge loop/2 ]

t.b.c.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 08, 2014, 05:21 pm
Update of the DHT library to version 0.1.15

+ reduced # micros calls 2->1 in inner loop. => footprint -18
  detection of the zero/one is now done by measuring the length of LOW+HIGH period, => reuse a time stamp
+ improved wait for acknowledge - (thanks to 68tjs)
+ merged two loopCounters into one again.
+ dht22_test sketch displays some statistics every 20 reads (used to run 10000 reads with zero errors)


links:
- http://playground.arduino.cc//Main/DHTLib - (version not updated, but as backgrounder useful)
- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib - (code only)


As always comments and remarks are welcome.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 08, 2014, 05:27 pm
footnote for the 0.1.15 version
Did quite some testing last few days with the idea (originally from 68tjs) of comparing LOW period and HIGH period of every bit. This resulted in additional testing with a fixed threshold and the HIGH period only. Smaller footprints, but also a few errors (5 in 10000 reads, not bad).

Then I suddenly got the insight that if I measured the whole bit period LOW+HIGH (about 80 or 130 uSec) - and just wait for the falling edge - I could reuse one call to micros(). With hindsight quite obvious. That insight proved to be very stable (10000++ reads, zero fails) and with the insights of previous posts I expect it to work reliable on 8 Mhz and even on 4 Mhz.

@16Mhz the inner loop runs at least 70 times, so at 4Mhz the inner loop would run at least 17 times, (precondition no interrupts!!). So even 2 and 1 Mhz with no interrupts might be possible. unfortunately no way to verify that quickly.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 08, 2014, 11:22 pm
some first tests at lower clock speeds  (
used trick described here - http://forum.arduino.cc/index.php?topic=271364.msg1913233#msg1913233 -

@8MHz  -> 98%
TOT   OK   CRC   TO   UNK
100   98   2   0   0


@4 Mhz -> 82%
TOT   OK   CRC   TO   UNK
100   82   12   6   0


@2MHz -> 3%
TOT   OK   CRC   TO   UNK
100   3   9   88   0


@1MHz -> 0%

TOT   OK   CRC   TO   UNK
100   0   0   100   0


So there is definitely room for improvement ;)

Note for 4, 2 and 1 Mhz I have tweaked the delayMicroseconds()  implementation so it compiled, not yet tuned.

update:
@4Mhz is already critical, other serial speed => drops result ~50%    (seems that higher baud rate scores better)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Clemens on Oct 10, 2014, 02:33 pm
Hi Rob, again many thanks for your excellent work also on this lib!

A question about temperature: As we know the DHT33 has an integrated DS18B20 for temperature measure http://shop.boxtec.ch/digital-humiditytemperature-sensor-dht33-rht04-p-40541.html. 

I like to use the DHT33 and about 5 DS18B20 only sensors in a project. So my question is: Do I have to use two different libs one for the DHT33 and one for the DS18B20s or can I use the DHTxx lib for reading the single DS18B20 sensors also?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 10, 2014, 02:52 pm

Hi Rob, again many thanks for your excellent work also on this lib!

Welcome, try to continuous improve it.

Quote
A question about temperature: As we know the DHT33 has an integrated DS18B20 for temperature measure http://shop.boxtec.ch/digital-humiditytemperature-sensor-dht33-rht04-p-40541.html. 

I like to use the DHT33 and about 5 DS18B20 only sensors in a project. So my question is: Do I have to use two different libs one for the DHT33 and one for the DS18B20s or can I use the DHTxx lib for reading the single DS18B20 sensors also?

Yes you need two libraries, although both use a so called "1-wire" protocol, they are as incompatible as can be ;)

The DS18 series have an internal address, so you can have multiple sensors on 1-Wire. The DS18 have more features in terms of alarm and parasite mode. The DHT series have no such internal address or parasite mode and in fact the DHT just dumps a stream of bits where the DS is register oriented.

I have a DHT33 for testing purposes (>250K reads already) and it works very well.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 15, 2014, 08:23 am
Update of the DHT library to version 0.1.17  (0.1.16 was an intermediate one)

+ replaced micros() with adaptive loopcount
+ removed DHTLIB_INVALID_VALUE (user should decide if value is usable)
+ more detailed errors per phase of handshake
+ added DHTLIB_ERROR_CONNECT
+ added DHTLIB_ERROR_ACK_L  DHTLIB_ERROR_ACK_H

- version 0.1.14 and up are not compatible with pre 1.0 Arduino
+ added fix for pre 1.0 (not tested)


links:
- http://playground.arduino.cc//Main/DHTLib - (version not updated, but as backgrounder useful)
- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib - (code only)


As always comments and remarks are welcome.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 15, 2014, 08:43 am
footnote for the 0.1.17 version
There are some bits that are always zero in the protocol. These are the first bits of the humidity. The current (0.1.17) implementation use these to learn the loop-count (duration) of a zero of the individual sensor. This count is used to discriminate between zero's and ones in the rest of the handshake. The robustness for 16Mhz and 8Mhz is almost perfect - see numbers below.  Tested with 4 Mhz and lower but these are not good.

Furthermore most important change in the interface is that DHTLIB_INVALID_VALUE is not used any more. The received bits are converted to temperature /humidity and it is up to the user to determine if the values are good. The reason for this change is that during testing I noticed that time out often occurred on the last bit(s) of the CRC, resulting good values for T&H which were thrown away. That does not happen any more. The read() functions still return an error (!=0) if something went wrong so the user should inspect that. In fact the errors now indicate where the handshake went wrong.  

test results:
@16 Mhz zero errors in 16K reads
@8 Mhz seven errors in 10K reads

dht22_test.ino
16000000
LIBRARY VERSION: 0.1.17
...
TOT   OK   CRC   TO   UNK
16000   16000   0   0   0

dht22_test.ino
8000000
LIBRARY VERSION: 0.1.17
...
TOT   OK   CRC   TO   UNK
10000   9993   5   2   0

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 23, 2014, 07:53 pm
updated the examples of the DHTlib on github to handle the recently added errors

DHTLIB_ERROR_CONNECT,
DHTLIB_ERROR_ACK_L 
DHTLIB_ERROR_ACK_H

there is no new code in the lib itself.

- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib - (code only)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: tong67 on Oct 26, 2014, 05:51 pm
I just tried the latest version (1.0.17) with a DHT11. It always reports 0.0 for temperature and humidity.
I checked the 1.0.15 version, some posts back made available as zip file and there the DHT11 reports the correct temperature and humidity. Somewhere in the transition from 1.0.15 to 1.0.17 the support of the DHT11 has broken. The communication between the UNO (board I am using) and the DHT11 is OK. When I remove the communication pin a communication error is reported else OK.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 26, 2014, 06:06 pm
Thanks for the remark, (and to verify that the 0.1.15 version still works).

I noticed this error earlier in another thread. As I do not have a DHT11 at the moment - ordered one last Friday evening - I cannot test it now.

I have analysed the cause, ==>  the "auto tuning" part.
Code: ("dht.cpp snippet") [Select]

            if (i > 34) // first 6 bits are all zero !!
            {
                zeroLoop = min(zeroLoop, loopCount);
                delta = (DHTLIB_TIMEOUT - zeroLoop)/4;
            }


The first 6 bits are all zero for the DHT21,22,33,44 as the 2 bytes go from 0..1000
The DHT11 goes from 0..100 in first byte. That means only the first bit is always zero.

As the code effectively skips the first six bits the value of the humidity gets corrupted for a DHT11 :(

As soon as the DHT11 comes in I will start work on a patch.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: rrjwilson on Oct 27, 2014, 03:56 pm
What does DHTLIB_ERROR_ACK_L actually mean.
I have had three sensors working fine on previous versions of your library but after enlongating the wire connecting the one of the sensors (furthest away ~45cm) returns that error.
Reluctant to unsolder it to check it so wondered if that error has a main cause before I go fiddling.
The other two 40cm and 35cm extensions work fine.

I am open to the idea that I've borked something while soldering but I am pretty competent with an iron.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 27, 2014, 04:18 pm

Quote
What does DHTLIB_ERROR_ACK_L actually mean.
The sensor gives an acknowledge after the wakeup signal. This acknowledge exists of a LOW and HIGH period. If there is a time out during one of these you get one of these errors:

- DHTLIB_ERROR_ACK_L
- DHTLIB_ERROR_ACK_H

in previous version it was just a time out, but I needed to differentiate between time outs during the sending of the data bits and the time out during the initial handshake/wakeup.

For details of the handshake - check datasheet.


Concerning the error:
Did you use pull up resistors with the sensors?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: rrjwilson on Oct 27, 2014, 05:23 pm
I did not.
I shall attempt with the internal ones and report back.
Thank you
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: rrjwilson on Oct 27, 2014, 05:32 pm
Boom! That did it.
Thank you
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 27, 2014, 07:30 pm
the internal ones might be of the wrong 'size'... but the proof is in the pudding test.
The longer the wires the smaller the pull up.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Stocky on Nov 05, 2014, 03:51 am
Hi Rob - I have been using your DHT22 Library with a weather warning device I'm working on ad have had it all working fine on a Duemilanove but have had to move to a Mega1280 for extra space & RAM to add some more features inc logging

Hardware wise I have an anemometer on Digital 2 and the DHT22 on Digital 3 and this worked fine on the Duemilanove but on the MEGA1280 the DHT22 readings go crazy as soon as the anemometer moves!

As far as I can see the interrupts are the same on Digital 2 & 3 on a Mega328 and a Mega1280 based board so I'm not sure whats going on - any pointers?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 05, 2014, 07:21 pm
You do not tell which version you use.  The interrupts seem to disrupt the communication between the DHT and the board.  The last 0.1.17 version is probably less interrupt resistant as it uses relative timing.

Version 0.1.15 uses absolute timing with micros() and is better "resistant" for interrupts.

Attached here - http://forum.arduino.cc/index.php?topic=58531.msg1912859#msg1912859 -

Hope this helps.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Stocky on Nov 05, 2014, 11:33 pm
Sorry was using latest version - I ended up moving the anemometer to another interrupt and that fixed it - weird!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 06, 2014, 07:46 pm
no need to apologize, good to hear it works :)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: danbi on Nov 09, 2014, 05:13 pm
Great library! Keep up the good work.

I have few issues however:

- Why would you make the 'invalid value' 0? How do you measure an 0 degrees temperature then? (it's less of a issue with humidity)

- Do you have an idea why some sensors might be way off. For example, using v14 of the lib (as the current one fails at DHT11), and 2xDHT22 + 3xDHT11 sensors, sitting on the same breadboard, I get:

DHT21, OK, 67.5, 22.7
DHT22, OK, 65.6, 22.7
DHT11, OK, 59.0, 22.0
DHT12, OK, 50.0, 23.0
DHT13, OK, 60.0, 22.0

(sensors names starting with 2 are DHT22, those with 1 are DHT11). Why would they be too far off on humidity, especially one of them? Could this be just a bad sensor that needs to get in trash or should I consider applying some offset correction? Temperature error seems tolerable.
After reading http://www.kandrsmith.org/RJS/Misc/calib_dht22.html I am ... very confused what to think of it all :)

- My application will use long cables (10-30m). What are the risks associated with this? Could the induced noise eventually damage the Arduino or the sensors? At which end is best to put the pull up resistor? At the controller or at the sensor?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 09, 2014, 08:09 pm
Quote
Why would you make the 'invalid value' 0? How do you measure an 0 degrees temperature then? (it's less of a issue with humidity)
The invalid value in 0.1.14 = DHTLIB_INVALID_VALUE = -999

in version 0.1.17 the DHTLIB_INVALID_VALUE is removed as sometimes the values are good and there is only a bit-error in the CRC. So the return value of the read() functions must be checked.

Also note that DHT11 use only integer values. That gives rounding errors by definition:)

Quote
Do you have an idea why some sensors might be way off.
Check the datasheets, the DHT sensors are not that accurate (esp the DHT11).
See detailed tests here - http://playground.boxtec.ch/doku.php/sensors/temp-hum_sensors_compared -

Quote
My application will use long cables (10-30m). What are the risks associated with this?
The signal is digital so it either fails or succeeds, it will not drift. You might need to use a smaller pull up resistor. I always put them near Arduino as there 5Volt == 5Volt.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Stocky on Nov 13, 2014, 07:27 am
Question for Rob - have you had any experience with the DHT series sensors and very low RH values?
I seem to have an issue with RH values less than 15% being very very inaccurate and just looking to see what other users have found!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 13, 2014, 08:03 pm
I've used the DHT's mostly at room temperature (say 5-40 degrees) and humidity between 35-75 %
Once I did use it in a room about 60-70 degrees but I do not recall what humidity was.

never did look at the humidity extremes.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Stocky on Nov 14, 2014, 01:55 am
Thanks Rob - down here in Australia Summer daytime RH can get down to 5% (or less!) and I'm having trouble being able to measure it which is an issue for my application :-/

Anyone out there got any experience with the DHT sensors at these ultra low RH values?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 16, 2014, 01:50 pm

I have finally found time to work on a fix for the DHT11 sensor in the DHTlib.
A beta version of the 0.1.18 lib is attached.
 
Could anyone with a DHT11 on UNO/MEGA confirm it works?
Note It won't work on any ARM/DUE.



Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 25, 2014, 09:39 pm
Finally got my new DHT11 and some time to test the 0.1.18(beta) version to see if the fix works.
And I'm happy to announce it does :)

So I pushed the 0.1.18 version to - https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib -


Please note that 0.1.18 does not work on ARM processors (e.g. Due),  please use the 0.1.13 version.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: kiloWATT on Dec 29, 2014, 01:15 pm
Hey,

I've been playing around with DHT11 sensor from ebay, and found that on all of the libraries that i've tested, sensor reads about 5 C high..

i bought 5 of those sensors on the same order and all of them seems to have a similar offset. I can't messure if the humidity has offset too because i don't have a refrence humidity meter to hand.

also if i breath on sensor humidity shoots up to about 63% and then shows checksum error..

have anyone had similar problems?

arduino Nano at 16MHz, stable 5V power supply, 10k signal pull-up, 5cm from the board, along side there is DS18B20 (it works just fine)(no change if i disconnect it).

sorry for my english and thanks.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 29, 2014, 05:42 pm
Hi KiloWatt

The DHT11 is not an accurate sensor and you can compensate for the temperature error in software quite easily. HUmidity is another story...

Check this comparison - http://playground.boxtec.ch/doku.php/sensors/temp-hum_sensors_compared -

which version of the library are you using?


Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: flagtrax on Jan 09, 2015, 08:22 pm
Hi Rob,
I am fairly new to arduino, so my apologies for my ignorance. For my second "serious" project, I want to be able to monitor temperatures in a crawl space, and activate a heat tape in the event of freeze conditions. To that end I acquired a DHT21
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: flagtrax on Jan 09, 2015, 08:36 pm
Hi Rob,
Great work! I am fairly new to arduino, so my apologies for my ignorance. For my second "serious" project, I want to be able to monitor temperatures in a crawl space, and activate a heat tape in the event of freeze conditions. To that end I acquired a DHT21 sensor. Looking at the documentation am I correct thinking it is similar to the DHT22 other than pin out? I am assuming that your 0.1.18 library covers this sensor as well, so I downloaded from the link here. However when I tried to import it to the IDE I get an error that that seems to deal with naming conventions. So I renamed it and it presumably loaded, but if I try to include it into a sketch, nothing is there. I'm quite sure I'm doing something wrong, but not sure what. Working this project in stages, at this point I simply want to read data from the sensor, and display it on a 1602 display, any steering in this direction would be greatly appreciated.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 09, 2015, 09:24 pm
DHT21 and 22 are interface identical, you're right on that.

the library folder should be named dht  with in it dht.cpp and dht.h and an examples subfolder
then it should work...



Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: flagtrax on Jan 10, 2015, 08:02 am
Thanks for the reply Rob, forgive my brain slip. I did get the library installed, uploaded to my UNO, and the test sketch ran well. I temporarily "rem'd" out the items for the DHT11, and 22, so I could simply read my DHT21 for testing purposes. Information flowed fine to the serial monitor. Although I was interested to see the readings wander a bit. I understand that sensor is not extremely precise, but I'd have thought if it were +or- .X it would stay at that point. Instead it would read, for example 71.2.....71.0....71.0....71.2. Curious.

I wanted then to display the data on a 1602 type display, rather than via the serial monitor. I used the lcd library, and combined it with what I needed to read the DHT21. There was more characters than would fit or needed on the display, so I "rem'd" a few out again, :smiley-red: leaving just the humidity and temp data sent to the display. Interestingly the Humidity displayed with 10 decimal points ie: 8.6000993810 while the temperature displayed as 69.4 ( I converted the output to F before the lcd.print function) with only one decimal. I'm not sure I get why that is happening. Ideally one decimal on both would be better. Any suggestions always appreciated.
Thanks again for great work and assistance.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 10, 2015, 11:47 am
with respect to the accuracy, read the datasheet.
You can do some averaging
- http://playground.arduino.cc/Main/Statistics
- http://playground.arduino.cc/Main/RunningAverage

Post your sketch and I'll have a look
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: flagtrax on Jan 10, 2015, 05:47 pm
Thanks Rob, I think I found it. First part was an oversite on my part. Both readings were going out 10 decimal places. Since the temperature was sent to the display second, it merely truncated. Secondly, to send data to the display I used the statement "lcd.print (DHT.temperature, DEC). When I remove the optional 2nd parameter (DEC) it only displays 2 decimal places. Since this is only a testing/learning phase I wasn't too concerned with the mathmatics of rounding etc. So at this point this works out fine. Thanks again for having a newbie's back  :P . I hope at some point I'll have learned enough to help as many people as you have. Cheers!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: flagtrax on Jan 13, 2015, 12:47 am
Hi again Rob,
I am happy to say I have a working prototype for my project. Using your library, which probably has more than I need being it supports 3 different sensors, I Rem'd out some, and deleted some statements in the main body of the sketch and changed serial outputs to the 16X2 lcd display. All worked fine. I even added a long 3 conductor cable to the sensor and placed out doors for testing. Sure enough when it cooled down to 0C the control relay operated  :D . While hooking up my "extended" wiring, I left the sketch running. As i removed and attached each lead to the sensor, it appeared that the last reading was held in DHT.temp. This could be an issue if in practice communications are lost to the sensor and it is not known. I am testing DHT.temperature in an if statement to control the ouput to a relay. If I see it correctly, if a temperature above freezing is read, and the communication is lost the last reading would be held. If temperatures then drop below freezing it would not be "seen" and heat tape would not be activated. Any thoughts on that appreciated. As always thanks for helping us newbies along.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 13, 2015, 07:35 pm
you should check the return value of the read() function.

If it equals DHTLIB_OK  there is a new reading

If it equals DHTLIC_ERROR_CHECKSUM, all bits are read but there are error(s), the temperature/humidity might be right or not. Comparing with a previous value might bring a clue. e.g. you do not expect T or H to drop a large amount between two adjacent readings.

DHTLIB_TIMEOUT: not all bits are read so the values are probably not right but might be right. Here too comparing with a previous value might bring some clue.

DHTLIB_ERROR_CONNECT,  DHTLIB_ERROR_ACK_L and  DHTLIB_ERROR_ACK_H: no new values read.



Code: (snippet) [Select]
  int chk = DHT.read22(DHT22_PIN);
  switch (chk)
  {
    case DHTLIB_OK: 
Serial.print("OK,\t");
break;
    case DHTLIB_ERROR_CHECKSUM:
Serial.print("Checksum error,\t");
break;
    case DHTLIB_ERROR_TIMEOUT:
Serial.print("Time out error,\t");
break;
    case DHTLIB_ERROR_CONNECT:
        Serial.print("Connect error,\t");
        break;
    case DHTLIB_ERROR_ACK_L:
        Serial.print("Ack Low error,\t");
        break;
    case DHTLIB_ERROR_ACK_H:
        Serial.print("Ack High error,\t");
        break;
    default:
Serial.print("Unknown error,\t");
break;
  }
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: flagtrax on Jan 14, 2015, 06:05 am
Ah, great I can work with that, thank you thank you!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 21, 2015, 09:53 pm
The DHT11 code had a masking bug (Thanks Richard for pointing this out and providing the fix)


Pushed the 0.1.19 version - https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib -


Please note that 0.1.19 does not work on ARM processors (e.g. Due),  please use the 0.1.13 version.

Still remarks and comments are welcome.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: ghlawrence2000 on Jan 29, 2015, 12:59 am
So much better than the Adafruit library, thankyou!

Regards,

Graham

+1
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: silvaphoenix on Mar 02, 2015, 10:45 pm
Hi,
I've purchased an Aosong AM2301 DHT21 sensor to use with a MEGA 2560 board. I've installed Rob Tillaart's latest library and example sketch but am having problems. The humidity reading is always 99.9% although the temperature reading is correct. Status OK.
This is happening on two sensors so is there something in the software or am I unlucky with two faulty sensors. I'm using pin 18 on the board.
Any help/advice would be appreciated.
Stephen
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 04, 2015, 10:08 pm
@Stephen,

which version of the library are you using? Then I can check the code.

Can you post the code you use?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 04, 2015, 10:12 pm
Version 0.1.20 of the lib is posted on GitHub - Thanks to chaviero!

- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib -


Functions now return a int8_t iso int => 34 bytes smaller footprint.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: silvaphoenix on Mar 05, 2015, 08:16 pm
Hi Rob,
Thanks for looking at this. I have tested a third sensor and that also reads only 99.9% so I don't think I have 3 faulty sensors.
The library version is 0.1.19 and the test sketch 0.1.01.
These are attached.
Stephen
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 06, 2015, 08:57 am
I see no code path that would generate 99.9% in a consistent way.


Can you post the exact output you get from the sketch?

please also try the 0.1.13 version attached to - http://forum.arduino.cc/index.php?topic=58531.0
DHT21 is interface compatible to DHT22.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: silvaphoenix on Mar 06, 2015, 03:48 pm
Hi Rob,
Output attached. I'll report back when I've tried the other version you suggest
Stephen
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 07, 2015, 08:21 am
Output looks normal and states the communication is OK.

you might try this debug version of read() in the lib. It dumps the bytes that come from the sensor.
Code: [Select]

int8_t dht::read(uint8_t pin)
{
    // READ VALUES
    int8_t result = _readSensor(pin, DHTLIB_DHT_WAKEUP, DHTLIB_DHT_LEADING_ZEROS);


    Serial.println("dump: ");
    for (int i=0; i< 5; i++)
    {
      Serial.print(bits[i], HEX);
      Serial.println("\t");
    }
    Serial.println();


    // these bits are always zero, masking them reduces errors.
    bits[0] &= 0x03;
    bits[2] &= 0x83;

    // CONVERT AND STORE
    humidity = word(bits[0], bits[1]) * 0.1;
    temperature = word(bits[2] & 0x7F, bits[3]) * 0.1;
    if (bits[2] & 0x80)  // negative temperature
    {
        temperature = -temperature;
    }

    // TEST CHECKSUM
    uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];
    if (bits[4] != sum)
    {
        return DHTLIB_ERROR_CHECKSUM;
    }
    return result;
}
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: silvaphoenix on Mar 08, 2015, 10:20 am
Hi Rob,
Bits[0] and bits[1] are 3 and E7. they do not change when humidity is changed by breathing on the sensor. Temperature does change. I haven't tried version 13 yet
Stephen
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 08, 2015, 10:36 am
Code: [Select]

  float f = word(3, 0xE7) * 0.1;
  Serial.println(f); 


output 99.9

As there is no checksum or other error the library works as intended.

You might need to recalibrate the sensors, or send them back?

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: silvaphoenix on Mar 09, 2015, 01:39 pm
Thank you Rob I've already sent two back so might try a different sensor.
Stephen
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: fvdnabee on Mar 20, 2015, 05:36 pm
I'm trying to get the DHT22 sensor working on the DigiX with DHTlib. I've read that the recommended way for doing so was plugging the DHT22 on 3.3V as per http://forum.arduino.cc/index.php?topic=215336.0.

When I use the version of DHTlib from February last year, I can get the DHT22 to work. This is the git commit with ref 2f6075437687932dc5f191e8931e35d1fd78a88f (February 10 2014)

However, with the DHTlib from the master tree I'm seeing two problems:
* In the dht22_test example sketch, the name stat is taken by a function. So I changed the name to statDHT. Compiler error:
Quote
c:\program files (x86)\digistump_arduino\hardware\tools\g++_arm_none_eabi\arm-none-eabi\include\sys\stat.h:150:5: error: previous declaration of 'int stat(const char*, stat*)'
int _EXFUN(stat,( const char *__restrict __path, struct stat *__restrict __sbuf ));
* More importantly in the dht.cc file, the direct port access does not compile for the DigiX:
Quote
In file included from C:\Users\Floris\Documents\Arduino\libraries\DHTlib\dht.h:19:0,
                 from C:\Users\Floris\Documents\Arduino\libraries\DHTlib\dht.cpp:42:
C:\Users\Floris\Documents\Arduino\libraries\DHTlib\dht.cpp: In member function 'int8_t dht::_readSensor(uint8_t, uint8_t, uint8_t)':
C:\Users\Floris\Documents\Arduino\hardware\digistump\sam\cores\digix/Arduino.h:57:65: error: invalid conversion from 'Pio*' to 'uint8_t {aka unsigned char}' [-fpermissive]
 #define digitalPinToPort(P)        ( g_APinDescription[P].pPort )
                                                                 ^
C:\Users\Floris\Documents\Arduino\libraries\DHTlib\dht.cpp:121:20: note: in expansion of macro 'digitalPinToPort'
     uint8_t port = digitalPinToPort(pin);
                    ^
C:\Users\Floris\Documents\Arduino\hardware\digistump\sam\cores\digix/Arduino.h:62:44: error: base operand of '->' is not a pointer
 #define portInputRegister(port)    ( &(port->PIO_PDSR) )
                                            ^
C:\Users\Floris\Documents\Arduino\libraries\DHTlib\dht.cpp:122:29: note: in expansion of macro 'portInputRegister'
     volatile uint8_t *PIR = portInputRegister(port);
                             ^
Error compiling.
I've managed to get DHTlib to compile by changing the data type to the return types from DigiX:
Quote
diff --git a/libraries/DHTlib/dht.cpp b/libraries/DHTlib/dht.cpp
index a40e47c..9cfd101 100644
--- a/libraries/DHTlib/dht.cpp
+++ b/libraries/DHTlib/dht.cpp
@@ -118,8 +118,10 @@ int8_t dht::_readSensor(uint8_t pin, uint8_t wakeupDelay, uint8_t leadingZeroBit
     // reduces footprint ~100 bytes => portability issue?
     // direct port read is about 3x faster
     uint8_t bit = digitalPinToBitMask(pin);
-    uint8_t port = digitalPinToPort(pin);
-    volatile uint8_t *PIR = portInputRegister(port);
+    //uint8_t port = digitalPinToPort(pin);
+       Pio* port = digitalPinToPort(pin);
+    //volatile uint8_t *PIR = portInputRegister(port);
+       volatile RoReg* PIR = portInputRegister(port);

     // REQUEST SAMPLE
     pinMode(pin, OUTPUT);
However, when I try to get a reading from my DHT22 sensor (modified dht22_test.ino), DHTlib is returning an 'Ack Low' error:
DHT22,    Ack Low error,   0.0,   0.0,   1061

Any suggestions? Could the code changes since February 2014 have introduced timing issues or is the direct port access not compatible with the DigiX (I'm not knowledgeable enough to access whether the above patch makes sense)?

I've put the changes to DHTlib (git diff) on pastebin @ http://pastebin.com/cEckj8es
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 26, 2015, 01:35 pm
Sorry for late reaction.

The latest portable version which should work as is on Digix is the 0.1.13.

The versions thereafter are experimental to support lower clock speeds on AVR processors, typically UNO and MEGA, and to some extend decrease footprint.

I have no Digix experience so I don't know if your modifications are correct or not.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: roop on Mar 31, 2015, 09:37 pm
Hi,

I got a strange issue with humidity readings and wonder if my DHT-22 is faulty or not.
I use an UNO and v1.1.20 of the lib.

The readings jump at ~39.9 humidity to ~61.2.
I don't know the exact values (the changes happend really fast).

In bytes (what i've seen):

bits[0] is 1 and bits[1] is 143

then jumps to

bits[0] is 2 and bits[1] is 99


I really can't tell if the sensor is the problem here
or some calculations are off.

Temperature seems normal so far.

Thanks a lot and great work so far!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 31, 2015, 10:23 pm
most probably the sensor is somehow faulty, otherwise the library would give a CRC error (OK chance one in 255 the Checksum is the same.

Is it repeatable?
Does the temperature show meaningful numbers?


Have you tried another version of the library?
The first post of this thread has 0.1.13 attached which is sort of reference version (without all AVR specific optimizations) Can you please give that a try?

Trying with the another lib e.g. Adafruit lib is also a way to test if the sensor is broken or the lib.

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: roop on Mar 31, 2015, 10:58 pm
Yeah its totally repeatable.
I'll make another test and post the values.

Temperature is arount 20 - 21 °C (room temp).
Should be fine.

I've just tried the Adafruit lib. Same values there.

Will try the 0.1.13 next.

Thanks so far.

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Mar 31, 2015, 11:02 pm
Quote
I've just tried the Adafruit lib. Same values there.
Strong indication its the sensor...
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: roop on Mar 31, 2015, 11:37 pm
Yes, looks like the sensor is faulty =(.

Here are some values (v.0.1.13):


DHT TEST PROGRAM
LIBRARY VERSION: 0.1.13

Type, status, Humidity (%), Temperature (C) Time (us)

DHT22, OK, 62.1, 21.5, 5224
DHT22, OK, 62.3, 21.5, 5220
DHT22, OK, 62.3, 21.5, 5224
DHT22, OK, 62.0, 21.4, 5080
DHT22, OK, 62.1, 21.5, 5224
DHT22, OK, 62.1, 21.4, 5184
DHT22, OK, 62.0, 21.4, 5076
DHT22, OK, 62.1, 21.5, 5220
DHT22, OK, 61.9, 21.4, 5176
DHT22, OK, 61.8, 21.4, 5076
DHT22, OK, 61.8, 21.4, 5076
DHT22, OK, 61.8, 21.4, 5076
DHT22, OK, 61.5, 21.4, 5324
DHT22, OK, 61.2, 21.4, 5128
DHT22, OK, 61.4, 21.4, 5224
DHT22, OK, 61.4, 21.4, 5220
DHT22, OK, 61.5, 21.4, 5344
DHT22, OK, 61.6, 21.4, 4984
DHT22, OK, 61.7, 21.4, 5080
DHT22, OK, 61.8, 21.4, 5096
DHT22, OK, 61.4, 21.3, 5224
DHT22, OK, 61.3, 21.3, 5176
DHT22, OK, 61.5, 21.4, 5320
DHT22, OK, 61.6, 21.3, 5224
DHT22, OK, 39.8, 21.3, 5128
DHT22, OK, 38.9, 21.3, 5176
DHT22, OK, 38.2, 21.3, 5224
DHT22, OK, 37.8, 21.3, 5128
DHT22, OK, 37.7, 21.2, 5176
DHT22, OK, 37.9, 21.2, 5128
DHT22, OK, 38.2, 21.2, 5220
DHT22, OK, 38.7, 21.1, 5196
DHT22, OK, 38.7, 21.1, 5176
DHT22, OK, 38.9, 21.1, 5124
DHT22, OK, 39.2, 21.1, 5076
DHT22, OK, 39.6, 21.1, 5032
DHT22, OK, 61.2, 21.1, 5124
DHT22, OK, 61.5, 21.1, 5224
DHT22, OK, 61.7, 21.1, 5248
DHT22, OK, 62.0, 21.0, 4984
DHT22, OK, 62.0, 21.0, 4980
DHT22, OK, 61.5, 21.0, 5220
DHT22, OK, 61.3, 21.0, 5128
DHT22, OK, 39.9, 21.0, 5124
DHT22, OK, 39.6, 21.0, 5196
DHT22, OK, 38.8, 20.9, 5028
DHT22, OK, 38.9, 20.9, 5132
DHT22, OK, 39.4, 20.9, 5076
DHT22, OK, 39.7, 20.9, 5220
DHT22, OK, 39.7, 20.9, 5224
DHT22, OK, 39.3, 20.9, 5124
DHT22, OK, 39.2, 20.9, 5060
DHT22, OK, 39.0, 20.8, 5084
DHT22, OK, 38.9, 20.8, 5028
DHT22, OK, 39.4, 20.9, 5076
DHT22, OK, 61.1, 20.9, 5124
DHT22, OK, 61.4, 20.9, 5128
DHT22, OK, 61.6, 20.9, 5128
DHT22, OK, 61.9, 20.9, 5224
DHT22, OK, 62.1, 20.9, 5032
DHT22, OK, 62.3, 20.9, 5152
DHT22, OK, 62.4, 20.9, 5028


I hope a new one will work.

Thanks again.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: tk5ep on Jun 08, 2015, 09:06 pm
Hi all,

I just tried this library and i do have plenty of checksum errors...
The sensor is connected via a 30 cm long cable.

Any advice ?

Thanks,
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jun 09, 2015, 08:04 pm
Which version of the library are you using?
Did you use a pull up resistor?
How long are your wires to the sensor?

Code, schematic ...?

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: gardab on Jul 03, 2015, 02:13 am
Thank you for your work. I tested the library and it works on my Leonardo.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jul 03, 2015, 07:57 pm
Thank you for your work. I tested the library and it works on my Leonardo.
Welcome, good to hear leonardo works, which version of the lib do you use?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jul 04, 2015, 07:01 pm
As the DHTLib is used more and more on ARM processors I added a separate repository for the stable 0.1.13 version of the DHT library on github.


URL: https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable

Have fun.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Clemens on Oct 02, 2015, 02:35 pm
I have a question about error handling and displaying values. The story behind: In case you have a running sensor and disconnect them while your sketch is running DHT.readxx(); returns an error but DHT.humidity and DHT.temperature returns still the last valid value. This can be a feature when you want always values back but can lead to misinterpretation in case you have time stamped data. It's not a big deal to fix that. You can check DHT.readxx() and output data in case this is DHTLIB_OK / 0 only. But I like to ask if there is a deeper reason behind and why not outputting nothing when you get an error code over the lib before.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Oct 02, 2015, 04:18 pm
Quote
This can be a feature when you want always values back but can lead to misinterpretation
Agree, but timestamped data can also be corrupted if people do not check invalid value of temperature()


I could give the getTemperature() an extremely non likely value like -999 which is both for temperature and humidity out of range for this universum. However people would still display those values or calculate the dewpoint() and close the door of the chicken nest as it is considered freezing etc.

I decided that the read() function is the one that detects the error and therefor read() reports the error.

Returning the last value read by temp/hum, is to keep the implementation small and simple. It has the "positive" side effect that code that does not check the read() return value and has an occasional glitch() is not affected by it. The code will appear to work smooth. Yes if the glitch takes longer it can really hurt.

People who want to make code fault proof should check the return value of the read().

So no big design philosophies, just pragmatic.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Qaazar on Nov 05, 2015, 10:01 am
Hello, my first post here :)

Anyway, I'm new to programming avr's and right now I'm building my first project.
I'm using ATmega8A-PU @ 8Mhz, connected to it DHT21,
it connects and returns DHTLIB_OK, so I tried pulling temperature to see if values are ok and got to little problem.

Temporarly I can't use serial port to just recive data so to test DHT I created workaround using LEDs.

Code: [Select]

if(chk == DHTLIB_OK)
  {
    if(DHT.temperature > 24)
    {
      digitalWrite(6, HIGH);
    }
    if(DHT.temperature < 25)
    {
      digitalWrite(7, HIGH);
    }

Knowing that my air temperature is 24.8, upon seeing both LEDs light up I knew that it's working. But then I wanted to change it so LED blinks to show temperature (24.8 == 24 blinks) and to achieve that I created this loop:

Code: [Select]

    int i =0;
    double a = DHT.temperature;
    while(i < a)
    {
     
      digitalWrite(7, HIGH);
      digitalWrite(6, HIGH);
      delay(150);
      digitalWrite(7, LOW);
      digitalWrite(6, LOW);
     
      i++;

    }


And result is that LEDs light up for ~6sec and turn off without blinking. I guess it's something stupid but I just can't understand why it's not blinking.

Side note, My DHT21 decided to disregard datasheet and not to work on 3,3V. Connecting at that voltage returns unending stream of DHTLIB_ERROR_TIMEOUT. On 5V it works without issues.

EDIT:
Got it solved. There is missing delay at end of the loop, so LEDs get instantly light up again.
Knew it's something stupid
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 05, 2015, 07:40 pm
Good to hear you solved it.

You could write a function for the blink part, then you can do something like

Code: (snippet) [Select]

double temperature = DHT.temperature;
blink(temperature, 7, 150);

double humidity = DHT.humidity;
blink(humidity, 6, 50);

....


void blink(int times, int pin, uint16_t del)
{
  for (int i=0; i<times; i++)
  {
    digitalWrite(pin, HIGH);
    delay(del);
    digitalWrite(pin, LOW);
    delay(del);
  }
}


get the idea?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Qaazar on Nov 05, 2015, 08:14 pm
Yep, I know functions.

I did some programming in C++ / C# in Visual Studio, just for some reason I didn't expect them to work in Arduino IDE.
Still getting used to it, thanks for enlightening me :)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: visualwork2000 on Nov 30, 2015, 06:36 pm
Hello,

I would like to know the HDT version which has been successfully tested on Arduino DUE boards. I have tried a number of versions but without luck. I use Arduino software version 1.6.6. I will use this library to read the output of RT03 sensor. I would be thankful if you could send me the zip file of the library. Without having this library, it is very difficult to use this type of sensors. Many thanks.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Nov 30, 2015, 06:47 pm
The most stable version is 0.1.13 - https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable -

The versions thereafter are optimized for AVR only
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Clemens on Jan 17, 2016, 12:27 am
I have tried to use the DHT lib for the ESP8266 (lib version 0.1.21 with DHT33 on Adafruit Huzzah board). But got this error message:

Code: [Select]

In file included from D:\projekte\arduino\arduino-1.6.6\libraries\DHTlib\dht.h:19:0,

                 from D:\projekte\arduino\arduino-1.6.6\libraries\DHTlib\dht.cpp:41:

D:\projekte\arduino\arduino-1.6.6\libraries\DHTlib\dht.cpp: In member function 'int8_t dht::_readSensor(uint8_t, uint8_t, uint8_t)':

C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\cores\esp8266/Arduino.h:228:62: error: cannot convert 'volatile uint32_t* {aka volatile unsigned int*}' to 'volatile uint8_t* {aka volatile unsigned char*}' in initialization

 #define portInputRegister(port)     ((volatile uint32_t*) GPI)

                                                              ^

D:\projekte\arduino\arduino-1.6.6\libraries\DHTlib\dht.cpp:121:29: note: in expansion of macro 'portInputRegister'

     volatile uint8_t *PIR = portInputRegister(port);

                             ^

exit status 1
Fehler beim Kompilieren.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 17, 2016, 11:25 am
Please use the stable version 0.1.13, it is confirmed (private mail)  to work with ESP8266 

https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable -

The versions 0.1.14 and up are optimized for AVR only
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Clemens on Jan 17, 2016, 05:18 pm
Many thanks, Rob! The version 0.1.13 is excellent running with the ESP8266 and the DHT33 I use.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 17, 2016, 06:29 pm
You're welcome :)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Wareemba on Jan 25, 2016, 09:41 am
Hi DHT22 users,

I have wired up 3 DHT22's to an ESP8266-12 using 0.1.13 DHT library

i'm getting very high humidity readings, 90%+ alongside normal temp readings

i have 3 other DHT22's on a ESP8266-12 using same library but showing normal humidity and temp readings.

(all in the same physical location)

the difference: the abnormal sensors are wired via ~6m of Cat5 cable and has 4k7 resistors between the GPIO pins and the 3.3 VCC of the ESP8266

the normal ones are wired via ~5m headphone cable and have NO resistors (as per my usual method using the ESP8266).

both are wired with the DH22's connected to 5V source & common ground.

boh ESP8266's get power from AM1117 3.3V regulators.


if the DHT22's are wired up and sending readings - is there any reason the readings would be so abnormal?

this is the first time with over 10 occasions using DHT22's that i have found this...

the abnormal reading DHT22's are all from the same 'aliexpress' batch.


do i have a bad batch of sensors?

has anyone seen this before?

these are my test outputs:

Code: [Select]
ROOF_DHT22, OK, 89.9, 23.4, 5104
HOUSE_DHT22, OK, 96.4, 23.1, 5244
PLENUM_DHT22, OK, 93.1, 23.3, 5703
---------
ROOF_DHT22, OK, 89.8, 23.4, 5199
HOUSE_DHT22, OK, 96.3, 23.1, 5294
PLENUM_DHT22, OK, 92.6, 23.3, 5204
---------
ROOF_DHT22, OK, 89.8, 23.4, 5197
HOUSE_DHT22, OK, 96.4, 23.1, 5244
PLENUM_DHT22, OK, 93.1, 23.3, 5244
---------
ROOF_DHT22, OK, 89.8, 23.4, 5199
HOUSE_DHT22, OK, 96.3, 23.1, 5292
PLENUM_DHT22, OK, 93.1, 23.3, 5243
---------
ROOF_DHT22, OK, 89.9, 23.4, 5104
HOUSE_DHT22, OK, 96.3, 23.1, 5292

TOT OK CRC TO UNK
20 20 0 0 0 0 0 0

PLENUM_DHT22, OK, 93.1, 23.3, 5243
---------
ROOF_DHT22, OK, 89.9, 23.4, 5104
HOUSE_DHT22, OK, 96.3, 23.1, 5291
PLENUM_DHT22, OK, 93.1, 23.3, 5244
---------
ROOF_DHT22, OK, 89.9, 23.4, 5105
HOUSE_DHT22, OK, 96.3, 23.1, 5292
PLENUM_DHT22, OK, 93.0, 23.3, 5148
---------
ROOF_DHT22, OK, 90.0, 23.4, 5104
HOUSE_DHT22, OK, 96.3, 23.1, 5292
PLENUM_DHT22, OK, 93.0, 23.3, 5149
---------
ROOF_DHT22, OK, 90.0, 23.4, 5564
HOUSE_DHT22, OK, 96.3, 23.1, 5300
PLENUM_DHT22, OK, 93.0, 23.3, 5149
---------
ROOF_DHT22, OK, 88.1, 23.4, 5703
HOUSE_DHT22, OK, 96.2, 23.1, 5197
PLENUM_DHT22, OK, 93.0, 23.3, 5149
---------
ROOF_DHT22, OK, 88.1, 23.4, 5247
HOUSE_DHT22, OK, 96.2, 23.1, 5197
PLENUM_DHT22, OK, 93.0, 23.3, 5148
---------
ROOF_DHT22, OK, 89.9, 23.4, 5104

TOT OK CRC TO UNK
40 40 0 0 0 0 0 0



the *real* humidity is around 76% and temp is around 23.5'C - from the Hylec handheld...

PLEASE excuse me if this is in the wrong place for such questions, but no sure where else it can go - i have learned lots about the DHT22 from this thread and Rob's many other responses to DHT related questions...


Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 25, 2016, 10:04 pm


The fact that there is no sensor error e.g. CRC error means the sensors make no communication error.

The DHT are not known for their accuracy (for the H part)

I don't know if the sensors are bad, is it possible to swap the 2 groups of sensors?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Wareemba on Jan 26, 2016, 12:04 am
removed the resistors, no change...

will swap over the sensors next, see what happens...
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Wareemba on Jan 26, 2016, 07:07 am
Thansk Rob,

The fact that there is no sensor error e.g. CRC error means the sensors make no communication error.

The DHT are not known for their accuracy (for the H part)

I don't know if the sensors are bad, is it possible to swap the 2 groups of sensors?

this is the CRC after a whole day:

Code: [Select]
TOT OK CRC TO UNK
13560 13555 4 1 0 0 0 0


i'm just going to swap the sensors (desolder/resolder) now..

is there  a much more reliable sensor for humidity? i am considering the BME280's perhaps?

my ventilation control system relies on accurate dew point for its if/else controls....

or do i just find a set of DHT22's that seem reliable and most closely match my SHT75 handheld readings? as mentioned, this set of sensors are from teh same batch - and are one of the first ones i have experienced such large deviations with...

or can i actually pseudo-calibrate them? like add/subtract a % so they are all on equal readings at the same location?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 26, 2016, 03:20 pm
>> is there  a much more reliable sensor for humidity?

Sensirion is oftenmentioned as stable humidity sensors, but they are in another price segment.

>> or can i actually pseudo-calibrate them?
There is a real-calibration procedure,

- http://www.kandrsmith.org/RJS/Misc/calib_dht22.html

possibly interesting too
- http://forum.arduino.cc/index.php?topic=184356.msg1753894#msg1753894
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Wareemba on Jan 28, 2016, 01:53 am
thanks for the links, i had read the Smith posting, which was very informative, but i'm not going to go through that!

it turns out the sensors seem to be bad,

i soldered the 'good' ones to the Cat5 cabling and these are the readings:

Code: [Select]
---------
ROOF_DHT22, OK, 79.2, 23.5, 5054
HOUSE_DHT22, OK, 79.3, 23.7, 5102
PLENUM_DHT22, OK, 80.1, 23.4, 5055
---------
ROOF_DHT22, OK, 79.1, 23.5, 5152
HOUSE_DHT22, OK, 79.2, 23.8, 5054
PLENUM_DHT22, OK, 80.1, 23.4, 5055
---------
ROOF_DHT22, OK, 79.3, 23.5, 5150
HOUSE_DHT22, OK, 79.4, 23.8, 5149
PLENUM_DHT22, OK, 80.2, 23.4, 5102
---------
ROOF_DHT22, OK, 79.3, 23.5, 5150
HOUSE_DHT22, OK, 79.3, 23.8, 5102
PLENUM_DHT22, OK, 80.2, 23.4, 5103
---------
ROOF_DHT22, OK, 79.3, 23.5, 5150
HOUSE_DHT22, OK, 79.4, 23.8, 5152
PLENUM_DHT22, OK, 80.2, 23.4, 5099
---------
ROOF_DHT22, OK, 79.3, 23.4, 5061
HOUSE_DHT22, OK, 79.4, 23.8, 5149
PLENUM_DHT22, OK, 80.2, 23.4, 5102
---------
ROOF_DHT22, OK, 79.3, 23.4, 5055

TOT OK CRC TO UNK
280 279 0 1 0 0 0 0


the Sensirion is showing 80.3% and 23.6'C

so we are back in range :)

Rob - if it is working without the resistors, do i actually need them?

i have 4 x DHT22 Cat5 cable runs, 3 x 6m runs (which had 4K7 resistors to VCC) and one 14m run (with a 2K2 resistor to VCC)

also - i am using the 0.1.13 dht library, is there any benefit going to the latest version if im using ESP8266-12E?

thanks!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 28, 2016, 09:02 pm
>> Rob - if it is working without the resistors, do i actually need them?

If it is working, it is working. The resistors will give a better square wave signal making the handshakes more reliable.

>> also - i am using the 0.1.13 dht library, is there any benefit going to the latest version if im using ESP8266-12E?

No, the 0.1.14 and up version are optimized for AVR to support lower clock speeds.

0.1.13 is the stable portable one, it has been used on a ESP2866 (sorry no link)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Wareemba on Jan 29, 2016, 01:28 am
0.1.13 is the stable portable one, it has been used on a ESP2866 (sorry no link)
ok, thanks again, 0.1.13 has been working fantastic for me.

fyi - i have used 0.1.13 with DHT22's on the following packages:

ESP8266-01
ESP8266-07
ESP8266-12E
ESP8266-12F
NodeMCUv1.0
WeMOS D1

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Jan 29, 2016, 07:10 am
Thank you that is very valuable feedback!  - karma to you :)

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: moreapicguy on Jan 31, 2016, 07:35 pm
I just ran into the same problem (stuck at 99.9% rH) as an earlier poster here, and discovered that for me it was a power supply issue.  I had been running this sensor on a 5V supply that I eventually determined was giving me some grief (inadvertent brownouts and reboots) and so I tried swapping out the power supply.  The new one is a little more robust, measuring at 5.29V on my meter when under load.  On the PRIOR supply, I was getting accurate relative humidity readings, but with the new one, it was stuck on 99.9% - although temperature was correct.  I put a 1N4148 in between my VCC and the sensor's power pin to drop by .7V and all is now well again, with accurate readings.

Just thought I'd post it here in case others were having the same issue.

Steve
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Feb 01, 2016, 02:53 pm
@moreapicguy

Thanks for sharing this valuable info
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: duino_nano on Mar 08, 2016, 02:17 am
I think that the DHT11 should not be connect on +5V in a permanent way. I had it connected on 5V in the past and had humidity data off (low)  by about 10%.
Now I use one of the digital output of the Arduino to supply it with 5V for 1 or 2 seconds every 20 seconds. Results are now more constants and higher by 10% (for 2 units)!
Note: the resistor between pin 1 and 2 is also connect to the output.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: jnissen on Mar 31, 2016, 12:53 am
Running into an issue with a 4MHz setup and trying to use the 0.1.21 version of the library. I get a variety of errors and I have tried 10K pullup, 5.1K pullup, reducing length of wires, ensuring I have 3.25V or better (3.3V system).

I got the code to run fine on a 5V UNO but I am targeting this 4MHz setup from Sparkfun.

Code is here:
https://codebender.cc/sketch:268024 (https://codebender.cc/sketch:268024)

Output:
connected at 9600
DHT Sensor with Badger Stick
LIBRARY VERSION: 0.1.21

Type, status, Humidity (%), Temperature (C) Time (us)
DHT22, Connect error, 0.0, 0.0, 3232
DHT22, Checksum error, 0.3, -76.8, 7168
DHT22, Time out error, 0.0, 0.0, 7408
DHT22, Time out error, 0.0, 0.0, 7056


One other thing... I modified the Badgerstick to eliminate batteries. The diode is now bypassed so the 3.3V is being seen by the whole board and sensor. I understand some of the DHT sensors can be low voltage sensitive.

Update: I looked at the signaling with my Rigol scope and it appears that I am getting fairly good rail to rail swing. The micro initialization delay is about 2.5uS then I go out and measure the appropriate response and data spacing. Ones and zero's are as they are supposed to be. At this point it looks like the data coming back is often all zero's but in the correct format. I ordered a couple new DHT sensors in case this one is wonky at low voltage.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: povlhp on Apr 27, 2016, 10:41 pm
I used the latest github version of DHTLib on my new DHT11, and like someone else, only got zero values back, communications error. Got the DHT11 library source, and used that, and now it works as expected.

My weather station 40cm away (10cm from wall) says 1.4 degrees colder, which is likely OK, humidity 38% vs 44% of the DHT11. Same humidity should show lower at the DHT11, so precision is far from perfect.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Apr 28, 2016, 09:26 am
Please use the version - https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable -
This equals the DHTlib 0.1.13 version

as the latest DHTlib version is more experimental to minimize footprint and work at lower clock speeds and is coded with AVR specific code. It will not work on ARM version.

Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: monotok on May 10, 2016, 08:50 pm
Hello All,

First time posting on here and getting into the Arduino (Or should I say Genuino).

Like many people seem to be doing I am creating a weather station. Multiple sensors connecting to a central atmega 328 module which will be plugged into a raspberry pi to send data over the serial link. I have got a lot working including the rf link, temp sensors and 7 segment (Wrote library for it so hopefully people will find it useful).

The bit I am struggling to get working is the DHT22. There are two libraries I have found. This one (ver 0.1.03) and the one written by Adafruit.

I can get the example to work perfectly with a 0.06% error rate over a day which is great. The adafruit one gets around a 10% error rate.

However when I use this library with the virtual wire library then I get around 99% error rate but the adafruit library is unaffected.

The line of code that seems to do it is:
Code: [Select]
vw_rx_start();

You should be able to replicate it by adding these lines to the example "dht22_test"

Code: [Select]

#include <VirtualWire.h>
vw_set_rx_pin(8);
vw_setup(2000);   // Bits per sec
vw_rx_start();


I can post the rest of my code or the example if it helps. The error I get is a checksum with the occasional timeout.

I have been looking at the code but I have no idea atm why it affects it.

Any help would be greatly appreciated.

Thanks in advance  :)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on May 10, 2016, 09:16 pm
Hi Monotok,

I have very little time to investigate but the question is interesting as I never tested the lib in combination with VW.

The version 0.1.03 is rather old, can you please confirm the bug exists with the 0.1.13 version a.k.a. DHTstable?

https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable

Thanks,
Rob
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: monotok on May 10, 2016, 10:46 pm
Hello Rob,

Thank you very much for your quick reply and that's Ok, I'll be fiddling with it so will let you know if I find anything.

My apologies, I was using version 0.1.21 from GitHub before. Here are the results:
Code: [Select]

dht22_test.ino
LIBRARY VERSION: 0.1.21

Type, status, Humidity (%), Temperature (C) Time (us)
DHT22, Checksum error, 90.6, 39.7, 6760
DHT22, Checksum error, 74.1, 79.6, 6648
DHT22, Checksum error, 90.0, 43.4, 6640
DHT22, Checksum error, 64.3, 19.6, 6176
DHT22, Checksum error, 70.6, 19.6, 6120



The stable version produces timeout errors instead.

Code: [Select]
dht22_test.ino
LIBRARY VERSION: 0.1.13

Type, status, Humidity (%), Temperature (C) Time (us)
DHT22, Time out error, -999.0, -999.0, 9000
DHT22, Time out error, -999.0, -999.0, 8888
DHT22, Time out error, -999.0, -999.0, 8944
DHT22, Time out error, -999.0, -999.0, 8952
DHT22, Time out error, -999.0, -999.0, 9000
DHT22, Time out error, -999.0, -999.0, 8952
DHT22, Time out error, -999.0, -999.0, 8992
DHT22, Time out error, -999.0, -999.0, 8912


I tried Virtual Wire's replacement (RadioHead) and that does the same thing. Quite an interesting "bug"  and surprised no body has encountered this before with quite a few people making weather stations.

Thanks  :)
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on May 10, 2016, 11:19 pm
Can you tell which boards you are using?
Do you use a pull up resistor on the data line of the DHT sensor?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: monotok on May 10, 2016, 11:40 pm
Hello,

Some good news! First I will answer your question. I am using a Uno R3 as a programmer to a Atmega 328P chip on a breadboard using it's own internal 8Mhz clock. I haven't used a resistor because I don't think I need one because I am using this http://www.banggood.com/AM2302-DHT22-Temperature-And-Humidity-Sensor-Module-For-Arduino-SCM-p-937403.html which I think has it's own inbuilt resistor.

So the good news is I seem to have modified your library (Very quickly and dodgy) and it now seems to work.

Code: [Select]
DHT22, OK, 70.4, 19.8, 3960
DHT22, OK, 70.4, 19.8, 3960
DHT22, OK, 70.4, 19.8, 4016
DHT22, OK, 70.4, 19.8, 4008

TOT OK CRC TO UNK
180 180 0 0 0 0 0 0


So I looked at your code, Adafruits library and the datasheet. The adafruit library mentioned part of the process of getting the bits back from the chip is timing critical and used an interrupt class to temporarily stop interrupts. I took the class and added it to your header file and then placed the same class call into your cpp file.

I am very very surprised but it seems to have fixed it somehow, maybe the Virtual library is causing the Atmega to be interrupted every time it hears a RF signal on 433Mhz?

Here is the class in the header.

Code: [Select]
class InterruptLock {
  public:
   InterruptLock() {
    noInterrupts();
   }
   ~InterruptLock() {
    interrupts();
   }

};
#endif
//
// END OF FILE
//


Here is the call in the CPP file.
Code: [Select]

// REQUEST SAMPLE
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW); // T-be
    delayMicroseconds(wakeupDelay * 1000UL);
    InterruptLock lock;
    digitalWrite(pin, HIGH); // T-go
    pinMode(pin, INPUT);


Anyway; do you think this is a good idea and should be added? Your library now works with my sensor code.

Hope this is helpful.

EDIT:
LED Receive light works, forgot to un-comment the code to make it go off.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: monotok on May 11, 2016, 07:52 pm
Just to add to my previous comment. I have left it running in my sensor code using VirtualWire and I have got 18,000 "Ok's" and Zero errors. 100% success rate is great, so disabling the interrupts in that function might have increased the success rate even further as I got 0.06% (9 out of 14,000) before.

Thanks
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Clemens on May 14, 2016, 05:14 pm
DHT lib outputs humidity and temperature values from the point in time of the reading before

I did some tests with a longer delay (20 min) between the DHT sensor readings, I noticed a significant offset between the DHT values and some DS18B20 temp sensors readings in parallel. After a rain shower I noticed also some implausible data values: It starts to rain but the next reading about 10 minutes after did report very "dry" values and only the next reading reports correct "wet" values.

So I did some tests with the sketch below. It reads values every 10 seconds but also a "control reading" 500 ms after the first reading. To trigger sensor changes I breathe upon the sensor to increase humidity, this is directly after last reading, around 9 seconds before next reading. So the sensor has enough time to "warm up" / catch the change. 

I got the same results as in my 20 minutes setting (detailed output see below after the code): The reading is NOT the value for the current time but represents the situation of the last measurement. It seams with "DHT.readxx" is done a reading but this reading will be outputted not in the following Serial.print(DHT.temperature, 1); but in outputs just after that, so "one data point too late".

Is this the way the DHT works??--I did not see any comment about that?? Or is there an error in the lib or in my code (a modification of the lib example)?

Code: [Select]
#include <dht.h>
dht DHT;
#define DHT33_PIN 7

struct{
    uint32_t total;
    uint32_t ok;
    uint32_t crc_error;
    uint32_t time_out;
    uint32_t connect;
    uint32_t ack_l;
    uint32_t ack_h;
    uint32_t unknown;
} stat = { 0,0,0,0,0,0,0,0};

void setup(){
    Serial.begin(9600);
    Serial.print("LIBRARY VERSION: ");
    Serial.println(DHT_LIB_VERSION);
    Serial.println();
    Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)\tTime (us)");
}

void loop(){
    readData();
    Serial.print("\t");
    Serial.print("delay 500");
    Serial.println();
    delay(500);
   
    readData();
    Serial.print("\t");
    Serial.print("delay 10000");
    Serial.println();
    delay(10000);
    Serial.println();
}

void readData(){
    // READ DATA
    Serial.print("DHT33, \t");

    uint32_t start = micros();
    int chk = DHT.read33(DHT33_PIN);
    uint32_t stop = micros();

    stat.total++;
    switch (chk)
    {
    case DHTLIB_OK:
        stat.ok++;
        Serial.print("OK,\t");
        break;
    case DHTLIB_ERROR_CHECKSUM:
        stat.crc_error++;
        Serial.print("Checksum error,\t");
        break;
    case DHTLIB_ERROR_TIMEOUT:
        stat.time_out++;
        Serial.print("Time out error,\t");
        break;
    default:
        stat.unknown++;
        Serial.print("Unknown error,\t");
        break;
    }
    // DISPLAY DATA
    Serial.print(DHT.humidity, 1);
    Serial.print(",\t");
    Serial.print(DHT.temperature, 1);
    Serial.print(",\t");
    Serial.print(stop - start);

    if (stat.total % 20 == 0)    {
        Serial.println("\nTOT\tOK\tCRC\tTO\tUNK");
        Serial.print(stat.total);
        Serial.print("\t");
        Serial.print(stat.ok);
        Serial.print("\t");
        Serial.print(stat.crc_error);
        Serial.print("\t");
        Serial.print(stat.time_out);
        Serial.print("\t");
        Serial.print(stat.connect);
        Serial.print("\t");
        Serial.print(stat.ack_l);
        Serial.print("\t");
        Serial.print(stat.ack_h);
        Serial.print("\t");
        Serial.print(stat.unknown);
        Serial.println("\n");
    }
}


What I get is this
Code: [Select]
LIBRARY VERSION: 0.1.13

Type, status, Humidity (%), Temperature (C) Time (us)
DHT33, OK, 28.4, 23.5, 5096 delay 500
DHT33, OK, 28.3, 23.5, 5240 delay 10000

DHT33, OK, 28.3, 23.5, 5232 delay 500
DHT33, Time out error, -999.0, -999.0, 6936 delay 10000

DHT33, OK, 28.3, 23.5, 5240 delay 500
DHT33, OK, 29.4, 23.5, 5160 delay 10000

=> directly after last reading breathing upon the sensor to 
=> increse humidity, this is around 9 seconds before next reading

DHT33, OK, 29.4, 23.5, 5152 delay 500    ??? why is this value (29.4) so low ???
DHT33, OK, 74.4, 23.5, 5336 delay 10000  !!! 74.4 is now ok and "wet", but environment did not change in 500 ms !!!   

DHT33, OK, 74.6, 23.5, 5416 delay 500
DHT33, OK, 69.4, 24.3, 5392 delay 10000

DHT33, OK, 68.8, 24.3, 5240 delay 500
DHT33, OK, 55.8, 24.2, 5152 delay 10000

DHT33, OK, 55.2, 24.2, 5112 delay 500
DHT33, OK, 42.0, 23.8, 5232 delay 10000

DHT33, OK, 41.6, 23.8, 5240 delay 500
DHT33, OK, 36.0, 23.8, 5288 delay 10000

=> again: directly after last reading breathing upon the sensor to 
=> increse humidity, this is around 9 seconds before next reading

DHT33, OK, 35.9, 23.8, 5336 delay 500    ??? same behavior, why is this value (35.9) so low ???
DHT33, OK, 87.1, 23.9, 5432 delay 10000 !!! 87.1 is now ok and "wet", but environment did not change in the last 500 ms !!!   

DHT33, OK, 87.9, 23.9, 5424 delay 500
DHT33, OK, 86.1, 24.2, 5288
TOT OK CRC TO UNK
20 19 0 1 0 0 0 0

 delay 10000

DHT33, OK, 84.6, 24.2, 5248 delay 500
DHT33, OK, 48.6, 24.1, 5288 delay 10000

DHT33, OK, 47.5, 24.1, 5384 delay 500
DHT33, OK, 35.9, 24.1, 5296 delay 10000
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Clemens on May 27, 2016, 03:20 pm
The offset problem in my last post was tested with two different DHT33 sensors. To be sure not the sensors types are the problem I tested with DHT22 sensors also: Same result, always this one reading point offset!

The only software fix that is working is reading the sensor twice with a 500 ms delay between:

Code: [Select]

    DHT.read22(DHT22_PIN);
    delay(500);
    int chk = DHT.read22(DHT22_PIN);


But this is not the way I want to go. My nodes are optimized for battery powering and so this is not really a good solution.

I tested it also with the Adafruit DHT lib and the results gone more worse: The update of a "reality" value happened two or three datapoints after the breathing event.

I have the 4k7 resistor (between data and Vcc) on the shield, then a 50 cm cable connects the sensor with the shield, but I have also tested with 10 cm cable also with no better results. Could this have any influence of the offset / delay or additional capacitors I saw on some breakouts? I think not - because I got a reading, but perhaps someone out has better ideas?

I still do not know: it's a hardware problem / knowing issue for the DHT or a software problem on the library?
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: Clemens on May 31, 2016, 03:40 pm
Ok, I have the answer, it's a hardware "problem" but obviously intended by the designers, see http://www.kandrsmith.org/RJS/Misc/Hygrometers/calib_dht22_dht11_sht71.html

Quote
However, the DHT22 caches a reading in memory and returns it whenever a value is next requested.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: MetzgerM on Dec 22, 2016, 05:59 pm
FYI, I just connected a DHT11 to Arduino NANO, using the LIB file and sketch dht_test1 from Arduino site  and it works good.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 23, 2016, 07:27 am
Thanks MetzgerM for this feedback!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: velumani on Apr 13, 2017, 01:43 pm
Arduino: 1.8.2 (Windows 8.1), Board: "Arduino/Genuino Uno"

C:\Users\Admin\AppData\Local\Temp\cc5ZtX3e.ltrans0.ltrans.o: In function `loop':

C:\Users\Admin\Desktop\testing/testing.ino:13: undefined reference to `dht::read11(unsigned char)'

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board Arduino/Genuino Uno.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: MaxG on Apr 27, 2017, 12:59 pm
I am getting this dreaded compile error:

Code: [Select]
D:\Temp\W7Temp\ccHsEcYa.ltrans0.ltrans.o: In function `read22':
D:\MaxG_MyDocuments\Arduino\libraries\DHT/dht.h:63: undefined reference to `dht::read(unsigned char)'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling.


dht.h and dht.cpp are in a folder DHT in libraries (where all other libraries are)

A different IDE gives me this error:

Code: [Select]
D:\Temp\W7Temp\ccSTkO5j.ltrans0.ltrans.o: In function `read22':
D:\Prog\sloeber\arduinoPlugin\libraries_added\DHT/dht.h:63: undefined reference to `dht::read(unsigned char)'
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:92: RoomControllerV0.elf] Error 1


No idea how to fix it... :(

Any hints appreciated...
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Apr 27, 2017, 06:52 pm
Have you tried the example sketches that come with the library?

Which board are you using?

What version of the IDE?

Can you post the sketch you use?


Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: MaxG on Apr 28, 2017, 01:14 am
Sorry for being unspecific... and thank you for your reply.

I used the github files and example...
Arduino IDE 1.6.7 -- which I only use to verify and validate any problem(s); e.g. like this I encounter, otherwise I use the Sloeber IDE for my UNO developments.

As I said before
create folder DHT, create file dht.cpp, dht.h, create example folder, create dht_test.ino; open Arduino IDE; open dht_test.ino, change DHT pin; at first leave the file intact; then deleted all but the DHT22 section -- same result = error msg when compiling.
When I googled this error, I found quite a few of the same problem, but no resolution.

As such, not so promising outlook and needing an immediate solution, I deleted the DHT library and downloaded/used the AdaFruit DHT library, which worked spot on.
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Apr 28, 2017, 11:05 am
OK good to hear you have it woirking

For my information, do you recall which version of the lib you were using, as I want to keep it as stable as possible.

Thx
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: MaxG on Apr 28, 2017, 11:17 am
Hi Rob,

No disrespect... I appreciate putting your work out there for others to use!

I took the files from GitHub as they were yesterday...
Proceeded as described; got the same compile error  in both IDEs...
Looked for an alternative, tested the AdaFruit library... worked, done.

Cheers, Max
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Apr 29, 2017, 05:32 pm
Thanks,

The latest version is an expirimental version,

The latest stable is - https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 12, 2017, 10:20 pm
Updated the DHTlib and DHTstable to support DHT12 and AM23XX.

- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib (experimental AVR version)
- https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTstable (stable)


Comments and remarks as always welcome
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: FooPlinger on Dec 22, 2017, 10:00 pm
So, I have just gotten the DHT11 to work and display values on an OLED, but the sketch I am using helpfully puts an "F" after the temperature, but only displays the temp in Celcius.  I have been digging through posts and websites for the last couple of hours, but have been unsuccessful.  I keep seeing people say use float, but I have no clue what that means, others say it is part of the library, but they must be using a different library than I am.
Using this library, how can I make it display the temperature in Farenheit?

Code: [Select]

#include <U8glib.h>  // U8glib library
#include <dht.h>     // DHT library

#define dht_dpin 2  //  pin to which the sensor is connected
dht DHT;
               /*Uncomment and comment*/
//U8GLIB_SH1106_128X64 u8g(13, 11, 10, 9, 8);  // CLK=13, DIN=11, CS=10, DC=9, Reset=8
//U8GLIB_SSD1306_128X32 u8g(13, 11, 10, 9, 8); // CLK=13, DIN=11, CS=10, DC=9, Reset=8
U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9, 8); // CLK=13, DIN=11, CS=10, DC=9, Reset=8

void draw(void)
{
   u8g.setFont(u8g_font_fub11r);   // select font
   u8g.drawStr(0, 11, "Temp: ");   // put string of display at position X, Y
   u8g.drawStr(80, 11, "Humi: ");
   u8g.setFont(u8g_font_fub14r);
   u8g.setPrintPos(10, 45);        // set position
   u8g.print(DHT.temperature, 0);  // display temperature from DHT11 in Celsius
   u8g.println("F");
   u8g.setPrintPos(72, 45);        // set position
   u8g.print(DHT.humidity, 0);     // display humidity from DHT11
   u8g.println("%");
}
void setup(void)
{

}

void loop(void)
{
   DHT.read11(dht_dpin);  // Read dpin on DHT11
   u8g.firstPage(); 
   do
{
   draw();
}  while( u8g.nextPage() );
   delay(5000);  // Delay of 2 sec before accessing DHT11 (min - 2sec)
}
                           /*END OF FILE*/
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 23, 2017, 12:57 am
>> Using this library, how can I make it display the temperature in Farenheit?

You can convert any Celsius temperature to Fahrenheit, that does not depend on the sensor.


float Tc = someObject.getTemperatureC(....);

float Tf = Tc * 1.8 + 32;

you should add this formula into your sketch.


Some interesting temperature is -40C as that is also -40F;  And 100F is about human body temperature.

The Celsius scale is based on the physics of water (melting/boiling)  @ 1013 hPa  or 1 atmosphere or sea level pressure.

More fun is the Kelvin scale as it has no negative temperatures in practice.



Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: FooPlinger on Dec 23, 2017, 04:58 pm
After some trial and error, it seems that float is mostly working, but now it displays 32F all the time.  I changed the formula to add 33 in the conversion, and it displays 33.   Seems the float is being set to the last number in the conversion formula?

               /*Uncomment and comment*/
//U8GLIB_SH1106_128X64 u8g(13, 11, 10, 9, 8);  // CLK=13, DIN=11, CS=10, DC=9, Reset=8
//U8GLIB_SSD1306_128X32 u8g(13, 11, 10, 9, 8); // CLK=13, DIN=11, CS=10, DC=9, Reset=8
U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9, 8); // CLK=13, DIN=11, CS=10, DC=9, Reset=8

float Tc = DHT.temperature;
float Tf =  (Tc*1.8+32);

void draw(void)
{
   u8g.setFont(u8g_font_fub11r);   // select font
   u8g.drawStr(0, 11, "Temp: ");   // put string of display at position X, Y
   u8g.drawStr(80, 11, "Humi: ");
   u8g.setFont(u8g_font_fub14r);
   u8g.setPrintPos(10, 45);        // set position
   u8g.print(Tf, 0);
//   u8g.print(DHT.temperature, 0);  // display temperature from DHT11 in Celsius
   u8g.println("F");
   u8g.setPrintPos(72, 45);        // set position
   u8g.print(DHT.humidity, 0);     // display humidity from DHT11
   u8g.println("%");
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: FooPlinger on Dec 23, 2017, 08:01 pm
After more searching and work, it seems I just don't understand float.   I finally got it working with the code below.
A few notes.   If I tried to print Tc, it shows 0.  If I print Tf, it shows 32.



Code: [Select]

#include <U8glib.h>  // U8glib library
#include <dht.h>     // DHT library

#define dht_dpin 2  //  pin to which the sensor is connected
dht DHT;
               /*Uncomment and comment*/
//U8GLIB_SH1106_128X64 u8g(13, 11, 10, 9, 8);  // CLK=13, DIN=11, CS=10, DC=9, Reset=8
//U8GLIB_SSD1306_128X32 u8g(13, 11, 10, 9, 8); // CLK=13, DIN=11, CS=10, DC=9, Reset=8
U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9, 8); // CLK=13, DIN=11, CS=10, DC=9, Reset=8

//float Tc = DHT.temperature;
//float Tf = Tc * 1.8 + 32;
//float Tf = (32 + (DHT.temperature * 1.8));

void draw(void)
{
   u8g.setFont(u8g_font_fub11r);   // select font
   u8g.drawStr(0, 11, "Temp: ");   // put string of display at position X, Y
   u8g.drawStr(80, 11, "Humi: ");
   u8g.setFont(u8g_font_fub14r);
   u8g.setPrintPos(10, 45);        // set position
//   u8g.print(Tc, 0);
//   u8g.print(Tf, 0);
   u8g.print((DHT.temperature * 1.8 + 32), 0);  // display temperature from DHT11 in Fahreneit
   u8g.println("F");
   u8g.setPrintPos(72, 45);        // set position
   u8g.print(DHT.humidity, 0);     // display humidity from DHT11
   u8g.println("%");
}
void setup(void)
{

}

void loop(void)
{
   DHT.read11(dht_dpin);  // Read dpin on DHT11
   u8g.firstPage(); 
   do
{
   draw();
}  while( u8g.nextPage() );
   delay(5000);  // Delay of 2 sec before accessing DHT11 (min - 2sec)
}
                           /*END OF FILE*/
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 23, 2017, 11:19 pm

Replace

Code: [Select]
u8g.print((DHT.temperature * 1.8 + 32), 0);  // display temperature from DHT11 in Fahreneit

by

Code: [Select]

float f = DHT.temperature * 1.8 + 32;
int whole = (int)f;  // take the whole part of the float
int decimal = (int) ((f-whole)*10);   // first decimal
u8g.print(whole);
u8g.print(".");
u8g.print(decimal);

splitting it up in pieces can help.



footnote:
The DHT11 has only integer values for temperature and humidity, so no need to use floats there.


Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: FooPlinger on Dec 24, 2017, 05:46 pm
It looks like my problem was putting the float and calculations between lines 9 and 11, and then trying to print them later.  Once I moved your code all together inside the "void draw(void) " section, it works fine.

Thank you for the help, now I am off to see how to log this somewhere.  I have a dirt floor and cinder-block room under my brick porch on my new house that I want to use as a root cellar.  I am looking to log the data every x minutes (maybe ten, maybe 30) and keep those values so I can track it throughout the year.   I will also be putting a second dht11 outside of the root cellar to record the differences between the two.

Merry Christmas!
Title: Re: Class for DHT11, DHT21 and DHT22 (temperature & humidity)
Post by: robtillaart on Dec 24, 2017, 06:19 pm
Better use a DHT22 as it more accurate and supports below zero (Celsius) temperatures.

did you do the storage math?

1 sample == 50 bytes? (including timestamp)

every 10 seconds --> 6 / minute  --> 360 / hour --> 9000 /day --> 3.300.000 / year ==> 165 MB