Interrupt driven DHT11/DHT22 library, port of Arduino idDHTLib (https://github.com/niesteszeck/idDHTLib)

Dependents:   NewDHT11Test

Committer:
kfigiela
Date:
Tue Nov 19 19:36:47 2013 +0000
Revision:
0:53913db38502
DHT11 and DHT22 working

Who changed what in which revision?

UserRevisionLine numberNew 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