Freeman Oldman / NUCLEO_STM32F401RE_CC3000_ILI9341
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DHT.cpp Source File

DHT.cpp

00001 #include "DHT.h"
00002 
00003 
00004 #define DHT_DATA_BIT_COUNT 41
00005 
00006 DHT::DHT(PinName pin,int DHTtype)
00007     : _mutex()
00008 {
00009     _pin = pin;
00010     _DHTtype = DHTtype;
00011     _firsttime=true;
00012 }
00013 
00014 DHT::~DHT() {
00015 }
00016 
00017 int DHT::readData() 
00018 {
00019 
00020     
00021    int err = ERROR_NONE;
00022    Timer tmr;
00023 
00024      DigitalInOut data_pin(_pin);
00025         // We make sure we are the only ones
00026         // reading data right now.
00027        _mutex.lock();
00028     
00029     // BUFFER TO RECEIVE
00030     uint8_t cnt = 7;
00031     uint8_t idx = 0;
00032     
00033     tmr.stop();
00034     tmr.reset();
00035  
00036     // EMPTY BUFFER
00037     for(int i=0; i< 5; i++) DHT_data[i] = 0;
00038  
00039     // REQUEST SAMPLE
00040     data_pin.output();
00041     data_pin.write(0);
00042     wait_ms(18);
00043     data_pin.write(1);
00044     wait_us(40);
00045     data_pin.input();
00046  
00047     // ACKNOWLEDGE or TIMEOUT
00048     unsigned int loopCnt = 10000;
00049     
00050     while(!data_pin.read())if(!loopCnt--)
00051         {
00052             _mutex.unlock();
00053             return ERROR_DATA_TIMEOUT;
00054         }
00055  
00056     loopCnt = 10000;
00057     
00058     while(data_pin.read())if(!loopCnt--)
00059         {
00060             _mutex.unlock();
00061             return ERROR_DATA_TIMEOUT;
00062         }
00063  
00064     // READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
00065     for(int i=0; i<40; i++){
00066         
00067         loopCnt = 10000;
00068         
00069         while(!data_pin.read())if(loopCnt-- == 0)
00070                 {
00071                     _mutex.unlock();
00072                     return ERROR_DATA_TIMEOUT;
00073                 }
00074  
00075         //unsigned long t = micros();
00076         tmr.start();
00077  
00078         loopCnt = 10000;
00079         
00080         while(data_pin.read())if(!loopCnt--)
00081                 {
00082                     _mutex.unlock();
00083                     return ERROR_DATA_TIMEOUT;
00084                 }
00085  
00086         if(tmr.read_us() > 40) DHT_data[idx] |= (1 << cnt);
00087         
00088         tmr.stop();
00089         tmr.reset();
00090         
00091         if(cnt == 0){   // next byte?
00092         
00093             cnt = 7;    // restart at MSB
00094             idx++;      // next byte!
00095             
00096         }else cnt--;
00097         
00098     }
00099  
00100     // WRITE TO RIGHT VARS
00101     uint8_t sum = (DHT_data[0] + DHT_data[1] + DHT_data[2] + DHT_data[3]) & 0xFF;  
00102  
00103     if(DHT_data[4] != sum)
00104         { 
00105             _mutex.unlock();
00106             return ERROR_CHECKSUM;
00107         }
00108         
00109     _lastTemperature= CalcTemperature();
00110     _lastHumidity= CalcHumidity();
00111     
00112         _mutex.unlock();
00113     return err;
00114 }
00115 
00116 
00117 float DHT::ReadHumidity() {
00118     return _lastHumidity;
00119 }
00120 
00121 float DHT::ConvertCelciustoFarenheit(float celsius) {
00122     return celsius * 9 / 5 + 32;
00123 }
00124 
00125 float DHT::ConvertCelciustoKelvin(float celsius) {
00126     return celsius + 273.15;
00127 }
00128 
00129 // dewPoint function NOAA
00130 // reference: http://wahiduddin.net/calc/density_algorithms.htm
00131 float DHT::CalcdewPoint(float celsius, float humidity) {
00132     float A0= 373.15/(273.15 + celsius);
00133     float SUM = -7.90298 * (A0-1);
00134     SUM += 5.02808 * log10(A0);
00135     SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
00136     SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
00137     SUM += log10(1013.246);
00138     float VP = pow(10, SUM-3) * humidity;
00139     float T = log(VP/0.61078);   // temp var
00140     return (241.88 * T) / (17.558-T);
00141 }
00142 
00143 // delta max = 0.6544 wrt dewPoint()
00144 // 5x faster than dewPoint()
00145 // reference: http://en.wikipedia.org/wiki/Dew_point
00146 float DHT::CalcdewPointFast(float celsius, float humidity)
00147 {
00148         float a = 17.271;
00149         float b = 237.7;
00150         float temp = (a * celsius) / (b + celsius) + log(humidity/100);
00151         float Td = (b * temp) / (a - temp);
00152         return Td;
00153 }
00154 
00155 float DHT::ReadTemperature(eScale Scale) {
00156     if (Scale == FARENHEIT)
00157         return ConvertCelciustoFarenheit(_lastTemperature);
00158     else if (Scale == KELVIN)
00159         return ConvertCelciustoKelvin(_lastTemperature);
00160     else
00161         return _lastTemperature;
00162 }
00163 
00164 float DHT::CalcTemperature() {
00165     int v;
00166 
00167     switch (_DHTtype) {
00168         case DHT11:
00169             v = DHT_data[2];
00170             return float(v);
00171         case DHT22:
00172             v = DHT_data[2] & 0x7F;
00173             v *= 256;
00174             v += DHT_data[3];
00175             v /= 10;
00176             if (DHT_data[2] & 0x80)
00177                 v *= -1;
00178             return float(v);
00179     }
00180     return 0;
00181 }
00182 
00183 float DHT::CalcHumidity() {
00184     int v;
00185 
00186     switch (_DHTtype) {
00187         case DHT11:
00188             v = DHT_data[0];
00189             return float(v);
00190         case DHT22:
00191             v = DHT_data[0];
00192             v *= 256;
00193             v += DHT_data[1];
00194             v /= 10;
00195             return float(v);
00196     }
00197     return 0;
00198 }
00199 
00200