Library for DHT22/RHT03 Temperature and Humidity Sensor
Revision 0:42ffca439fcc, committed 2012-03-29
- Comitter:
- crazystick
- Date:
- Thu Mar 29 06:14:07 2012 +0000
- Commit message:
- Updates from around the web, still some issues but at least it now reads reliably for me
Changed in this revision
DHT22.cpp | Show annotated file Show diff for this revision Revisions of this file |
DHT22.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHT22.cpp Thu Mar 29 06:14:07 2012 +0000 @@ -0,0 +1,217 @@ +/* + DHT22.cpp - DHT22 sensor library + Developed by HO WING KIT + Modifications by Paul Adams + + 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 + Version 0.2: 29-Mar-2012 by Paul Adams + + Additional Credit: All the commenters on http://www.sparkfun.com/products/10167 + +*/ + +#include "DHT22.h" + +// This should be 40, but the sensor is adding an extra bit at the start +#define DHT22_DATA_BIT_COUNT 41 + +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, j, retryCount; + int currentTemperature=0; + int currentHumidity=0; + unsigned int checkSum = 0, csPart1, csPart2, csPart3, csPart4; + unsigned int bitTimes[DHT22_DATA_BIT_COUNT]; + DHT22_ERROR err = DHT_ERROR_NONE; + 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) { + printf("DHT22 Error Access Time < 2s"); + err = DHT_ERROR_TOO_QUICK; + } + retryCount = 0; + // Pin needs to start HIGH, wait unit it is HIGH with a timeout + do { + if (retryCount > 125) { + printf("DHT22 Bus busy!"); + err = DHT_BUS_HUNG; + } + retryCount ++; + wait_us(2); + } while (DATA==0); // exit on DHT22 return '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, please check the electrical connection status. + // + DATA.output(); // set pin to output data + DATA = 0; // MCU send out start signal to DHT22 + wait_ms(18); // 18 ms wait (spec: at least 1ms) + DATA = 1; // MCU pull up + wait_us(40); + DATA.input(); // set pin to receive data + // Find the start of the ACK Pulse + retryCount = 0; + do { + if (retryCount > 40) { // (Spec is 20-40 us high) + printf("DHT22 not responding!"); + err = DHT_ERROR_NOT_PRESENT; + } + retryCount++; + wait_us(1); + } while (DATA==1); // Exit on DHT22 pull low within 40us + if (err != DHT_ERROR_NONE) { + // initialisation failed + return err; + } + wait_us(80); // DHT pull up ready to transmit data + + /* + if (DATA == 0) { + printf("DHT22 not ready!"); + err = DHT_ERROR_ACK_TOO_LONG; + return err; + } + */ + + // Reading the 5 byte data stream + // Step 2: DHT22 send data to MCU + // Start bit -> low volage within 50us (actually could be anything from 35-75us) + // 0 -> high volage within 26-28us (actually could be 10-40us) + // 1 -> high volage within 70us (actually could be 60-85us) + // See http://www.sparkfun.com/products/10167#comment-4f118d6e757b7f536e000000 + + + for (i = 0; i < 5; i++) { + for (j = 0; j < 8; j++) { + // Instead of relying on the data sheet, just wait while the RHT03 pin is low + retryCount = 0; + do { + if (retryCount > 75) { + printf("DHT22 timeout waiting for data!"); + err = DHT_ERROR_DATA_TIMEOUT; + } + retryCount++; + wait_us(1); + } while (DATA == 0); + // We now wait for 40us + wait_us(40); + if (DATA == 1) { + // If pin is still high, bit value is a 1 + bitTimes[i*8+j] = 1; + } else { + // The bit value is a 0 + bitTimes[i*8+j] = 0; + } + int count = 0; + while (DATA == 1 && count < 100) { + wait_us(1); // Delay for 1 microsecond + count++; + } + } + } + // Re-init DHT22 pin + DATA.output(); + DATA = 1; + + // Now bitTimes have the actual bits + // that were needed to find the end of each data bit + // Note: the bits are offset by one from the data sheet, not sure why + currentHumidity = 0; + currentTemperature = 0; + checkSum = 0; + // First 16 bits is Humidity + for (i=0; i<16; i++) { + //printf("bit %d: %d ", i, bitTimes[i+1]); + if (bitTimes[i+1] > 0) { + currentHumidity |= ( 1 << (15-i)); + } + } + + // Second 16 bits is Temperature + for (i=0; i<16; i ++) { + //printf("bit %d: %d ", i+16, bitTimes[i+17]); + if (bitTimes[i+17] > 0) { + currentTemperature |= (1 <<(15-i)); + } + } + + // Last 8 bit is Checksum + for (i=0; i<8; i++) { + //printf("bit %d: %d ", i+32, bitTimes[i+33]); + if (bitTimes[i+33] > 0) { + 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)) { + _lastReadTime = currentTime; + printf("OK-->Temperature:%f, Humidity:%f\r\n", _lastTemperature, _lastHumidity); + err = DHT_ERROR_NONE; + } else { + printf("DHT22 Checksum error!\n"); + printf("Calculate check sum is %d\n",(csPart1 + csPart2 + csPart3 + csPart4) & 0xFF); + printf("Reading check sum is %d",checkSum); + err = DHT_ERROR_CHECKSUM; + } + return err; +} + +float DHT22::getTemperatureC() { + return _lastTemperature; +} + +float DHT22::getHumidity() { + return _lastHumidity; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DHT22.h Thu Mar 29 06:14:07 2012 +0000 @@ -0,0 +1,84 @@ +/* mbed DHT22 Library + * Copyright (c) 2011, sford, http://mbed.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documnetation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MBED_DHT22_H +#define MBED_DHT22_H + +#include "mbed.h" + +/** + * Currently supports DHT22 (SparkFun Electronics) + * Humidity and Temperature Sensor + * + * Features: + * > 3.3-6V Input + * > 1-1.5mA measuring current + * > 40-50uA standby current + * > Humidity from 0-100% RH + * > -40 - 80 degrees C temperature range + * > +-2% RH accuracy + * > +-0.5 degrees C + * + * Usages + * #include "DHT22.h" + * + * DTH22 dth22(PinName sda, PinName scl, int addr); // pin + * + * int main() { + * err=dth22.readData(); + * if (err==0) { + printf("Temperature is %f.2 C\n",dht22.getTemperature()); + printf("Humidity is %f.2 \%\n",dht22.getHumidity()); + } + * + * + */ + +#define DHT22_ERROR_VALUE -99.5 + +typedef enum { + DHT_ERROR_NONE = 0, + DHT_BUS_HUNG, + DHT_ERROR_NOT_PRESENT, + DHT_ERROR_ACK_TOO_LONG, + DHT_ERROR_SYNC_TIMEOUT, + DHT_ERROR_DATA_TIMEOUT, + DHT_ERROR_CHECKSUM, + DHT_ERROR_TOO_QUICK +} DHT22_ERROR; + +class DHT22 { +private: + time_t _lastReadTime; + PinName _data; + float _lastHumidity; + float _lastTemperature; +public: + DHT22(PinName Data); + ~DHT22(); + DHT22_ERROR readData(void); + float getHumidity(); + float getTemperatureC(); + void clockReset(); +}; + +#endif /*_DHT22_H_*/