
Augur rain MASTER
Dependencies: mbed
Fork of 1A_PROJECT_DIGITAL by
DHT22.cpp@0:ede9cc7e508b, 2015-12-08 (annotated)
- Committer:
- gamezajad
- Date:
- Tue Dec 08 19:25:47 2015 +0000
- Revision:
- 0:ede9cc7e508b
1A
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gamezajad | 0:ede9cc7e508b | 1 | |
gamezajad | 0:ede9cc7e508b | 2 | #include "DHT22.h" |
gamezajad | 0:ede9cc7e508b | 3 | #define DHT22_DATA_BIT_COUNT 41 |
gamezajad | 0:ede9cc7e508b | 4 | |
gamezajad | 0:ede9cc7e508b | 5 | DHT22::DHT22(PinName Data) { |
gamezajad | 0:ede9cc7e508b | 6 | |
gamezajad | 0:ede9cc7e508b | 7 | _data = Data; // Set Data Pin |
gamezajad | 0:ede9cc7e508b | 8 | _lastReadTime = time(NULL); |
gamezajad | 0:ede9cc7e508b | 9 | _lastHumidity = 0; |
gamezajad | 0:ede9cc7e508b | 10 | _lastTemperature = DHT22_ERROR_VALUE; |
gamezajad | 0:ede9cc7e508b | 11 | } |
gamezajad | 0:ede9cc7e508b | 12 | |
gamezajad | 0:ede9cc7e508b | 13 | DHT22::~DHT22() { |
gamezajad | 0:ede9cc7e508b | 14 | } |
gamezajad | 0:ede9cc7e508b | 15 | |
gamezajad | 0:ede9cc7e508b | 16 | DHT22_ERROR DHT22::readData() { |
gamezajad | 0:ede9cc7e508b | 17 | int i, j, retryCount; |
gamezajad | 0:ede9cc7e508b | 18 | int currentTemperature=0; |
gamezajad | 0:ede9cc7e508b | 19 | int currentHumidity=0; |
gamezajad | 0:ede9cc7e508b | 20 | unsigned int checkSum = 0, csPart1, csPart2, csPart3, csPart4; |
gamezajad | 0:ede9cc7e508b | 21 | unsigned int bitTimes[DHT22_DATA_BIT_COUNT]; |
gamezajad | 0:ede9cc7e508b | 22 | DHT22_ERROR err = DHT_ERROR_NONE; |
gamezajad | 0:ede9cc7e508b | 23 | time_t currentTime = time(NULL); |
gamezajad | 0:ede9cc7e508b | 24 | |
gamezajad | 0:ede9cc7e508b | 25 | DigitalInOut DATA(_data); |
gamezajad | 0:ede9cc7e508b | 26 | |
gamezajad | 0:ede9cc7e508b | 27 | for (i = 0; i < DHT22_DATA_BIT_COUNT; i++) { |
gamezajad | 0:ede9cc7e508b | 28 | bitTimes[i] = 0; |
gamezajad | 0:ede9cc7e508b | 29 | } |
gamezajad | 0:ede9cc7e508b | 30 | |
gamezajad | 0:ede9cc7e508b | 31 | if (int(currentTime - _lastReadTime) < 2) { |
gamezajad | 0:ede9cc7e508b | 32 | err = DHT_ERROR_TOO_QUICK; |
gamezajad | 0:ede9cc7e508b | 33 | } |
gamezajad | 0:ede9cc7e508b | 34 | retryCount = 0; |
gamezajad | 0:ede9cc7e508b | 35 | |
gamezajad | 0:ede9cc7e508b | 36 | do { |
gamezajad | 0:ede9cc7e508b | 37 | if (retryCount > 125) { |
gamezajad | 0:ede9cc7e508b | 38 | printf("DHT22 Bus busy!"); |
gamezajad | 0:ede9cc7e508b | 39 | err = DHT_BUS_HUNG; |
gamezajad | 0:ede9cc7e508b | 40 | } |
gamezajad | 0:ede9cc7e508b | 41 | retryCount ++; |
gamezajad | 0:ede9cc7e508b | 42 | wait_us(2); |
gamezajad | 0:ede9cc7e508b | 43 | } while (DATA==0); // exit on DHT22 return 'High' Signal within 250us |
gamezajad | 0:ede9cc7e508b | 44 | |
gamezajad | 0:ede9cc7e508b | 45 | // Send the activate pulse |
gamezajad | 0:ede9cc7e508b | 46 | // Step 1: MCU send out start signal to DHT22 and DHT22 send |
gamezajad | 0:ede9cc7e508b | 47 | // response signal to MCU. |
gamezajad | 0:ede9cc7e508b | 48 | // If always signal high-voltage-level, it means DHT22 is not |
gamezajad | 0:ede9cc7e508b | 49 | // working properly, please check the electrical connection status. |
gamezajad | 0:ede9cc7e508b | 50 | // |
gamezajad | 0:ede9cc7e508b | 51 | DATA.output(); // set pin to output data |
gamezajad | 0:ede9cc7e508b | 52 | DATA = 0; // MCU send out start signal to DHT22 |
gamezajad | 0:ede9cc7e508b | 53 | wait_ms(18); // 18 ms wait (spec: at least 1ms) |
gamezajad | 0:ede9cc7e508b | 54 | DATA = 1; // MCU pull up |
gamezajad | 0:ede9cc7e508b | 55 | wait_us(40); |
gamezajad | 0:ede9cc7e508b | 56 | DATA.input(); // set pin to receive data |
gamezajad | 0:ede9cc7e508b | 57 | // Find the start of the ACK Pulse |
gamezajad | 0:ede9cc7e508b | 58 | retryCount = 0; |
gamezajad | 0:ede9cc7e508b | 59 | do { |
gamezajad | 0:ede9cc7e508b | 60 | if (retryCount > 40) { // (Spec is 20-40 us high) |
gamezajad | 0:ede9cc7e508b | 61 | printf("DHT22 not responding!"); |
gamezajad | 0:ede9cc7e508b | 62 | err = DHT_ERROR_NOT_PRESENT; |
gamezajad | 0:ede9cc7e508b | 63 | } |
gamezajad | 0:ede9cc7e508b | 64 | retryCount++; |
gamezajad | 0:ede9cc7e508b | 65 | wait_us(1); |
gamezajad | 0:ede9cc7e508b | 66 | } while (DATA==1); // Exit on DHT22 pull low within 40us |
gamezajad | 0:ede9cc7e508b | 67 | if (err != DHT_ERROR_NONE) { |
gamezajad | 0:ede9cc7e508b | 68 | // initialisation failed |
gamezajad | 0:ede9cc7e508b | 69 | return err; |
gamezajad | 0:ede9cc7e508b | 70 | } |
gamezajad | 0:ede9cc7e508b | 71 | wait_us(80); // DHT pull up ready to transmit data |
gamezajad | 0:ede9cc7e508b | 72 | |
gamezajad | 0:ede9cc7e508b | 73 | /* |
gamezajad | 0:ede9cc7e508b | 74 | if (DATA == 0) { |
gamezajad | 0:ede9cc7e508b | 75 | printf("DHT22 not ready!"); |
gamezajad | 0:ede9cc7e508b | 76 | err = DHT_ERROR_ACK_TOO_LONG; |
gamezajad | 0:ede9cc7e508b | 77 | return err; |
gamezajad | 0:ede9cc7e508b | 78 | } |
gamezajad | 0:ede9cc7e508b | 79 | */ |
gamezajad | 0:ede9cc7e508b | 80 | |
gamezajad | 0:ede9cc7e508b | 81 | // Reading the 5 byte data stream |
gamezajad | 0:ede9cc7e508b | 82 | // Step 2: DHT22 send data to MCU |
gamezajad | 0:ede9cc7e508b | 83 | // Start bit -> low volage within 50us (actually could be anything from 35-75us) |
gamezajad | 0:ede9cc7e508b | 84 | // 0 -> high volage within 26-28us (actually could be 10-40us) |
gamezajad | 0:ede9cc7e508b | 85 | // 1 -> high volage within 70us (actually could be 60-85us) |
gamezajad | 0:ede9cc7e508b | 86 | // See http://www.sparkfun.com/products/10167#comment-4f118d6e757b7f536e000000 |
gamezajad | 0:ede9cc7e508b | 87 | |
gamezajad | 0:ede9cc7e508b | 88 | |
gamezajad | 0:ede9cc7e508b | 89 | for (i = 0; i < 5; i++) { |
gamezajad | 0:ede9cc7e508b | 90 | for (j = 0; j < 8; j++) { |
gamezajad | 0:ede9cc7e508b | 91 | // Instead of relying on the data sheet, just wait while the RHT03 pin is low |
gamezajad | 0:ede9cc7e508b | 92 | retryCount = 0; |
gamezajad | 0:ede9cc7e508b | 93 | do { |
gamezajad | 0:ede9cc7e508b | 94 | if (retryCount > 75) { |
gamezajad | 0:ede9cc7e508b | 95 | printf("DHT22 timeout waiting for data!"); |
gamezajad | 0:ede9cc7e508b | 96 | err = DHT_ERROR_DATA_TIMEOUT; |
gamezajad | 0:ede9cc7e508b | 97 | } |
gamezajad | 0:ede9cc7e508b | 98 | retryCount++; |
gamezajad | 0:ede9cc7e508b | 99 | wait_us(1); |
gamezajad | 0:ede9cc7e508b | 100 | } while (DATA == 0); |
gamezajad | 0:ede9cc7e508b | 101 | // We now wait for 40us |
gamezajad | 0:ede9cc7e508b | 102 | wait_us(40); |
gamezajad | 0:ede9cc7e508b | 103 | if (DATA == 1) { |
gamezajad | 0:ede9cc7e508b | 104 | // If pin is still high, bit value is a 1 |
gamezajad | 0:ede9cc7e508b | 105 | bitTimes[i*8+j] = 1; |
gamezajad | 0:ede9cc7e508b | 106 | } else { |
gamezajad | 0:ede9cc7e508b | 107 | // The bit value is a 0 |
gamezajad | 0:ede9cc7e508b | 108 | bitTimes[i*8+j] = 0; |
gamezajad | 0:ede9cc7e508b | 109 | } |
gamezajad | 0:ede9cc7e508b | 110 | int count = 0; |
gamezajad | 0:ede9cc7e508b | 111 | while (DATA == 1 && count < 100) { |
gamezajad | 0:ede9cc7e508b | 112 | wait_us(1); // Delay for 1 microsecond |
gamezajad | 0:ede9cc7e508b | 113 | count++; |
gamezajad | 0:ede9cc7e508b | 114 | } |
gamezajad | 0:ede9cc7e508b | 115 | } |
gamezajad | 0:ede9cc7e508b | 116 | } |
gamezajad | 0:ede9cc7e508b | 117 | // Re-init DHT22 pin |
gamezajad | 0:ede9cc7e508b | 118 | DATA.output(); |
gamezajad | 0:ede9cc7e508b | 119 | DATA = 1; |
gamezajad | 0:ede9cc7e508b | 120 | |
gamezajad | 0:ede9cc7e508b | 121 | // Now bitTimes have the actual bits |
gamezajad | 0:ede9cc7e508b | 122 | // that were needed to find the end of each data bit |
gamezajad | 0:ede9cc7e508b | 123 | // Note: the bits are offset by one from the data sheet, not sure why |
gamezajad | 0:ede9cc7e508b | 124 | currentHumidity = 0; |
gamezajad | 0:ede9cc7e508b | 125 | currentTemperature = 0; |
gamezajad | 0:ede9cc7e508b | 126 | checkSum = 0; |
gamezajad | 0:ede9cc7e508b | 127 | // First 16 bits is Humidity |
gamezajad | 0:ede9cc7e508b | 128 | for (i=0; i<16; i++) { |
gamezajad | 0:ede9cc7e508b | 129 | //printf("bit %d: %d ", i, bitTimes[i+1]); |
gamezajad | 0:ede9cc7e508b | 130 | if (bitTimes[i+1] > 0) { |
gamezajad | 0:ede9cc7e508b | 131 | currentHumidity |= ( 1 << (15-i)); |
gamezajad | 0:ede9cc7e508b | 132 | } |
gamezajad | 0:ede9cc7e508b | 133 | } |
gamezajad | 0:ede9cc7e508b | 134 | |
gamezajad | 0:ede9cc7e508b | 135 | // Second 16 bits is Temperature |
gamezajad | 0:ede9cc7e508b | 136 | for (i=0; i<16; i ++) { |
gamezajad | 0:ede9cc7e508b | 137 | //printf("bit %d: %d ", i+16, bitTimes[i+17]); |
gamezajad | 0:ede9cc7e508b | 138 | if (bitTimes[i+17] > 0) { |
gamezajad | 0:ede9cc7e508b | 139 | currentTemperature |= (1 <<(15-i)); |
gamezajad | 0:ede9cc7e508b | 140 | } |
gamezajad | 0:ede9cc7e508b | 141 | } |
gamezajad | 0:ede9cc7e508b | 142 | |
gamezajad | 0:ede9cc7e508b | 143 | // Last 8 bit is Checksum |
gamezajad | 0:ede9cc7e508b | 144 | for (i=0; i<8; i++) { |
gamezajad | 0:ede9cc7e508b | 145 | //printf("bit %d: %d ", i+32, bitTimes[i+33]); |
gamezajad | 0:ede9cc7e508b | 146 | if (bitTimes[i+33] > 0) { |
gamezajad | 0:ede9cc7e508b | 147 | checkSum |= (1 << (7-i)); |
gamezajad | 0:ede9cc7e508b | 148 | } |
gamezajad | 0:ede9cc7e508b | 149 | } |
gamezajad | 0:ede9cc7e508b | 150 | |
gamezajad | 0:ede9cc7e508b | 151 | _lastHumidity = (float(currentHumidity) / 10.0); |
gamezajad | 0:ede9cc7e508b | 152 | |
gamezajad | 0:ede9cc7e508b | 153 | // if first bit of currentTemperature is 1, it is negative value. |
gamezajad | 0:ede9cc7e508b | 154 | if ((currentTemperature & 0x8000)==0x8000) { |
gamezajad | 0:ede9cc7e508b | 155 | _lastTemperature = (float(currentTemperature & 0x7FFF) / 10.0) * -1.0; |
gamezajad | 0:ede9cc7e508b | 156 | } else { |
gamezajad | 0:ede9cc7e508b | 157 | _lastTemperature = float(currentTemperature) / 10.0; |
gamezajad | 0:ede9cc7e508b | 158 | } |
gamezajad | 0:ede9cc7e508b | 159 | |
gamezajad | 0:ede9cc7e508b | 160 | // Calculate Check Sum |
gamezajad | 0:ede9cc7e508b | 161 | csPart1 = currentHumidity >> 8; |
gamezajad | 0:ede9cc7e508b | 162 | csPart2 = currentHumidity & 0xFF; |
gamezajad | 0:ede9cc7e508b | 163 | csPart3 = currentTemperature >> 8; |
gamezajad | 0:ede9cc7e508b | 164 | csPart4 = currentTemperature & 0xFF; |
gamezajad | 0:ede9cc7e508b | 165 | |
gamezajad | 0:ede9cc7e508b | 166 | if (checkSum == ((csPart1 + csPart2 + csPart3 + csPart4) & 0xFF)) { |
gamezajad | 0:ede9cc7e508b | 167 | _lastReadTime = currentTime; |
gamezajad | 0:ede9cc7e508b | 168 | //printf("OK-->Temperature :: %f , Humidity :: %f\r\n", _lastTemperature, _lastHumidity); |
gamezajad | 0:ede9cc7e508b | 169 | err = DHT_ERROR_NONE; |
gamezajad | 0:ede9cc7e508b | 170 | printf("\n"); |
gamezajad | 0:ede9cc7e508b | 171 | |
gamezajad | 0:ede9cc7e508b | 172 | } |
gamezajad | 0:ede9cc7e508b | 173 | else { |
gamezajad | 0:ede9cc7e508b | 174 | //printf("DHT22 Checksum error!\n"); |
gamezajad | 0:ede9cc7e508b | 175 | //printf("Calculate check sum is %d\n",(csPart1 + csPart2 + csPart3 + csPart4) & 0xFF); |
gamezajad | 0:ede9cc7e508b | 176 | //printf("Reading check sum is %d\n",checkSum); |
gamezajad | 0:ede9cc7e508b | 177 | err = DHT_ERROR_CHECKSUM; |
gamezajad | 0:ede9cc7e508b | 178 | printf("\n"); |
gamezajad | 0:ede9cc7e508b | 179 | } |
gamezajad | 0:ede9cc7e508b | 180 | |
gamezajad | 0:ede9cc7e508b | 181 | return err; |
gamezajad | 0:ede9cc7e508b | 182 | } |
gamezajad | 0:ede9cc7e508b | 183 | |
gamezajad | 0:ede9cc7e508b | 184 | float DHT22::getTemperatureC() { |
gamezajad | 0:ede9cc7e508b | 185 | return _lastTemperature; |
gamezajad | 0:ede9cc7e508b | 186 | } |
gamezajad | 0:ede9cc7e508b | 187 | |
gamezajad | 0:ede9cc7e508b | 188 | float DHT22::getHumidity() { |
gamezajad | 0:ede9cc7e508b | 189 | return _lastHumidity; |
gamezajad | 0:ede9cc7e508b | 190 | } |