Library for DHT22/RHT03 Temperature and Humidity Sensor

Committer:
crazystick
Date:
Thu Mar 29 06:14:07 2012 +0000
Revision:
0:42ffca439fcc
Updates from around the web, still some issues but at least it now reads reliably for me

Who changed what in which revision?

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