Interrupt driven DHT11/DHT22 library, port of Arduino idDHTLib (https://github.com/niesteszeck/idDHTLib)
idDHTLib.cpp@0:53913db38502, 2013-11-19 (annotated)
- Committer:
- kfigiela
- Date:
- Tue Nov 19 19:36:47 2013 +0000
- Revision:
- 0:53913db38502
DHT11 and DHT22 working
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kfigiela | 0:53913db38502 | 1 | /* |
kfigiela | 0:53913db38502 | 2 | FILE: idDHTLib.cpp |
kfigiela | 0:53913db38502 | 3 | VERSION: 0.0.3 |
kfigiela | 0:53913db38502 | 4 | PURPOSE: Interrupt driven Lib for DHT11 and DHT22 for mbed. |
kfigiela | 0:53913db38502 | 5 | LICENCE: GPL v3 (http://www.gnu.org/licenses/gpl.html) |
kfigiela | 0:53913db38502 | 6 | DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf |
kfigiela | 0:53913db38502 | 7 | DATASHEET: http://www.adafruit.com/datasheets/DHT22.pdf |
kfigiela | 0:53913db38502 | 8 | |
kfigiela | 0:53913db38502 | 9 | Based on idDHT11 library: https://github.com/niesteszeck/idDHT11 |
kfigiela | 0:53913db38502 | 10 | Based on DHTLib library: http://playground.arduino.cc/Main/DHTLib |
kfigiela | 0:53913db38502 | 11 | Based on code proposed: http://forum.arduino.cc/index.php?PHPSESSID=j6n105kl2h07nbj72ac4vbh4s5&topic=175356.0 |
kfigiela | 0:53913db38502 | 12 | Mbed port of Arduino library: https://github.com/niesteszeck/idDHTLib |
kfigiela | 0:53913db38502 | 13 | |
kfigiela | 0:53913db38502 | 14 | Changelog: |
kfigiela | 0:53913db38502 | 15 | v 0.0.1 |
kfigiela | 0:53913db38502 | 16 | fork from idDHT11 lib |
kfigiela | 0:53913db38502 | 17 | change names to idDHTLib |
kfigiela | 0:53913db38502 | 18 | added DHT22 functionality |
kfigiela | 0:53913db38502 | 19 | v 0.0.2 |
kfigiela | 0:53913db38502 | 20 | Optimization on shift var (pylon from Arduino Forum) |
kfigiela | 0:53913db38502 | 21 | v 0.0.3 |
kfigiela | 0:53913db38502 | 22 | Timing correction to finally work properly on DHT22 |
kfigiela | 0:53913db38502 | 23 | (Dessimat0r from Arduino forum) |
kfigiela | 0:53913db38502 | 24 | */ |
kfigiela | 0:53913db38502 | 25 | |
kfigiela | 0:53913db38502 | 26 | #include "idDHTLib.h" |
kfigiela | 0:53913db38502 | 27 | #define DEBUG_idDHTLIB |
kfigiela | 0:53913db38502 | 28 | |
kfigiela | 0:53913db38502 | 29 | idDHTLib::idDHTLib(PinName pin, void (*callback_wrapper)()): inOut(pin), intIn(pin) { |
kfigiela | 0:53913db38502 | 30 | init(pin,callback_wrapper); |
kfigiela | 0:53913db38502 | 31 | } |
kfigiela | 0:53913db38502 | 32 | |
kfigiela | 0:53913db38502 | 33 | void idDHTLib::init(PinName pin, void (*callback_wrapper) ()) { |
kfigiela | 0:53913db38502 | 34 | this->pin = pin; |
kfigiela | 0:53913db38502 | 35 | this->isrCallback_wrapper = callback_wrapper; |
kfigiela | 0:53913db38502 | 36 | hum = 0; |
kfigiela | 0:53913db38502 | 37 | temp = 0; |
kfigiela | 0:53913db38502 | 38 | inOut.output(); |
kfigiela | 0:53913db38502 | 39 | inOut = 1; |
kfigiela | 0:53913db38502 | 40 | state = STOPPED; |
kfigiela | 0:53913db38502 | 41 | status = IDDHTLIB_ERROR_NOTSTARTED; |
kfigiela | 0:53913db38502 | 42 | } |
kfigiela | 0:53913db38502 | 43 | |
kfigiela | 0:53913db38502 | 44 | int idDHTLib::acquire() { |
kfigiela | 0:53913db38502 | 45 | if (state == STOPPED || state == ACQUIRED) { |
kfigiela | 0:53913db38502 | 46 | |
kfigiela | 0:53913db38502 | 47 | //set the state machine for interruptions analisis of the signal |
kfigiela | 0:53913db38502 | 48 | state = RESPONSE; |
kfigiela | 0:53913db38502 | 49 | |
kfigiela | 0:53913db38502 | 50 | // EMPTY BUFFER and vars |
kfigiela | 0:53913db38502 | 51 | for (int i=0; i< 5; i++) bits[i] = 0; |
kfigiela | 0:53913db38502 | 52 | cnt = 7; |
kfigiela | 0:53913db38502 | 53 | idx = 0; |
kfigiela | 0:53913db38502 | 54 | hum = 0; |
kfigiela | 0:53913db38502 | 55 | temp = 0; |
kfigiela | 0:53913db38502 | 56 | |
kfigiela | 0:53913db38502 | 57 | // REQUEST SAMPLE |
kfigiela | 0:53913db38502 | 58 | inOut.output(); |
kfigiela | 0:53913db38502 | 59 | inOut = 0; |
kfigiela | 0:53913db38502 | 60 | wait_ms(18); |
kfigiela | 0:53913db38502 | 61 | inOut = 1; |
kfigiela | 0:53913db38502 | 62 | wait_us(25); |
kfigiela | 0:53913db38502 | 63 | inOut.input(); |
kfigiela | 0:53913db38502 | 64 | t.start(); |
kfigiela | 0:53913db38502 | 65 | |
kfigiela | 0:53913db38502 | 66 | handler = intIn.fall(isrCallback_wrapper); |
kfigiela | 0:53913db38502 | 67 | |
kfigiela | 0:53913db38502 | 68 | return IDDHTLIB_ACQUIRING; |
kfigiela | 0:53913db38502 | 69 | } else |
kfigiela | 0:53913db38502 | 70 | return IDDHTLIB_ERROR_ACQUIRING; |
kfigiela | 0:53913db38502 | 71 | } |
kfigiela | 0:53913db38502 | 72 | int idDHTLib::acquireAndWait() { |
kfigiela | 0:53913db38502 | 73 | acquire(); |
kfigiela | 0:53913db38502 | 74 | while(acquiring()) |
kfigiela | 0:53913db38502 | 75 | ; |
kfigiela | 0:53913db38502 | 76 | return getStatus(); |
kfigiela | 0:53913db38502 | 77 | } |
kfigiela | 0:53913db38502 | 78 | void idDHTLib::dht11Callback() { |
kfigiela | 0:53913db38502 | 79 | isrCallback(false); |
kfigiela | 0:53913db38502 | 80 | } |
kfigiela | 0:53913db38502 | 81 | void idDHTLib::dht22Callback() { |
kfigiela | 0:53913db38502 | 82 | isrCallback(true); |
kfigiela | 0:53913db38502 | 83 | } |
kfigiela | 0:53913db38502 | 84 | |
kfigiela | 0:53913db38502 | 85 | void idDHTLib::isrCallback(bool dht22) { |
kfigiela | 0:53913db38502 | 86 | int delta = t.read_us(); |
kfigiela | 0:53913db38502 | 87 | t.reset(); |
kfigiela | 0:53913db38502 | 88 | if (delta>6000) { |
kfigiela | 0:53913db38502 | 89 | status = IDDHTLIB_ERROR_TIMEOUT; |
kfigiela | 0:53913db38502 | 90 | state = STOPPED; |
kfigiela | 0:53913db38502 | 91 | intIn.fall_remove(handler); |
kfigiela | 0:53913db38502 | 92 | return; |
kfigiela | 0:53913db38502 | 93 | } |
kfigiela | 0:53913db38502 | 94 | switch(state) { |
kfigiela | 0:53913db38502 | 95 | case RESPONSE: |
kfigiela | 0:53913db38502 | 96 | if(delta<25){ |
kfigiela | 0:53913db38502 | 97 | break; //do nothing, it started the response signal |
kfigiela | 0:53913db38502 | 98 | } if(125<delta && delta<190) { |
kfigiela | 0:53913db38502 | 99 | state = DATA; |
kfigiela | 0:53913db38502 | 100 | } else { |
kfigiela | 0:53913db38502 | 101 | intIn.fall_remove(handler); |
kfigiela | 0:53913db38502 | 102 | status = IDDHTLIB_ERROR_TIMEOUT; |
kfigiela | 0:53913db38502 | 103 | state = STOPPED; |
kfigiela | 0:53913db38502 | 104 | } |
kfigiela | 0:53913db38502 | 105 | break; |
kfigiela | 0:53913db38502 | 106 | case DATA: |
kfigiela | 0:53913db38502 | 107 | if(60<delta && delta<145) { //valid in timing |
kfigiela | 0:53913db38502 | 108 | bits[idx] <<= 1; //shift the data |
kfigiela | 0:53913db38502 | 109 | if(delta>100) //is a one |
kfigiela | 0:53913db38502 | 110 | bits[idx] |= 1; |
kfigiela | 0:53913db38502 | 111 | if (cnt == 0) { // when we have fulfilled the byte, go to the next |
kfigiela | 0:53913db38502 | 112 | cnt = 7; // restart at MSB |
kfigiela | 0:53913db38502 | 113 | if(++idx == 5) { // go to next byte; when we have got 5 bytes, stop. |
kfigiela | 0:53913db38502 | 114 | intIn.fall_remove(handler); |
kfigiela | 0:53913db38502 | 115 | // WRITE TO RIGHT VARS |
kfigiela | 0:53913db38502 | 116 | uint8_t sum; |
kfigiela | 0:53913db38502 | 117 | if (dht22) { |
kfigiela | 0:53913db38502 | 118 | hum = (bits[0] << 8 | bits[1]) * 0.1; |
kfigiela | 0:53913db38502 | 119 | temp = (bits[2] & 0x80 ? |
kfigiela | 0:53913db38502 | 120 | -(bits[2] & 0x7F << 8 | bits[3]) : |
kfigiela | 0:53913db38502 | 121 | (bits[2] << 8 | bits[3])) |
kfigiela | 0:53913db38502 | 122 | * 0.1; |
kfigiela | 0:53913db38502 | 123 | sum = bits[0] + bits[1] + bits[2] + bits[3]; |
kfigiela | 0:53913db38502 | 124 | printf("DHT22 Bits: %02d %02d %02d %02d %02d sum=%02d\r\n", bits[0],bits[1],bits[2],bits[3],bits[4],sum&0xff); |
kfigiela | 0:53913db38502 | 125 | |
kfigiela | 0:53913db38502 | 126 | } else { |
kfigiela | 0:53913db38502 | 127 | hum = bits[0]; |
kfigiela | 0:53913db38502 | 128 | // as bits[1] and bits[3] are always zero they are omitted in formulas. |
kfigiela | 0:53913db38502 | 129 | temp = bits[2]; |
kfigiela | 0:53913db38502 | 130 | sum = bits[0] + bits[2]; |
kfigiela | 0:53913db38502 | 131 | } |
kfigiela | 0:53913db38502 | 132 | if (bits[4] != (sum&0xFF)) { |
kfigiela | 0:53913db38502 | 133 | status = IDDHTLIB_ERROR_CHECKSUM; |
kfigiela | 0:53913db38502 | 134 | state = STOPPED; |
kfigiela | 0:53913db38502 | 135 | } else { |
kfigiela | 0:53913db38502 | 136 | status = IDDHTLIB_OK; |
kfigiela | 0:53913db38502 | 137 | state = ACQUIRED; |
kfigiela | 0:53913db38502 | 138 | } |
kfigiela | 0:53913db38502 | 139 | break; |
kfigiela | 0:53913db38502 | 140 | } |
kfigiela | 0:53913db38502 | 141 | } else cnt--; |
kfigiela | 0:53913db38502 | 142 | } else if(delta<10) { |
kfigiela | 0:53913db38502 | 143 | intIn.fall_remove(handler); |
kfigiela | 0:53913db38502 | 144 | status = IDDHTLIB_ERROR_DELTA; |
kfigiela | 0:53913db38502 | 145 | state = STOPPED; |
kfigiela | 0:53913db38502 | 146 | } else { |
kfigiela | 0:53913db38502 | 147 | intIn.fall_remove(handler); |
kfigiela | 0:53913db38502 | 148 | status = IDDHTLIB_ERROR_TIMEOUT; |
kfigiela | 0:53913db38502 | 149 | state = STOPPED; |
kfigiela | 0:53913db38502 | 150 | } |
kfigiela | 0:53913db38502 | 151 | break; |
kfigiela | 0:53913db38502 | 152 | default: |
kfigiela | 0:53913db38502 | 153 | break; |
kfigiela | 0:53913db38502 | 154 | } |
kfigiela | 0:53913db38502 | 155 | } |
kfigiela | 0:53913db38502 | 156 | bool idDHTLib::acquiring() { |
kfigiela | 0:53913db38502 | 157 | if (state != ACQUIRED && state != STOPPED) { |
kfigiela | 0:53913db38502 | 158 | int delta = t.read_us(); |
kfigiela | 0:53913db38502 | 159 | if (delta>6000) { |
kfigiela | 0:53913db38502 | 160 | status = IDDHTLIB_ERROR_TIMEOUT; |
kfigiela | 0:53913db38502 | 161 | state = STOPPED; |
kfigiela | 0:53913db38502 | 162 | intIn.fall_remove(handler); |
kfigiela | 0:53913db38502 | 163 | return false; |
kfigiela | 0:53913db38502 | 164 | } |
kfigiela | 0:53913db38502 | 165 | return true; |
kfigiela | 0:53913db38502 | 166 | } |
kfigiela | 0:53913db38502 | 167 | return false; |
kfigiela | 0:53913db38502 | 168 | } |
kfigiela | 0:53913db38502 | 169 | int idDHTLib::getStatus() { |
kfigiela | 0:53913db38502 | 170 | return status; |
kfigiela | 0:53913db38502 | 171 | } |
kfigiela | 0:53913db38502 | 172 | float idDHTLib::getCelsius() { |
kfigiela | 0:53913db38502 | 173 | IDDHTLIB_CHECK_STATE; |
kfigiela | 0:53913db38502 | 174 | return temp; |
kfigiela | 0:53913db38502 | 175 | } |
kfigiela | 0:53913db38502 | 176 | |
kfigiela | 0:53913db38502 | 177 | float idDHTLib::getHumidity() { |
kfigiela | 0:53913db38502 | 178 | IDDHTLIB_CHECK_STATE; |
kfigiela | 0:53913db38502 | 179 | return hum; |
kfigiela | 0:53913db38502 | 180 | } |
kfigiela | 0:53913db38502 | 181 | |
kfigiela | 0:53913db38502 | 182 | float idDHTLib::getFahrenheit() { |
kfigiela | 0:53913db38502 | 183 | IDDHTLIB_CHECK_STATE; |
kfigiela | 0:53913db38502 | 184 | return temp * 1.8 + 32; |
kfigiela | 0:53913db38502 | 185 | } |
kfigiela | 0:53913db38502 | 186 | |
kfigiela | 0:53913db38502 | 187 | float idDHTLib::getKelvin() { |
kfigiela | 0:53913db38502 | 188 | IDDHTLIB_CHECK_STATE; |
kfigiela | 0:53913db38502 | 189 | return temp + 273.15; |
kfigiela | 0:53913db38502 | 190 | } |
kfigiela | 0:53913db38502 | 191 | |
kfigiela | 0:53913db38502 | 192 | // delta max = 0.6544 wrt dewPoint() |
kfigiela | 0:53913db38502 | 193 | // 5x faster than dewPoint() |
kfigiela | 0:53913db38502 | 194 | // reference: http://en.wikipedia.org/wiki/Dew_point |
kfigiela | 0:53913db38502 | 195 | double idDHTLib::getDewPoint() { |
kfigiela | 0:53913db38502 | 196 | IDDHTLIB_CHECK_STATE; |
kfigiela | 0:53913db38502 | 197 | double a = 17.271; |
kfigiela | 0:53913db38502 | 198 | double b = 237.7; |
kfigiela | 0:53913db38502 | 199 | double temp_ = (a * (double) temp) / (b + (double) temp) + log( (double) hum/100); |
kfigiela | 0:53913db38502 | 200 | double Td = (b * temp_) / (a - temp_); |
kfigiela | 0:53913db38502 | 201 | return Td; |
kfigiela | 0:53913db38502 | 202 | |
kfigiela | 0:53913db38502 | 203 | } |
kfigiela | 0:53913db38502 | 204 | // dewPoint function NOAA |
kfigiela | 0:53913db38502 | 205 | // reference: http://wahiduddin.net/calc/density_algorithms.htm |
kfigiela | 0:53913db38502 | 206 | double idDHTLib::getDewPointSlow() { |
kfigiela | 0:53913db38502 | 207 | IDDHTLIB_CHECK_STATE; |
kfigiela | 0:53913db38502 | 208 | double A0= 373.15/(273.15 + (double) temp); |
kfigiela | 0:53913db38502 | 209 | double SUM = -7.90298 * (A0-1); |
kfigiela | 0:53913db38502 | 210 | SUM += 5.02808 * log10(A0); |
kfigiela | 0:53913db38502 | 211 | SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ; |
kfigiela | 0:53913db38502 | 212 | SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ; |
kfigiela | 0:53913db38502 | 213 | SUM += log10(1013.246); |
kfigiela | 0:53913db38502 | 214 | double VP = pow(10, SUM-3) * (double) hum; |
kfigiela | 0:53913db38502 | 215 | double T = log(VP/0.61078); // temp var |
kfigiela | 0:53913db38502 | 216 | return (241.88 * T) / (17.558-T); |
kfigiela | 0:53913db38502 | 217 | } |
kfigiela | 0:53913db38502 | 218 | // EOF |