[LIB] Interrupt driven DHTLib (DHT11 & DHT22 = idDHTLib)

As turgo kindly ask if someone can add DHT22 functionality to the idDHT11 lib, I make a new lib that can use DHT11 and DHT22 sensors based on the suggestions by pylon.
You can get it from

I have tested it with a DHT11 sensor on a Mega2560 on pin 19 (int4), but I don't have a DHT22 sensor to prove it, so if you have one and can confirm that it is working, please let me know to get out the beta label of the code.

EDIT: Finally is ready. Thanks All for the testing

DHT22 not working, I'm afraid. I did have trouble getting the non-interrupt version to work, however, which I solved by rearranging the construction order of various objects. For some reason the DHT object construction had to be first even though it did nothing meaningful in its constructor, so I wouldn't rule out a problem there. However, I do still have the idDHT object ctor first. I'll try with the barebones example next.

Edit: Scrub that. Now it's working. I didn't even do anything! But temperature is negative and invalid. It's reading -39c when it's actually 25c or so. Humidity might be correct but not sure.

What I 'changed' was seemingly taking the Arduino with sensor upstairs to my bedroom, where it is warmer. The sensor shows -2.00 temp until 25c (reading on another temperature monitor not connected to Arduino) / -39.50c on Arduino. After it reads the values, those values can be obtained but then appears to be permanently 'acquiring' after another acquire() call.

Tested on Uno R3.

I added some wait time between the acquisitions rather than starting a new one straight after getting the results (1 sec) from the one one and it's working a little better, but a lot of the time it's showing -1 for temp and hum. The temperature is still negative and incorrect whenever it shows something not -1.

Just to say, the other Adafruit lib worked great without checksum errors once the problems were fixed, so my wiring should not be at fault.

Whatever you do you need a 2 second delay between calls to the DHTXX, 2.5 seconds is better. It sounds like you are polling it too fast.

Doc

Still getting frequent checksum errors even with 2.5secs. The data and checksum are probably corrupt somehow after being retrieved in idDHTLib.

Hi, thanks for testing it, I'll check it why is failing when I have some time. Please be patient.

any info that you can add that can be useful will be great
Best regards

I supose you are using the example code and you are using the dht22Callback instead of the dht11Callback.

I preferred that you use example code to test it, so we can check the same code to find the bug

I am using the dht22callback :slight_smile: I'll try with the example code today, if you want :slight_smile:

You are telling that the addafruit lib is working, but it still can be some signal/wiring problem. For example the DHT11 module that I use is equipped whit the pullup resistor, are you using one similar? or just the naked sensor without nothing extra (I think for DHT11 is a ~5K pull up, and a 1K for the DH22, but please confirm on the datasheet). I'm just trying to think about all possibilities, 'cause I don't have a sensor to pass over the oscilloscope here and be sure that the signal is right, remember that some small noise in the line can trigger an interrupt, so maybe, really a remote possibility, is the line that triggers to much interrupts so the data get corrupted. If you have an oscilloscope, please, can you check the signal against the datasheet of the sensor.

I someone have any idea? Please I'll be glad to discuses any aproach

I am using both the pull up resistor and cap :slight_smile: Like I say, no checksum errors or anything with the Adafruit lib, if the constructor is initialised in front of all the constructors (I removed parts of my code to find out which bit was causing the issues, and the two codes looked the same, except for the constructor order, and I thought 'hmmm, it couldn't be this, could it? that really makes no sense..'. But to rule out any memory issues I'll try it with the simple example.

Please share a sample code that present that problem and a one that "solve" (where the initialization happens) so I can test it with my dht11 sensor, maybe it happens to

Broken:

#define DHTTYPE DHT22
#define DHTPIN 2     // what pin we're connected to

#include <DHT.h>
DHT dht(DHTTYPE, DHTPIN);

int   dht_chk  = -10;
float dht_hum  = 0;
float dht_temp = 0;

unsigned long dht11lastcheck = 0;

void setup() {
	Serial.begin(9600);
	Serial.println("DHTxx test!");
	dht.begin();
}

void loop() {
	if ((millis() > 5000) && (dht11lastcheck + 5000 < millis())) {
		Serial.println(millis());
		dht_hum  = dht.readHumidity();
		dht_temp = dht.readTemperature(false);
		dht11lastcheck = millis();
		dht_chk = 0;
	}
}

I can't seem to find any working version this code, which is a little strange. Before I did it by re-arranging the constructors when I had some more in a bigger version of the code. The DHT pin is correct.

This DHTTester code works:

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#include "DHT.h"

#define DHTPIN 2     // what pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600); 
  Serial.println("DHTxx test!");
 
  dht.begin();
}

void loop() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
    Serial.print("Humidity: "); 
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: "); 
    Serial.print(t);
    Serial.println(" *C");
  }
}

Any major differences?

Running simple idDHT11 example with dht22callback:

ididDHTLib Example program
LIB version: 0.0.2
---------------

Retrieving information from sensor: Read sensor:

... and then nothing.

With 2 second delay in some places:

Retrieving information from sensor: Read sensor: Error

	Time out error
Humidity (%): -2.00
Temperature (oC): -2.00
Temperature (oF): -2.00
Temperature (K): -2.00
Dew Point (oC): -2.00
Dew Point Slow (oC): -2.00

It repeats this exact output in a loop.

/*
  Board	          int.0	  int.1	  int.2	  int.3	  int.4	  int.5
 Uno, Ethernet	  2       3
 Mega2560         2       3       21      20      19      18
 Leonardo         3       2       0       1
 Due	          (any pin, more info http://arduino.cc/en/Reference/AttachInterrupt)
 
 This example, as difference to the other, make use of the new method acquireAndWait()
 */

#include <idDHTLib.h>

int idDHTLibPin = 2; //Digital pin for comunications
int idDHTLibIntNumber = 0; //interrupt number (must be the one that use the previus defined pin (see table above)

//declaration
void dhtLib_wrapper(); // must be declared before the lib initialization

// Lib instantiate
idDHTLib DHTLib(idDHTLibPin,idDHTLibIntNumber,dhtLib_wrapper);

void setup()
{
  Serial.begin(9600);
  Serial.println("idDHTLib Example program");
  Serial.print("LIB version: ");
  Serial.println(IDDHTLIB_VERSION);
  Serial.println("---------------");
}
// This wrapper is in charge of calling 
// mus be defined like this for the lib work
void dhtLib_wrapper() {
  DHTLib.dht22Callback(); // Change dht11Callback() for a dht22Callback() if you have a DHT22 sensor
}
void loop()
{
  Serial.print("\nRetrieving information from sensor: ");
  Serial.print("Read sensor: ");
  delay(2000);
  
  int result = DHTLib.acquireAndWait();
  switch (result)
  {
  case IDDHTLIB_OK: 
    Serial.println("OK"); 
    break;
  case IDDHTLIB_ERROR_CHECKSUM: 
    Serial.println("Error\n\r\tChecksum error"); 
    break;
  case IDDHTLIB_ERROR_TIMEOUT: 
    Serial.println("Error\n\r\tTime out error"); 
    break;
  case IDDHTLIB_ERROR_ACQUIRING: 
    Serial.println("Error\n\r\tAcquiring"); 
    break;
  case IDDHTLIB_ERROR_DELTA: 
    Serial.println("Error\n\r\tDelta time to small"); 
    break;
  case IDDHTLIB_ERROR_NOTSTARTED: 
    Serial.println("Error\n\r\tNot started"); 
    break;
  default: 
    Serial.println("Unknown error"); 
    break;
  }
  Serial.print("Humidity (%): ");
  Serial.println(DHTLib.getHumidity(), 2);

  Serial.print("Temperature (oC): ");
  Serial.println(DHTLib.getCelsius(), 2);

  Serial.print("Temperature (oF): ");
  Serial.println(DHTLib.getFahrenheit(), 2);

  Serial.print("Temperature (K): ");
  Serial.println(DHTLib.getKelvin(), 2);

  Serial.print("Dew Point (oC): ");
  Serial.println(DHTLib.getDewPoint());

  Serial.print("Dew Point Slow (oC): ");
  Serial.println(DHTLib.getDewPointSlow());

  delay(2000);
}

Dessimat0r:
This DHTTester code works:

// Example testing sketch for various DHT humidity/temperature sensors

// Written by ladyada, public domain

#include "DHT.h"

#define DHTPIN 2     // what pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  Serial.println("DHTxx test!");

dht.begin();
}

void loop() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

// check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *C");
  }
}




Any major differences?

Yes, at least one in my first check, the declaration/initialization of the lib is different, in the first example you use:

DHT dht(DHTTYPE, DHTPIN);

In the second one:

DHT dht(DHTPIN, DHTTYPE);

so, I suppose as the second one is working, that is correct, and the first one have an error in the constructor call

Dessimat0r:
With 2 second delay in some places:

Retrieving information from sensor: Read sensor: Error
Time out error

Humidity (%): -2.00
Temperature (oC): -2.00
Temperature (oF): -2.00
Temperature (K): -2.00
Dew Point (oC): -2.00
Dew Point Slow (oC): -2.00




It repeats this exact output in a loop.



/*
 Board          int.0  int.1  int.2  int.3  int.4  int.5
Uno, Ethernet  2       3
Mega2560         2       3       21      20      19      18
Leonardo         3       2       0       1
Due          (any pin, more info http://arduino.cc/en/Reference/AttachInterrupt)

This example, as difference to the other, make use of the new method acquireAndWait()
*/

#include <idDHTLib.h>

int idDHTLibPin = 2; //Digital pin for comunications
int idDHTLibIntNumber = 0; //interrupt number (must be the one that use the previus defined pin (see table above)

//declaration
void dhtLib_wrapper(); // must be declared before the lib initialization

// Lib instantiate
idDHTLib DHTLib(idDHTLibPin,idDHTLibIntNumber,dhtLib_wrapper);

void setup()
{
 Serial.begin(9600);
 Serial.println("idDHTLib Example program");
 Serial.print("LIB version: ");
 Serial.println(IDDHTLIB_VERSION);
 Serial.println("---------------");
}
// This wrapper is in charge of calling
// mus be defined like this for the lib work
void dhtLib_wrapper() {
 DHTLib.dht22Callback(); // Change dht11Callback() for a dht22Callback() if you have a DHT22 sensor
}
void loop()
{
 Serial.print("\nRetrieving information from sensor: ");
 Serial.print("Read sensor: ");
 delay(2000);
 
 int result = DHTLib.acquireAndWait();
 switch (result)
 {
 case IDDHTLIB_OK:
   Serial.println("OK");
   break;
 case IDDHTLIB_ERROR_CHECKSUM:
   Serial.println("Error\n\r\tChecksum error");
   break;
 case IDDHTLIB_ERROR_TIMEOUT:
   Serial.println("Error\n\r\tTime out error");
   break;
 case IDDHTLIB_ERROR_ACQUIRING:
   Serial.println("Error\n\r\tAcquiring");
   break;
 case IDDHTLIB_ERROR_DELTA:
   Serial.println("Error\n\r\tDelta time to small");
   break;
 case IDDHTLIB_ERROR_NOTSTARTED:
   Serial.println("Error\n\r\tNot started");
   break;
 default:
   Serial.println("Unknown error");
   break;
 }
 Serial.print("Humidity (%): ");
 Serial.println(DHTLib.getHumidity(), 2);

Serial.print("Temperature (oC): ");
 Serial.println(DHTLib.getCelsius(), 2);

Serial.print("Temperature (oF): ");
 Serial.println(DHTLib.getFahrenheit(), 2);

Serial.print("Temperature (K): ");
 Serial.println(DHTLib.getKelvin(), 2);

Serial.print("Dew Point (oC): ");
 Serial.println(DHTLib.getDewPoint());

Serial.print("Dew Point Slow (oC): ");
 Serial.println(DHTLib.getDewPointSlow());

delay(2000);
}

I see that is the "simple" example, have you tried the other example?

I have added a new branch to the lib that have more detailed timeout error (we can see wich of the three time out error is causing the problem)
Please try this modification to see the output so we can figure aout, what part of the code is generating the timeout. The new branch is called dht22_bug_detect and you can download it from GitHub - niesteszeck/idDHTLib at dht22_bug_detect