=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>> <<library users=\"\" hwkit=\"\" libraries=\"\" dht22=\"\" latest=\"\" docs=\"\" dht22_8cpp_source.html=\"\">></library>
DHT22.cpp@2:340957cc8fef, 2011-07-09 (annotated)
- 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?
User | Revision | Line number | New 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 | } |