Go Down

Topic: Arduino - Temperature & Humidity DHT11 without delay example (Read 7009 times) previous topic - next topic

nathanas

May 27, 2012, 02:38 pm Last Edit: May 27, 2012, 02:47 pm by nathanas Reason: 1
Hi there!
I've been using the DHT11 sensor a lot and I spent time making the code its time. So I made a sketch example so anyone can use it.
I've been hoping that you can post my code to the examples, because its frustrating for new arduino users to use the DHT11 example code directly.
It also is very slow (2seconds delay in each loop).

So I made a sketch to match all your needs.
It reads the sensor every 2 seconds without delays.
The user can also use the temperature and humidity values directly as an integer and compare it to other values without making new arrays.


Please check it out and let me know if you find any errors.

Code: [Select]
/*  DHT11 Example Sketch Code for reading the sensor without delay on your program!
Example Code by: Nick Athanasoulas
Date: 27/5/2012
FUNCTION: It reads the sensor every 2 seconds without delays.
The user can also use the temperature and humidity values directly as an integer
and compare it to other values without making new arrays.
*/
#define DHT11_PIN 4      // ADC0  Define the ANALOG Pin connected to DHT11 Sensor
int temp1[3];                //Temp1, temp2, hum1 & hum2 are the final integer values that you are going to use in your program.
int temp2[3];                // They update every 2 seconds.
int hum1[3];
int hum2[3];

byte read_dht11_dat()
{
 byte i = 0;
 byte result=0;
 for(i=0; i< 8; i++){


   while(!(PINC & _BV(DHT11_PIN)));  // wait for 50us
   delayMicroseconds(30);

   if(PINC & _BV(DHT11_PIN))
     result |=(1<<(7-i));
   while((PINC & _BV(DHT11_PIN)));  // wait '1' finish


 }
 return result;
}


long dht11delay_previousMillis = 0;        // will store last time LED was updated
long dht11delay_interval = 1000;           // dht11delay_interval at which to blink (milliseconds)

void setup()
{
 DDRC |= _BV(DHT11_PIN);
 PORTC |= _BV(DHT11_PIN);

 Serial.begin(9600);
Serial.println("DHT11 without delay");
Serial.println("Example code by: Nick Athanasoulas");
 Serial.println("Ready");
 delay(1000);
}

void loop()
{




 unsigned long dht11delay_currentMillis = millis();

 if(dht11delay_currentMillis - dht11delay_previousMillis > dht11delay_interval) {
   // save the last time you blinked the LED
   dht11delay_previousMillis = dht11delay_currentMillis;  
   byte dht11_dat[5];
   byte dht11_in;
   byte i;
   // start condition
   // 1. pull-down i/o pin from 18ms
   PORTC &= ~_BV(DHT11_PIN);
   delay(18);
   PORTC |= _BV(DHT11_PIN);
   delayMicroseconds(40);

   DDRC &= ~_BV(DHT11_PIN);
   delayMicroseconds(40);

   dht11_in = PINC & _BV(DHT11_PIN);

   if(dht11_in){
     Serial.println("dht11 start condition 1 not met");
     return;
   }
   delayMicroseconds(80);

   dht11_in = PINC & _BV(DHT11_PIN);

   if(!dht11_in){
     Serial.println("dht11 start condition 2 not met");
     return;
   }
   delayMicroseconds(80);
   // now ready for data reception
   for (i=0; i<5; i++)
     dht11_dat[i] = read_dht11_dat();

   DDRC |= _BV(DHT11_PIN);
   PORTC |= _BV(DHT11_PIN);

   byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];
   // check check_sum
   if(dht11_dat[4]!= dht11_check_sum)
   {
     Serial.println("DHT11 checksum error");
   }



   temp1[0]=dht11_dat[2];
   temp2[0]=dht11_dat[3];
   Serial.print("Temperature: ");
   Serial.print(temp1[0]);
   Serial.print(".");
   Serial.print(temp2[0]);
   Serial.print(" C");
   Serial.print("    ");
   hum1[0]=dht11_dat[0];
   hum2[0]=dht11_dat[1];
   Serial.print("Humidity: ");
   Serial.print(hum1[0]);
   Serial.print(".");
   Serial.print(hum2[0]);
   Serial.println("%");

 }
}
// END OF CODE

robtillaart


Seems like working code (did not test it) - recognize the handshake, CRC checking etc - would prefer it in a separate class.

For the DHT11 there is no decimal part so it makes not much sense to print allways .0 for temp and humidity.

Another drawback is that not all pins are possible because you hardcoded PORTC ...

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

nathanas

It seems to be a problem sometimes though.
The DHT11 is not communicating because of a program error.
I get "dht11 start condition 1 not met"

Many have the same problem. I found a post of someone that has fixed this error. But his code is not compiling. Please take a look, because sometimes Arduino can't see the readings correctly.

http://linux-utils.blogspot.com/2010/10/dht11-arduino-with-virtualwire.html?showComment=1338136957757#c8321490607167585796

nathanas

The ground Pin of the DHT11 was broken. That's why I received the "dht11 start condition 1 not met" error.

All are working like a charm now!

robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Thinkerion

i know this topic is old but i have a question about this code,,

as it is i have a lot of things i am going to hook up to the arduino at the same time and i need to avoid any delays.

right now i have a clock and an lcd hooked up through I2c units, meaning both on pin A4, and A5.
I will add two DHT11 sensors and some other temperature sensors, moisture sensors some relays to controll 230V feed, IR controll to change temperature and moisture settings and a servo.

hence i need all my code to be seamless without Delays.

i see there are delayMicroseconds in this loop will it disrupt the other actions ?   
And how should i write the code to be non disruptive?

robtillaart

The handshake of the DHT11 is quite timing sensitive. Most libraries for it are blocking but there is at least one that uses interrupts
discussed here - http://forum.arduino.cc/index.php/topic,155800.0.html -

That might be what you are looking for.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up