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