=DHT22 Temperature and Humidity Sensor= The DHT-22 is a low cost humidity and temperature sensor with a single wire digital interface. The sensor is calibrated and doesn\\\'t require extra components so you can get right to measuring relative humidity and temperature. [[http://dlnmh9ip6v2uc.cloudfront.net/images/products/10167-01_i_ma.jpg]] Features: * 3.3-6V Input * 1-1.5mA measuring current * 40-50 uA standby current * Humidity from 0-100% RH * -40 - 80 degrees C temperature range * +-2% RH accuracy * +-0.5 degrees C ***(same as RHT03 www.humiditycn.com)*** Available as http://www.sparkfun.com/products/10167 | DHT22(pin) | Function | mbed | | 1 - VDD | VDD-power supply (3.3-6V) | (Vout) 5V | | 2 - DATA | Single pin signal | p15 | | 3 - NULL | | | | 4 - GND | Connect to ground | GND | == Library == <<library /users/hwkit/libraries/DHT22/latest/docs/DHT22_8h_source.html>> &lt;<library users=\"\" hwkit=\"\" libraries=\"\" dht22=\"\" latest=\"\" docs=\"\" dht22_8cpp_source.html=\"\">&gt;</library>

DHT22.cpp

Committer:
hwkit
Date:
2011-07-09
Revision:
2:340957cc8fef
Parent:
1:5b20ff4fd227

File content as of revision 2:340957cc8fef:

/*
    DHT22.cpp - DHT22 sensor library
    Developed by HO WING KIT

    This library is free software; you can redistribute it and / or
    modify it under the terms of the GNU Leser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRENTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PATRICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA


    Humidity and Temperature Sensor DHT22 info found at
    http://www.sparkfun.com/products/10167
    same as RHT03 http://www.humiditycn.com    

    Version 0.1: 8-Jan-2011 by Ho Wing Kit
                 Beata test
    
*/

#include "DHT22.h"


// This should be 40, but the sensor is adding an extra bit at the start
#define DHT22_DATA_BIT_COUNT 41
                           // debug
Serial pc(USBTX, USBRX);   // Tx, Rx Using USB Virtual Serial Port
                           // Read Data From /etc/ttyACM* (linux port)

DHT22::DHT22(PinName Data) {

    _data = Data;                // Set Data Pin
    _lastReadTime = time(NULL);
    _lastHumidity = 0;
    _lastTemperature = DHT22_ERROR_VALUE;
}

DHT22::~DHT22() {
}

DHT22_ERROR DHT22::readData() {
    int i, retryCount;
    int currentTemperature=0;
    int currentHumidity=0;
    unsigned int checkSum = 0, csPart1, csPart2, csPart3, csPart4;
    unsigned int bitTimes[DHT22_DATA_BIT_COUNT];
    
    time_t currentTime = time(NULL);

    DigitalInOut  DATA(_data);
   
       
    for (i = 0; i < DHT22_DATA_BIT_COUNT; i++) {
        bitTimes[i] = 0;
    }
    
    if (int(currentTime - _lastReadTime) < 2) {        
        pc.printf("DHT22 Error Too Quick, wiat...");
        return DHT_ERROR_TOOQUICK;
    }   
    retryCount = 0;
    // Pin needs to start HIGH, wait unit it is HIGH with a timeout
    do {
        if (retryCount > 125) {
            pc.printf("DHT22 Bus busy! ");
            return DHT_BUS_HUNG;
        }
        retryCount ++;
        wait_us(2);
    } while (DATA==0);   // exit on DHT22 retrun 'High' Signal within 250us
    
    // Send the activate pulse
    // Step 1: MCU send out start signal to DHT22 and DHT22 send
    //         response signal to MCU.
    // If always signal high-voltage-level, it means DHT22 is not 
    // working properly, plesee check the electrical connection status.
    //
    DATA = 0;        // MCU send out start signal to DHT22
    wait_us(1100);   // 1.1 ms
    DATA = 1;        // MCU pull up 
    wait_us(30);     // 30 us
    // Find the start of the ACK Pulse
    retryCount = 0;
    do {
        if (retryCount > 40)  {// (Spec is 80 us, 40*2 == 80us
            pc.printf("DHT22 is not present! ");
            return DHT_ERROR_NOT_PRESENT;
        }
        retryCount ++;
        wait_us(2);
    } while (DATA==1);   // Exit on DHT22 pull low within 80us
    
    // Find the last of the ACK Pulse
    retryCount = 0;
    do {
        if (retryCount > 40) {// (Spec is 80 us, 40 * 2 == 100us)
            pc.printf("DHT22 error timeout for receiveing last ack signal! ");
            return DHT_ERROR_ACK_TOO_LONG;
        }
        retryCount++;
        wait_us(2);
    } while (DATA==0); // Exit on DHT22 pull high within 80us

    // Reading the 40 bit data stream
    // Step 2: DHT22 send data to MCU
    //         Start bit -> low volage within 50us
    //         0         -> high volage within 26-28 us
    //         1         -> high volage within 70us
    // 
         
    for (i=0; i < DHT22_DATA_BIT_COUNT; i++) {
        retryCount = 0;
        do {                       // Getting start bit signal 
            if (retryCount > 25) { // spec is 50 u, 25*2 = 50 us
                pc.printf("DHT22 sync timeout error! ");
                return DHT_ERROR_SYNC_TIMEOUT;
            }
            retryCount ++;
            wait_us(2);
        } while (DATA==0);   // Exit on high volage within 50us
        // Measure the width of the data pulse
        retryCount = 0;
        do {
            if (retryCount > 40) { // spec is 80us, 50*2 == 100us
                pc.printf("DHT22 ERROR DATA TIMEOUT\n");
                return DHT_ERROR_DATA_TIMEOUT;
            }
            retryCount++;
            wait_us(2);
        } while (DATA==1);        // Exit on low volage below 80us
        bitTimes[i] = retryCount; // Assign bitTimes in us
    }

    // Now bitTimes have the number of retries (us *2)
    // that were needed to find the end of each data bit
    // Spec: 0 is 26 to 28 us
    // Spec: 1 is 70 us
    // bitTimes[x] <= 14 is a 0 (14x2us = 28us)
    // bitTimes[x] > 15  is a 1 (15x2us = 30us)
    // Note: the bits are offset by one from the data sheet, not sure why
    currentHumidity   = 0;
    currentTemperature = 0;
    checkSum           = 0;
    // First 16 bit is Humidity
    for (i=0; i<16; i++) {
        if (bitTimes[i] > 14) {
            pc.printf("%d: bit time is %d us. ", i, bitTimes[i]);
            currentHumidity |= ( 1 << (15-i));
        }
    }
    
    // Second 16 bit is Temperature 
    for (i=0; i<16; i ++) {
        if (bitTimes[i+16] > 14) {
            currentTemperature |= (1 <<(15-i));
        }
    }

    // Last 8 bit is Checksum
    for (i=0; i<8; i++) {
        if (bitTimes[i+32] > 14) {
            checkSum |= (1 << (7-i));
        }
    }
   
    _lastHumidity = (float(currentHumidity) / 10.0);
    
    // if first bit of currentTemperature is 1, it is negative value.
    
    if ((currentTemperature &= 0x8000)==0x8000) {        
        _lastTemperature = (float(currentTemperature & 0x7FFF) / 10.0) * -1.0;
    } else {
        _lastTemperature = float(currentTemperature) / 10.0;
    }

    // Calculate Check Sum
    //           
    csPart1 = currentHumidity >> 8;
    csPart2 = currentHumidity & 0xFF;
    csPart3 = currentTemperature >> 8;
    csPart4 = currentTemperature & 0xFF;
    if (checkSum == ((csPart1 + csPart2 + csPart3 + csPart4) & 0xFF)) {
        pc.printf("Calculate check sum is %d.",(csPart1 + csPart2 + csPart3 + csPart4) & 0xFF);
        pc.printf("Reading check sum is %d.",checkSum);
        _lastReadTime = currentTime;
        pc.printf("OK-->Temperature:%d, Humidity:%d\n", _lastTemperature, _lastHumidity);
        return DHT_ERROR_NONE;
    }
    pc.printf("DHT22 Checksum error!");
    return DHT_ERROR_CHECKSUM;
}

float DHT22::getTemperatureC() {
    return _lastTemperature;
}

float DHT22::getHumidity() {
    return _lastHumidity;
}