Main > Diary > Development

« XBee Pulse I/O | Main | Israel, you're delicious. »

February 20, 2012

Arduino DHT22 Library Improvement

Rob Faludi and I have been teaching a class at the International Center for Theoretical Physics in Trieste, Italy. Marco Zennaro furnished us with a number of DHT22-based Grove Temperature and Humidity Sensors for Seeed Studio. The example code on the Seeed wasn't very robust nor parameterized to work on any Arduino pin so I took a few moments to make some changes. There are now two files:

DHT22.h:

#ifndef DHT22_H
#define DHT22_H

enum DHT22_Err_t {
  DHT22_ERR_NONE = 0,
  DHT22_ERR_HUNG = 1,
  DHT22_ERR_SYNC = 2,
  DHT22_ERR_CHKSUM = 3,
};

DHT22_Err_t getDHT22(int pin, float *temperature, float *humidity);

#endif

DHT22.ino:

#include "DHT22.h"

static byte _read_dht22_dat(volatile uint8_t *in, uint8_t bitmask)
{
  byte i = 0;
  byte result=0;
  for(i=0; i< 8; i++){
    while(!(*in & bitmask));  // wait for 50us
    delayMicroseconds(30);
 
    if(*in & bitmask) 
      result |=(1<<(7-i));
    while((*in & bitmask));  // wait '1' finish
  }
  return result;
}

DHT22_Err_t getDHT22(int pin, float *temperature, float *humidity)
{
  byte dht22_dat[5];
  byte dht22_in;
  byte i;

  uint8_t bitmask = digitalPinToBitMask(pin);
  volatile uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *reg, *out, *in;

  // setup registers and pins
  reg = portModeRegister(port);
  out = portOutputRegister(port);
  in =  portInputRegister(port);
  *reg |= bitmask;
  *out |= bitmask;

  // start condition
  // 1. pull-down i/o pin from 18ms
  *out &= ~bitmask;
  delay(18);
  *out |= bitmask;
  delayMicroseconds(40);
 
  *reg &= ~bitmask;
  delayMicroseconds(40);
 
  dht22_in = *in & bitmask;
 
  if(dht22_in){
    Serial.println("dht22 start condition 1 not met");
    return DHT22_ERR_HUNG;
  }
  delayMicroseconds(80);
 
  dht22_in = *in & bitmask;
 
  if(!dht22_in){
    return DHT22_ERR_SYNC;
  }
  delayMicroseconds(80);
  // now ready for data reception
  for (i=0; i<5; i++)
    dht22_dat[i] = _read_dht22_dat(in, bitmask);
 
  *reg |= bitmask;
  *out |= bitmask;
 
  byte dht22_check_sum = dht22_dat[0]+dht22_dat[1]+dht22_dat[2]+dht22_dat[3];
  // check check_sum
  if(dht22_dat[4]!= dht22_check_sum)
  {
    return DHT22_ERR_CHKSUM;
  }
  
  *humidity=((float)(dht22_dat[0]*256+dht22_dat[1]))/10;
  *temperature=((float)(dht22_dat[2]*256+dht22_dat[3]))/10;
 
  return DHT22_ERR_NONE; 
}

This can be used as in in the following example:

#include "DHT22.h"

void setup() {
  Serial.begin(9600);
  delay(2000); // Recommended delay before sensor can be used
}

void loop() {
  DHT22_Err_t result;
  float temperature = 0, humidity = 0;
  
  result = getDHT22(4, &temperature, &humidity);  
  if (result != DHT22_ERR_NONE)
  {
    delay(5000);
    return;
  }
  
  Serial.print("Current humdity = ");
  Serial.print(humidity,1);
  Serial.print("%  ");
  Serial.print("temperature = ");
  Serial.print(temperature,1);
  Serial.println("C  ");
  delay(5000);
}

You may download the file ICTP_DHT22_XIG.zip. It contains a slightly enhanced example which transmits the information to the XBee Internet Gateway.

Posted by jordanh at February 20, 2012 6:46 AM |

Trackback Pings

TrackBack URL for this entry:
http://jordan.husney.com/mt/mt-tb.cgi/415.

Comments

Hi,

my board is a arduino mega 2560.
The following error has appeared:
undefined reference to `getDHT22(int, float*, float*)'
What is wrong ?

Posted by: Bernd at August 23, 2012 12:13 AM

It sounds like you don't have the DHT22.ino and DHT22.h files in your sketch folder. When you downloaded this ZIP file from this post, how did you try to use them?

Posted by: Jordan at August 23, 2012 8:52 AM

I have found the error. Thank you.

Bernd

Posted by: Bernd [TypeKey Profile Page] at August 27, 2012 12:45 AM

This library saved my project. Was about to replace DHT22 with some different humidity sensor. All those problems with changing serial baud rates, which somehow impact "delayMicroseconds" in all the other libraries were intolerable. Thanks a lot!

Posted by: flegmatoid at September 1, 2013 11:50 AM

I also had the same error. The fix was to include
#include "Arduino.h"
in the DHT22.h

Posted by: JuhaK at February 14, 2014 3:57 PM

Continuing the previous post...
The error message was this 'undefined reference to...'
And the complete fix was:
- #include "Arduino.h"
in the DHT22.h (3rd row)
- DHT22.ino was changed to DHT22.cpp
- DHT22.h and DHT22.cpp were put to the Arduino libraries folder

Posted by: JuhaK at February 14, 2014 4:03 PM

Post a comment




Remember Me?