Interrupt driven DHT11/DHT22 library, port of Arduino idDHTLib (https://github.com/niesteszeck/idDHTLib)
Revision 0:53913db38502, committed 2013-11-19
- Comitter:
- kfigiela
- Date:
- Tue Nov 19 19:36:47 2013 +0000
- Commit message:
- DHT11 and DHT22 working
Changed in this revision
idDHTLib.cpp | Show annotated file Show diff for this revision Revisions of this file |
idDHTLib.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idDHTLib.cpp Tue Nov 19 19:36:47 2013 +0000 @@ -0,0 +1,218 @@ +/* + 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 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idDHTLib.h Tue Nov 19 19:36:47 2013 +0000 @@ -0,0 +1,87 @@ +/* + FILE: idDHTLib.h + 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) + */ + +#ifndef idDHTLib_H__ +#define idDHTLib_H__ + +#define IDDHTLIB_VERSION "0.0.3" +#include "mbed.h" + +// state codes +#define IDDHTLIB_OK 0 +#define IDDHTLIB_ACQUIRING 1 +#define IDDHTLIB_ACQUIRED 2 +#define IDDHTLIB_RESPONSE_OK 3 + +// error codes +#define IDDHTLIB_ERROR_CHECKSUM -1 +#define IDDHTLIB_ERROR_TIMEOUT -2 +#define IDDHTLIB_ERROR_ACQUIRING -3 +#define IDDHTLIB_ERROR_DELTA -4 +#define IDDHTLIB_ERROR_NOTSTARTED -5 + +#define IDDHTLIB_CHECK_STATE if(state == STOPPED) \ + return status; \ + else if(state != ACQUIRED) \ + return IDDHTLIB_ERROR_ACQUIRING; + +class idDHTLib +{ +public: + idDHTLib(PinName pin, void (*isrCallback_wrapper)()); + void init(PinName pin, void (*isrCallback_wrapper)()); + void dht11Callback(); + void dht22Callback(); + int acquire(); + int acquireAndWait(); + float getCelsius(); + float getFahrenheit(); + float getKelvin(); + double getDewPoint(); + double getDewPointSlow(); + float getHumidity(); + bool acquiring(); + int getStatus(); + +private: + Timer t; + void (*isrCallback_wrapper)(void); + pFunctionPointer_t handler; + enum states{RESPONSE=0,DATA=1,ACQUIRED=2,STOPPED=3,ACQUIRING=4}; + volatile states state; + volatile int status; + volatile char bits[5]; + volatile char cnt; + volatile char idx; +// volatile int us; + + DigitalInOut inOut; + InterruptIn intIn; + PinName pin; + volatile float hum; + volatile float temp; + void isrCallback(bool dht22); +}; +#endif // idDHTLib_H__ \ No newline at end of file