Interrupt driven DHT11/DHT22 library, port of Arduino idDHTLib (https://github.com/niesteszeck/idDHTLib)
idDHTLib.cpp
- Committer:
- kfigiela
- Date:
- 2013-11-19
- Revision:
- 0:53913db38502
File content as of revision 0:53913db38502:
/* FILE: idDHTLib.cpp VERSION: 0.0.3 PURPOSE: Interrupt driven Lib for DHT11 and DHT22 for mbed. LICENCE: GPL v3 (http://www.gnu.org/licenses/gpl.html) DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf DATASHEET: http://www.adafruit.com/datasheets/DHT22.pdf Based on idDHT11 library: https://github.com/niesteszeck/idDHT11 Based on DHTLib library: http://playground.arduino.cc/Main/DHTLib Based on code proposed: http://forum.arduino.cc/index.php?PHPSESSID=j6n105kl2h07nbj72ac4vbh4s5&topic=175356.0 Mbed port of Arduino library: https://github.com/niesteszeck/idDHTLib Changelog: v 0.0.1 fork from idDHT11 lib change names to idDHTLib added DHT22 functionality v 0.0.2 Optimization on shift var (pylon from Arduino Forum) v 0.0.3 Timing correction to finally work properly on DHT22 (Dessimat0r from Arduino forum) */ #include "idDHTLib.h" #define DEBUG_idDHTLIB idDHTLib::idDHTLib(PinName pin, void (*callback_wrapper)()): inOut(pin), intIn(pin) { init(pin,callback_wrapper); } void idDHTLib::init(PinName pin, void (*callback_wrapper) ()) { this->pin = pin; this->isrCallback_wrapper = callback_wrapper; hum = 0; temp = 0; inOut.output(); inOut = 1; state = STOPPED; status = IDDHTLIB_ERROR_NOTSTARTED; } int idDHTLib::acquire() { if (state == STOPPED || state == ACQUIRED) { //set the state machine for interruptions analisis of the signal state = RESPONSE; // EMPTY BUFFER and vars for (int i=0; i< 5; i++) bits[i] = 0; cnt = 7; idx = 0; hum = 0; temp = 0; // REQUEST SAMPLE inOut.output(); inOut = 0; wait_ms(18); inOut = 1; wait_us(25); inOut.input(); t.start(); handler = intIn.fall(isrCallback_wrapper); return IDDHTLIB_ACQUIRING; } else return IDDHTLIB_ERROR_ACQUIRING; } int idDHTLib::acquireAndWait() { acquire(); while(acquiring()) ; return getStatus(); } void idDHTLib::dht11Callback() { isrCallback(false); } void idDHTLib::dht22Callback() { isrCallback(true); } void idDHTLib::isrCallback(bool dht22) { int delta = t.read_us(); t.reset(); if (delta>6000) { status = IDDHTLIB_ERROR_TIMEOUT; state = STOPPED; intIn.fall_remove(handler); return; } switch(state) { case RESPONSE: if(delta<25){ break; //do nothing, it started the response signal } if(125<delta && delta<190) { state = DATA; } else { intIn.fall_remove(handler); status = IDDHTLIB_ERROR_TIMEOUT; state = STOPPED; } break; case DATA: if(60<delta && delta<145) { //valid in timing bits[idx] <<= 1; //shift the data if(delta>100) //is a one bits[idx] |= 1; if (cnt == 0) { // when we have fulfilled the byte, go to the next cnt = 7; // restart at MSB if(++idx == 5) { // go to next byte; when we have got 5 bytes, stop. intIn.fall_remove(handler); // WRITE TO RIGHT VARS uint8_t sum; if (dht22) { hum = (bits[0] << 8 | bits[1]) * 0.1; temp = (bits[2] & 0x80 ? -(bits[2] & 0x7F << 8 | bits[3]) : (bits[2] << 8 | bits[3])) * 0.1; sum = bits[0] + bits[1] + bits[2] + bits[3]; printf("DHT22 Bits: %02d %02d %02d %02d %02d sum=%02d\r\n", bits[0],bits[1],bits[2],bits[3],bits[4],sum&0xff); } else { hum = bits[0]; // as bits[1] and bits[3] are always zero they are omitted in formulas. temp = bits[2]; sum = bits[0] + bits[2]; } if (bits[4] != (sum&0xFF)) { status = IDDHTLIB_ERROR_CHECKSUM; state = STOPPED; } else { status = IDDHTLIB_OK; state = ACQUIRED; } break; } } else cnt--; } else if(delta<10) { intIn.fall_remove(handler); status = IDDHTLIB_ERROR_DELTA; state = STOPPED; } else { intIn.fall_remove(handler); status = IDDHTLIB_ERROR_TIMEOUT; state = STOPPED; } break; default: break; } } bool idDHTLib::acquiring() { if (state != ACQUIRED && state != STOPPED) { int delta = t.read_us(); if (delta>6000) { status = IDDHTLIB_ERROR_TIMEOUT; state = STOPPED; intIn.fall_remove(handler); return false; } return true; } return false; } int idDHTLib::getStatus() { return status; } float idDHTLib::getCelsius() { IDDHTLIB_CHECK_STATE; return temp; } float idDHTLib::getHumidity() { IDDHTLIB_CHECK_STATE; return hum; } float idDHTLib::getFahrenheit() { IDDHTLIB_CHECK_STATE; return temp * 1.8 + 32; } float idDHTLib::getKelvin() { IDDHTLIB_CHECK_STATE; return temp + 273.15; } // delta max = 0.6544 wrt dewPoint() // 5x faster than dewPoint() // reference: http://en.wikipedia.org/wiki/Dew_point double idDHTLib::getDewPoint() { IDDHTLIB_CHECK_STATE; double a = 17.271; double b = 237.7; double temp_ = (a * (double) temp) / (b + (double) temp) + log( (double) hum/100); double Td = (b * temp_) / (a - temp_); return Td; } // dewPoint function NOAA // reference: http://wahiduddin.net/calc/density_algorithms.htm double idDHTLib::getDewPointSlow() { IDDHTLIB_CHECK_STATE; double A0= 373.15/(273.15 + (double) temp); double SUM = -7.90298 * (A0-1); SUM += 5.02808 * log10(A0); SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ; SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ; SUM += log10(1013.246); double VP = pow(10, SUM-3) * (double) hum; double T = log(VP/0.61078); // temp var return (241.88 * T) / (17.558-T); } // EOF