Arduino Forum

Development => Other Software Development => Topic started by: niesteszeck on Mar 22, 2013, 03:51 pm

Title: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: niesteszeck on Mar 22, 2013, 03:51 pm
Hello, I'm working with DuinOS and the DHT11 library has some problems working with it 'cause the timing. 'cause of this i had improved the library to use ineterrupts on pins and liberate the cpu meanwhile. I have proved it in a Mega2560 with arduino 1.03 and is working bery well.

You can get this lib at
https://github.com/niesteszeck/idDHT11 (https://github.com/niesteszeck/idDHT11)
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: robtillaart on Mar 22, 2013, 07:58 pm
Looks good!

I can see only one remark that is STOPPED is with double P ;)

I'll make a link in the playground article - http://playground.arduino.cc/Main/DHT11Lib - to this thread so people can find it easier!
(done)
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: niesteszeck on Mar 22, 2013, 09:07 pm
Sorry for that (I speek spanish as my native language)
Now is corrected
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: robtillaart on Mar 23, 2013, 07:34 pm
No need to apologize for a great job!
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: chuckiecc on Jul 03, 2013, 02:43 am
Hi can someone help please with newb question.  Trying to read temp/rh with the dht11.  In the code samples and examples I came across a VERY cool code example that not only reads temp/rh BUT reads dewpoint calcs.  Which is very useful for me.  Only problem is that being a NEWB Im sure that Im doing something wrong in loading the code to the Arduino.

Arduino Mega 2560
Mega shield

So code that has information I want is here-

http://playground.arduino.cc//Main/DHT11Lib?action=sourceblock&num=1

but when I try to compile/upload, i get the error message "DHT11 does NOT have a name"  ARRGGHH....

now I notice that along with this code there are two other files
one labeled
dht11.h (code is here http://playground.arduino.cc//Main/DHT11Lib?action=sourceblock&num=2)

the other labeled
dht11.cpp (code is here http://playground.arduino.cc//Main/DHT11Lib?action=sourceblock&num=3)

so not sure (because I am a newb) if these are necessary? help define the name of the DHT or what.. 

Can someone help please..

thanks again for your patience in advance..
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: niesteszeck on Jul 03, 2013, 03:59 pm
Hello, your question isn't related to this specific lib. You are using example code and source files from the original DHT11 lib. THIS lib that I published here is another version, that works different (interrupt driven way) and has his own example codes. If you want you can try it downloading it from the link to github in the original post of this thread.
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: robtillaart on Jul 03, 2013, 08:05 pm
@niesteszeck

Can this DHT22 patch be included in the library?   - http://forum.arduino.cc/index.php?topic=175356.0 -

imho it is worth the effort to merge!
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: niesteszeck on Jul 03, 2013, 08:29 pm
I'm talking on the other thread. If the modification is working on a dht22 sensor, I'll analyze how to mix both sensors in the same library, other way we have to make 2 libraries. Other thing is that I dont have a dht22 sensor, so any modification must be proved by others (or someone can gift me one :D)
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: robtillaart on Jul 03, 2013, 08:51 pm
It should be quite easy to add DHT22 support into one library
- add a flag that indicates the type and select the right - bits to data -  function in the end.

the code in the other thread looks good to me, so I think you can start designing/integrating to create a first beta.

Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: niesteszeck on Jul 03, 2013, 09:06 pm
Yes sure, but the modification to DATA section on the interrupt that is proposed on http://forum.arduino.cc/index.php?topic=175356.0 I need to confirm that is actually working to integrate into the other library.

Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: robtillaart on Jul 03, 2013, 09:22 pm
Or you can build it into the lib and you have something to be verified by someone.
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: niesteszeck on Jul 04, 2013, 04:57 am
That's right. I'll make it for DHT22 to, but give me some time to do it, I'm working and don't have to much time to my personal projects, so please be patient. I'm goig to continue this conversation on the other thread
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: Tero521 on Mar 21, 2014, 04:24 pm
Is it possible to use multiple dht11 sensors with this library?
The test so far only reports -7 for second sensor.
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: niesteszeck on Mar 21, 2014, 09:01 pm
I'm not pretty sure if it's working with two sensors, but I have two, and when I was developing it I used the 2. If I'm not wrong it should work with two sensors. The only thing is that you have to use 2 different pins that has interrupts

In a quick review, I can say that looks like the interrupt is not being called. What method are you calling to get the -7 value, can you share the code.

A small example that is based on the example that comes with the lib:
Code: [Select]

/*
 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)
*/

#include <idDHT11.h>

int idDHT11pinA = 2; //Digital pin for comunications
int idDHT11intNumberB = 0; //interrupt number (must be the one that use the previus defined pin (see table above)
int idDHT11pinB = 3; //Digital pin for comunications
int idDHT11intNumberB = 1; //interrupt number (must be the one that use the previus defined pin (see table above)

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

// Lib instantiate
idDHT11 DHT11A(idDHT11pinA,idDHT11intNumberA,dht11_wrapperA);
idDHT11 DHT11B(idDHT11pinB,idDHT11intNumberB,dht11_wrapperB);

// This wrapper is in charge of calling
// mus be defined like this for the lib work
void dht11_wrapperA() {
 DHT11A.isrCallback();
}
// This wrapper is in charge of calling
// mus be defined like this for the lib work
void dht11_wrapperB() {
 DHT11B.isrCallback();
}



if you test this small example (need to be completed the loop and setup functions), please tell me how it goes. If it works, you can make a pull request to add an example that use 2 sensors on github, so everyone wins. If not, we can review why and analyze if it will be possible and add this functionality to the lib, anyway, everyone wins :).
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: Tero521 on Mar 23, 2014, 12:34 pm
Sorry for the long wait, i was swamped by another aspect of my project.
Now it's working. The problem was the missing
Code: [Select]
DHT11B.acquire();
Is there any other reason than debugging purpose for this part of code?
Code: [Select]
while (DHT11A.acquiring())
   ;
 int result = DHT11A.getStatus();
 switch (result)
 {
   case IDDHTLIB_OK:
     Serial.println("OK");
     break;
   case IDDHTLIB_ERROR_CHECKSUM:
     Serial.println("Error\n\r\tChecksum error");
     break;
   case IDDHTLIB_ERROR_ISR_TIMEOUT:
     Serial.println("Error\n\r\tISR Time out error");
     break;
   case IDDHTLIB_ERROR_RESPONSE_TIMEOUT:
     Serial.println("Error\n\r\tResponse time out error");
     break;
   case IDDHTLIB_ERROR_DATA_TIMEOUT:
     Serial.println("Error\n\r\tData time 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;
 }

because it work just fine without it, and i didn't figured out how to change it for the second sensor.

Here is the modified code. Sorry for the bad formating  :smiley-red:
Code: [Select]
/*
 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)
*/

#include <idDHT11.h>

int idDHT11pinA = 2; //Digital pin for comunications
int idDHT11intNumberA = 0; //interrupt number (must be the one that use the previus defined pin (see table above)
int idDHT11pinB = 3; //Digital pin for comunications
int idDHT11intNumberB = 1; //interrupt number (must be the one that use the previus defined pin (see table above)

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

// Lib instantiate
idDHT11 DHT11A(idDHT11pinA, idDHT11intNumberA, dht11_wrapperA);
idDHT11 DHT11B(idDHT11pinB, idDHT11intNumberB, dht11_wrapperB);




void setup()
{
 Serial.begin(115200);
 Serial.println("idDHT11 Example program for two sensors");
 Serial.print("LIB version: ");
 Serial.println(IDDHT11LIB_VERSION);
 Serial.println("---------------");
}
// This wrapper is in charge of calling
// mus be defined like this for the lib work
void dht11_wrapperA() {
 DHT11A.isrCallback();
}
// This wrapper is in charge of calling
// mus be defined like this for the lib work
void dht11_wrapperB() {
 DHT11B.isrCallback();
}
void loop()
{
 Serial.print("\nRetrieving information from sensors: ");
 Serial.print("Read sensor: ");
 //delay(100);
 DHT11B.acquire();
 DHT11A.acquire();
 while (DHT11A.acquiring())
   ;
 int result = DHT11A.getStatus();
 switch (result)
 {
   case IDDHTLIB_OK:
     Serial.println("OK");
     break;
   case IDDHTLIB_ERROR_CHECKSUM:
     Serial.println("Error\n\r\tChecksum error");
     break;
   case IDDHTLIB_ERROR_ISR_TIMEOUT:
     Serial.println("Error\n\r\tISR Time out error");
     break;
   case IDDHTLIB_ERROR_RESPONSE_TIMEOUT:
     Serial.println("Error\n\r\tResponse time out error");
     break;
   case IDDHTLIB_ERROR_DATA_TIMEOUT:
     Serial.println("Error\n\r\tData time 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.println("************************************************************");
 Serial.println("*********************************Sensor 1*******************");
 Serial.println("************************************************************");
 Serial.print("Humidity (%): ");
 Serial.println(DHT11A.getHumidity(), 2);

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

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

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

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

 Serial.print("Dew Point Slow (oC): ");
 Serial.println(DHT11A.getDewPointSlow());
 Serial.println("************************************************************");
 Serial.println("*********************************Sensor 2*******************");
 Serial.println("************************************************************");
 Serial.print("Humidity (%): ");
 Serial.println(DHT11B.getHumidity(), 2);

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

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

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

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

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

 delay(2000);
}
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: niesteszeck on Mar 24, 2014, 01:43 pm
I've added an example that use 2 sensor, please try it at
https://github.com/niesteszeck/idDHT11/tree/master/examples/idDHT11_Lib_2sensors_example (https://github.com/niesteszeck/idDHT11/tree/master/examples/idDHT11_Lib_2sensors_example)

One problem with your example is that it doesn't check if the B sensor end acquiring. so maybe sometimes you could get error values.

The part that you said is for debugging, is only to know which error was causing a problem. you can erase it, but you should do something like this to be sure you receive a good measure

Code: [Select]

....
while (DHT11A.acquiring()) // check if first sensor has ended acquiring
    ;
int result = DHT11A.getStatus();
if(result != IDDHTLIB_OK)
   //HANDLE THE ERROR
   ...... 
} else {
   // DO WHATEVER YOU WANT with the data of the sensor
   ......
}

Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: Tero521 on Mar 30, 2014, 10:36 am
Thank you, that works like a charm.
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: petoulachi on Dec 04, 2015, 09:33 am
Hello,

I'm trying to use idDHTLib with a DHT22 on a Pro 5V, using port 3 on the Pro (and therefore interrupt number 1).
But I cannot read any value, everytime I've got a CheckSum error.

Any idea of what I'm doing wrong ?


Regards,

edit : ok my very bad, I do not noticed I had to change the callback method. Sorry !
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: miltonortega on May 27, 2016, 05:11 pm
buenos dias,

cordial saludo serian tan amables de ayudarmen en este error que me sale al cargar el programa.

soy novato o nuevo en este campo.


sketch_may27a.ino:17:17: fatal error: DHT.h: No such file or directory
compilation terminated.
Error de compilaciĆ³n


gracias    david
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: markfrencken on Jan 28, 2017, 11:47 pm
Hi, very nice library.

I would like to make an addition to catch a transmission timeout while recieving a talagram, for example due to a bad connection (dupont wires anyone):


/*
   FILE:       idDHT11.cpp
   VERSION:    0.1
   PURPOSE:    Interrupt driven Lib for DHT11 with Arduino.
   LICENCE:   GPL v3 (http://www.gnu.org/licenses/gpl.html)
   DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf
   
   Based on DHT11 library: http://playground.arduino.cc/Main/DHT11Lib
*/

#include "idDHT11.h"
#define DEBUG_IDDHT11

idDHT11::idDHT11(int pin, int intNumber,void (*callback_wrapper)()) {
   init(pin, intNumber,callback_wrapper);
}

void idDHT11::init(int pin, int intNumber, void (*callback_wrapper) ()) {
   this->intNumber = intNumber;
   this->pin = pin;
   this->isrCallback_wrapper = callback_wrapper;
   hum = 0;
   temp = 0;
   pinMode(pin, OUTPUT);
   digitalWrite(pin, HIGH);
   state = STOPPED;
   status = IDDHTLIB_ERROR_NOTSTARTED;
}

int idDHT11::acquire() {
   if (state == STOPPED || state == ACQUIRED) {
      
      //set the state machine for interruptions analisis of the signal
      state = RESPONSE;
      
      // EMPTY BUFFER and vars
      for (int i=0; i< 5; i++) bits = 0;
      cnt = 7;
      idx = 0;
      hum = 0;
      temp = 0;
   
      // REQUEST SAMPLE
      pinMode(pin, OUTPUT);
      digitalWrite(pin, LOW);
      delay(18);
      digitalWrite(pin, HIGH);
      delayMicroseconds(40);
      pinMode(pin, INPUT);
      
      // Analize the data in an interrupt
      us = micros();
      us_global = us;
      attachInterrupt(intNumber,isrCallback_wrapper,FALLING);
      
      return IDDHTLIB_ACQUIRING;
   } else
      return IDDHTLIB_ERROR_ACQUIRING;
}
int idDHT11::acquireAndWait() {
   acquire();
   while(acquiring())
      ;
   return getStatus();
}
void idDHT11::isrCallback() {
   int newUs = micros();
   int delta = (newUs-us);
   us = newUs;
   if (delta>6000) {
      status = IDDHTLIB_ERROR_ISR_TIMEOUT;
      state = STOPPED;
      detachInterrupt(intNumber);
      return;
   }
   switch(state) {
      case RESPONSE:
         if(delta<25){
            us -= delta;
            break; //do nothing, it started the response signal
         } if(125<delta && delta<190) {
            state = DATA;
         } else {
            detachInterrupt(intNumber);
            status = IDDHTLIB_ERROR_RESPONSE_TIMEOUT;
            state = STOPPED;
         }
         break;
      case DATA:
         if(delta<10) {
            detachInterrupt(intNumber);
            status = IDDHTLIB_ERROR_DELTA;
            state = STOPPED;
         } else if(60<delta && delta<155) { //valid in timing
            if(delta>90) //is a one
               bits[idx] |= (1 << cnt);
            if (cnt == 0) {  // whe have fullfilled the byte, go to next
                  cnt = 7;    // restart at MSB
                  if(idx++ == 4) {      // go to next byte, if whe have got 5 bytes stop.
                     detachInterrupt(intNumber);
                     // WRITE TO RIGHT VARS
                     // as bits[1] and bits[3] are allways zero they are omitted in formulas.
                     hum    = bits[0];
                     temp = bits[2];
                     uint8_t sum = bits[0] + bits[2]; 
                     if (bits[4] != sum) {
                        status = IDDHTLIB_ERROR_CHECKSUM;
                        state = STOPPED;
                     } else {
                        status = IDDHTLIB_OK;
                        state = ACQUIRED;
                     }
                     break;
                  }
            } else cnt--;
         } else {
            detachInterrupt(intNumber);
            status = IDDHTLIB_ERROR_DATA_TIMEOUT;
            state = STOPPED;
         }
         break;
      default:
         break;
   }
}
bool idDHT11::acquiring() {
   int newUs = micros();
   if (state != ACQUIRED && state != STOPPED)
   {
      if (newUs-us_global>6000)   
        {
          status = IDDHTLIB_ERROR_ISR_TIMEOUT;
          state = STOPPED;
          detachInterrupt(intNumber);
           return false;
        }
        else
        {
          return true;           
        }
    }
    else
    {
       return false;
   }
}
int idDHT11::getStatus() {
   return status;
}
float idDHT11::getCelsius() {
   IDDHT11_CHECK_STATE;
   return temp;
}

float idDHT11::getHumidity() {
   IDDHT11_CHECK_STATE;
   return hum;
}

float idDHT11::getFahrenheit() {
   IDDHT11_CHECK_STATE;
   return temp * 1.8 + 32;
}

float idDHT11::getKelvin() {
   IDDHT11_CHECK_STATE;
   return temp + 273.15;
}

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double idDHT11::getDewPoint() {
   IDDHT11_CHECK_STATE;
   double a = 17.271;
   double b = 237.7;
   double temp_ = (a * (double) temp) / (b + (double) temp) + log( (double) hum/100);
   double Td = (b * temp_) / (a - temp_);
   return Td;
   
}
// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm
double idDHT11::getDewPointSlow() {
   IDDHT11_CHECK_STATE;
   double A0= 373.15/(273.15 + (double) temp);
   double SUM = -7.90298 * (A0-1);
   SUM += 5.02808 * log10(A0);
   SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
   SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
   SUM += log10(1013.246);
   double VP = pow(10, SUM-3) * (double) hum;
   double T = log(VP/0.61078);   // temp var
   return (241.88 * T) / (17.558-T);
}
// EOF
Title: Re: [LIB] Interrupt driven DHT11 Lib (idDHT11)
Post by: Flixon on Nov 25, 2017, 01:33 pm
Hello everybody, i am working on my project and i want use your library there. But i am newbie in this so i don't understand how this interrupt in your example code is working. I thought it's nothing more needed just arduino + sensor DHT11. when i want test your code for one sensor it only shows me what is on this picture https://imgur.com/a/RT7I9. And nothing more happens. It looks like it's waiting for interupt on that interrupt port. I tested all reccomended interrupt ports and still not working. Can you please explain me how your example code working ? Thank you very much :)