=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>

Committer:
hwkit
Date:
Sat Jul 09 02:18:38 2011 +0000
Revision:
2:340957cc8fef
Parent:
1:5b20ff4fd227
0.1 -> Beta test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hwkit 0:547e68daeb1b 1 /*
hwkit 0:547e68daeb1b 2 DHT22.cpp - DHT22 sensor library
hwkit 2:340957cc8fef 3 Developed by HO WING KIT
hwkit 0:547e68daeb1b 4
hwkit 0:547e68daeb1b 5 This library is free software; you can redistribute it and / or
hwkit 0:547e68daeb1b 6 modify it under the terms of the GNU Leser General Public
hwkit 0:547e68daeb1b 7 License as published by the Free Software Foundation; either
hwkit 0:547e68daeb1b 8 version 2.1 of the License, or (at your option) any later version.
hwkit 0:547e68daeb1b 9
hwkit 0:547e68daeb1b 10 This library is distributed in the hope that it will be useful,
hwkit 0:547e68daeb1b 11 but WITHOUT ANY WARRENTY; without even the implied warranty of
hwkit 0:547e68daeb1b 12 MERCHANTABILITY or FITNESS FOR A PATRICULAR PURPOSE. See the GNU
hwkit 0:547e68daeb1b 13 Lesser General Public License for more details.
hwkit 0:547e68daeb1b 14
hwkit 0:547e68daeb1b 15 You should have received a copy of the GNU Lesser General Public
hwkit 0:547e68daeb1b 16 License along with this library; if not, write to the Free Software
hwkit 0:547e68daeb1b 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
hwkit 0:547e68daeb1b 18
hwkit 0:547e68daeb1b 19
hwkit 0:547e68daeb1b 20 Humidity and Temperature Sensor DHT22 info found at
hwkit 0:547e68daeb1b 21 http://www.sparkfun.com/products/10167
hwkit 2:340957cc8fef 22 same as RHT03 http://www.humiditycn.com
hwkit 0:547e68daeb1b 23
hwkit 2:340957cc8fef 24 Version 0.1: 8-Jan-2011 by Ho Wing Kit
hwkit 2:340957cc8fef 25 Beata test
hwkit 2:340957cc8fef 26
hwkit 0:547e68daeb1b 27 */
hwkit 0:547e68daeb1b 28
hwkit 0:547e68daeb1b 29 #include "DHT22.h"
hwkit 0:547e68daeb1b 30
hwkit 1:5b20ff4fd227 31
hwkit 0:547e68daeb1b 32 // This should be 40, but the sensor is adding an extra bit at the start
hwkit 0:547e68daeb1b 33 #define DHT22_DATA_BIT_COUNT 41
hwkit 2:340957cc8fef 34 // debug
hwkit 1:5b20ff4fd227 35 Serial pc(USBTX, USBRX); // Tx, Rx Using USB Virtual Serial Port
hwkit 1:5b20ff4fd227 36 // Read Data From /etc/ttyACM* (linux port)
hwkit 1:5b20ff4fd227 37
hwkit 0:547e68daeb1b 38 DHT22::DHT22(PinName Data) {
hwkit 2:340957cc8fef 39
hwkit 0:547e68daeb1b 40 _data = Data; // Set Data Pin
hwkit 1:5b20ff4fd227 41 _lastReadTime = time(NULL);
hwkit 0:547e68daeb1b 42 _lastHumidity = 0;
hwkit 0:547e68daeb1b 43 _lastTemperature = DHT22_ERROR_VALUE;
hwkit 0:547e68daeb1b 44 }
hwkit 0:547e68daeb1b 45
hwkit 0:547e68daeb1b 46 DHT22::~DHT22() {
hwkit 0:547e68daeb1b 47 }
hwkit 0:547e68daeb1b 48
hwkit 0:547e68daeb1b 49 DHT22_ERROR DHT22::readData() {
hwkit 0:547e68daeb1b 50 int i, retryCount;
hwkit 1:5b20ff4fd227 51 int currentTemperature=0;
hwkit 1:5b20ff4fd227 52 int currentHumidity=0;
hwkit 1:5b20ff4fd227 53 unsigned int checkSum = 0, csPart1, csPart2, csPart3, csPart4;
hwkit 0:547e68daeb1b 54 unsigned int bitTimes[DHT22_DATA_BIT_COUNT];
hwkit 2:340957cc8fef 55
hwkit 1:5b20ff4fd227 56 time_t currentTime = time(NULL);
hwkit 0:547e68daeb1b 57
hwkit 0:547e68daeb1b 58 DigitalInOut DATA(_data);
hwkit 2:340957cc8fef 59
hwkit 1:5b20ff4fd227 60
hwkit 0:547e68daeb1b 61 for (i = 0; i < DHT22_DATA_BIT_COUNT; i++) {
hwkit 0:547e68daeb1b 62 bitTimes[i] = 0;
hwkit 0:547e68daeb1b 63 }
hwkit 1:5b20ff4fd227 64
hwkit 2:340957cc8fef 65 if (int(currentTime - _lastReadTime) < 2) {
hwkit 2:340957cc8fef 66 pc.printf("DHT22 Error Too Quick, wiat...");
hwkit 0:547e68daeb1b 67 return DHT_ERROR_TOOQUICK;
hwkit 2:340957cc8fef 68 }
hwkit 0:547e68daeb1b 69 retryCount = 0;
hwkit 0:547e68daeb1b 70 // Pin needs to start HIGH, wait unit it is HIGH with a timeout
hwkit 0:547e68daeb1b 71 do {
hwkit 0:547e68daeb1b 72 if (retryCount > 125) {
hwkit 2:340957cc8fef 73 pc.printf("DHT22 Bus busy! ");
hwkit 0:547e68daeb1b 74 return DHT_BUS_HUNG;
hwkit 0:547e68daeb1b 75 }
hwkit 0:547e68daeb1b 76 retryCount ++;
hwkit 0:547e68daeb1b 77 wait_us(2);
hwkit 2:340957cc8fef 78 } while (DATA==0); // exit on DHT22 retrun 'High' Signal within 250us
hwkit 2:340957cc8fef 79
hwkit 0:547e68daeb1b 80 // Send the activate pulse
hwkit 2:340957cc8fef 81 // Step 1: MCU send out start signal to DHT22 and DHT22 send
hwkit 2:340957cc8fef 82 // response signal to MCU.
hwkit 2:340957cc8fef 83 // If always signal high-voltage-level, it means DHT22 is not
hwkit 2:340957cc8fef 84 // working properly, plesee check the electrical connection status.
hwkit 2:340957cc8fef 85 //
hwkit 0:547e68daeb1b 86 DATA = 0; // MCU send out start signal to DHT22
hwkit 0:547e68daeb1b 87 wait_us(1100); // 1.1 ms
hwkit 2:340957cc8fef 88 DATA = 1; // MCU pull up
hwkit 2:340957cc8fef 89 wait_us(30); // 30 us
hwkit 0:547e68daeb1b 90 // Find the start of the ACK Pulse
hwkit 0:547e68daeb1b 91 retryCount = 0;
hwkit 0:547e68daeb1b 92 do {
hwkit 2:340957cc8fef 93 if (retryCount > 40) {// (Spec is 80 us, 40*2 == 80us
hwkit 2:340957cc8fef 94 pc.printf("DHT22 is not present! ");
hwkit 0:547e68daeb1b 95 return DHT_ERROR_NOT_PRESENT;
hwkit 0:547e68daeb1b 96 }
hwkit 0:547e68daeb1b 97 retryCount ++;
hwkit 0:547e68daeb1b 98 wait_us(2);
hwkit 2:340957cc8fef 99 } while (DATA==1); // Exit on DHT22 pull low within 80us
hwkit 2:340957cc8fef 100
hwkit 2:340957cc8fef 101 // Find the last of the ACK Pulse
hwkit 0:547e68daeb1b 102 retryCount = 0;
hwkit 0:547e68daeb1b 103 do {
hwkit 2:340957cc8fef 104 if (retryCount > 40) {// (Spec is 80 us, 40 * 2 == 100us)
hwkit 2:340957cc8fef 105 pc.printf("DHT22 error timeout for receiveing last ack signal! ");
hwkit 0:547e68daeb1b 106 return DHT_ERROR_ACK_TOO_LONG;
hwkit 0:547e68daeb1b 107 }
hwkit 0:547e68daeb1b 108 retryCount++;
hwkit 0:547e68daeb1b 109 wait_us(2);
hwkit 2:340957cc8fef 110 } while (DATA==0); // Exit on DHT22 pull high within 80us
hwkit 2:340957cc8fef 111
hwkit 2:340957cc8fef 112 // Reading the 40 bit data stream
hwkit 2:340957cc8fef 113 // Step 2: DHT22 send data to MCU
hwkit 2:340957cc8fef 114 // Start bit -> low volage within 50us
hwkit 2:340957cc8fef 115 // 0 -> high volage within 26-28 us
hwkit 2:340957cc8fef 116 // 1 -> high volage within 70us
hwkit 2:340957cc8fef 117 //
hwkit 2:340957cc8fef 118
hwkit 0:547e68daeb1b 119 for (i=0; i < DHT22_DATA_BIT_COUNT; i++) {
hwkit 0:547e68daeb1b 120 retryCount = 0;
hwkit 2:340957cc8fef 121 do { // Getting start bit signal
hwkit 2:340957cc8fef 122 if (retryCount > 25) { // spec is 50 u, 25*2 = 50 us
hwkit 2:340957cc8fef 123 pc.printf("DHT22 sync timeout error! ");
hwkit 0:547e68daeb1b 124 return DHT_ERROR_SYNC_TIMEOUT;
hwkit 0:547e68daeb1b 125 }
hwkit 0:547e68daeb1b 126 retryCount ++;
hwkit 0:547e68daeb1b 127 wait_us(2);
hwkit 2:340957cc8fef 128 } while (DATA==0); // Exit on high volage within 50us
hwkit 0:547e68daeb1b 129 // Measure the width of the data pulse
hwkit 0:547e68daeb1b 130 retryCount = 0;
hwkit 0:547e68daeb1b 131 do {
hwkit 2:340957cc8fef 132 if (retryCount > 40) { // spec is 80us, 50*2 == 100us
hwkit 2:340957cc8fef 133 pc.printf("DHT22 ERROR DATA TIMEOUT\n");
hwkit 0:547e68daeb1b 134 return DHT_ERROR_DATA_TIMEOUT;
hwkit 0:547e68daeb1b 135 }
hwkit 0:547e68daeb1b 136 retryCount++;
hwkit 0:547e68daeb1b 137 wait_us(2);
hwkit 2:340957cc8fef 138 } while (DATA==1); // Exit on low volage below 80us
hwkit 2:340957cc8fef 139 bitTimes[i] = retryCount; // Assign bitTimes in us
hwkit 0:547e68daeb1b 140 }
hwkit 0:547e68daeb1b 141
hwkit 0:547e68daeb1b 142 // Now bitTimes have the number of retries (us *2)
hwkit 0:547e68daeb1b 143 // that were needed to find the end of each data bit
hwkit 0:547e68daeb1b 144 // Spec: 0 is 26 to 28 us
hwkit 0:547e68daeb1b 145 // Spec: 1 is 70 us
hwkit 2:340957cc8fef 146 // bitTimes[x] <= 14 is a 0 (14x2us = 28us)
hwkit 2:340957cc8fef 147 // bitTimes[x] > 15 is a 1 (15x2us = 30us)
hwkit 0:547e68daeb1b 148 // Note: the bits are offset by one from the data sheet, not sure why
hwkit 2:340957cc8fef 149 currentHumidity = 0;
hwkit 2:340957cc8fef 150 currentTemperature = 0;
hwkit 2:340957cc8fef 151 checkSum = 0;
hwkit 2:340957cc8fef 152 // First 16 bit is Humidity
hwkit 0:547e68daeb1b 153 for (i=0; i<16; i++) {
hwkit 2:340957cc8fef 154 if (bitTimes[i] > 14) {
hwkit 2:340957cc8fef 155 pc.printf("%d: bit time is %d us. ", i, bitTimes[i]);
hwkit 0:547e68daeb1b 156 currentHumidity |= ( 1 << (15-i));
hwkit 0:547e68daeb1b 157 }
hwkit 0:547e68daeb1b 158 }
hwkit 2:340957cc8fef 159
hwkit 2:340957cc8fef 160 // Second 16 bit is Temperature
hwkit 0:547e68daeb1b 161 for (i=0; i<16; i ++) {
hwkit 2:340957cc8fef 162 if (bitTimes[i+16] > 14) {
hwkit 0:547e68daeb1b 163 currentTemperature |= (1 <<(15-i));
hwkit 0:547e68daeb1b 164 }
hwkit 0:547e68daeb1b 165 }
hwkit 0:547e68daeb1b 166
hwkit 2:340957cc8fef 167 // Last 8 bit is Checksum
hwkit 0:547e68daeb1b 168 for (i=0; i<8; i++) {
hwkit 2:340957cc8fef 169 if (bitTimes[i+32] > 14) {
hwkit 0:547e68daeb1b 170 checkSum |= (1 << (7-i));
hwkit 0:547e68daeb1b 171 }
hwkit 0:547e68daeb1b 172 }
hwkit 2:340957cc8fef 173
hwkit 2:340957cc8fef 174 _lastHumidity = (float(currentHumidity) / 10.0);
hwkit 2:340957cc8fef 175
hwkit 2:340957cc8fef 176 // if first bit of currentTemperature is 1, it is negative value.
hwkit 2:340957cc8fef 177
hwkit 2:340957cc8fef 178 if ((currentTemperature &= 0x8000)==0x8000) {
hwkit 2:340957cc8fef 179 _lastTemperature = (float(currentTemperature & 0x7FFF) / 10.0) * -1.0;
hwkit 0:547e68daeb1b 180 } else {
hwkit 0:547e68daeb1b 181 _lastTemperature = float(currentTemperature) / 10.0;
hwkit 0:547e68daeb1b 182 }
hwkit 0:547e68daeb1b 183
hwkit 0:547e68daeb1b 184 // Calculate Check Sum
hwkit 2:340957cc8fef 185 //
hwkit 0:547e68daeb1b 186 csPart1 = currentHumidity >> 8;
hwkit 0:547e68daeb1b 187 csPart2 = currentHumidity & 0xFF;
hwkit 0:547e68daeb1b 188 csPart3 = currentTemperature >> 8;
hwkit 0:547e68daeb1b 189 csPart4 = currentTemperature & 0xFF;
hwkit 0:547e68daeb1b 190 if (checkSum == ((csPart1 + csPart2 + csPart3 + csPart4) & 0xFF)) {
hwkit 2:340957cc8fef 191 pc.printf("Calculate check sum is %d.",(csPart1 + csPart2 + csPart3 + csPart4) & 0xFF);
hwkit 2:340957cc8fef 192 pc.printf("Reading check sum is %d.",checkSum);
hwkit 2:340957cc8fef 193 _lastReadTime = currentTime;
hwkit 2:340957cc8fef 194 pc.printf("OK-->Temperature:%d, Humidity:%d\n", _lastTemperature, _lastHumidity);
hwkit 0:547e68daeb1b 195 return DHT_ERROR_NONE;
hwkit 0:547e68daeb1b 196 }
hwkit 2:340957cc8fef 197 pc.printf("DHT22 Checksum error!");
hwkit 0:547e68daeb1b 198 return DHT_ERROR_CHECKSUM;
hwkit 0:547e68daeb1b 199 }
hwkit 0:547e68daeb1b 200
hwkit 0:547e68daeb1b 201 float DHT22::getTemperatureC() {
hwkit 0:547e68daeb1b 202 return _lastTemperature;
hwkit 0:547e68daeb1b 203 }
hwkit 0:547e68daeb1b 204
hwkit 0:547e68daeb1b 205 float DHT22::getHumidity() {
hwkit 0:547e68daeb1b 206 return _lastHumidity;
hwkit 0:547e68daeb1b 207 }