DHT.cpp
Go to the documentation of this file.
00001 /*
00002  *  DHT Library for  Digital-output Humidity and Temperature sensors
00003  *
00004  *  Works with DHT11, DHT22
00005  *             SEN11301P,  Grove - Temperature&Humidity Sensor     (Seeed Studio)
00006  *             SEN51035P,  Grove - Temperature&Humidity Sensor Pro (Seeed Studio)
00007  *             AM2302   ,  temperature-humidity sensor
00008  *             HM2303   ,  Digital-output humidity and temperature sensor
00009  *
00010  *  Copyright (C) Wim De Roeve
00011  *                based on DHT22 sensor library by HO WING KIT
00012  *                Arduino DHT11 library
00013  *
00014  * Permission is hereby granted, free of charge, to any person obtaining a copy
00015  * of this software and associated documnetation files (the "Software"), to deal
00016  * in the Software without restriction, including without limitation the rights
00017  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00018  * copies of the Software, and to permit persons to  whom the Software is
00019  * furished to do so, subject to the following conditions:
00020  *
00021  * The above copyright notice and this permission notice shall be included in
00022  * all copies or substantial portions of the Software.
00023  *
00024  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00025  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00026  * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00027  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00028  * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00029  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00030  * THE SOFTWARE.
00031  */
00032 
00033 #include "DHT.h"
00034 
00035 #define DHT_DATA_BIT_COUNT 40
00036 
00037 DHT::DHT(PinName pin, eType DHTtype)
00038 {
00039   _pin = pin;
00040   _DHTtype = DHTtype;
00041   _firsttime = true;
00042 }
00043 
00044 DHT::~DHT()
00045 {
00046 
00047 }
00048 
00049 eError DHT::stall(DigitalInOut &io, int const level, int const max_time)
00050 {
00051   int cnt = 0;
00052   while (level == io)
00053   {
00054     if (cnt > max_time)
00055     {
00056       return ERROR_NO_PATIENCE;
00057     }
00058     cnt++;
00059     wait_us(1);
00060   }
00061   return ERROR_NONE;
00062 }
00063 
00064 eError DHT::readData()
00065 {
00066   uint8_t i = 0, j = 0, b = 0, data_valid = 0;
00067   uint32_t bit_value[DHT_DATA_BIT_COUNT] = {0};
00068 
00069   eError err = ERROR_NONE;
00070   //time_t currentTime = time(NULL);
00071 
00072   DigitalInOut DHT_io(_pin);
00073 
00074   // IO must be in hi state to start
00075   if (ERROR_NONE != stall(DHT_io, 0, 250))
00076   {
00077     return BUS_BUSY;
00078   }
00079 
00080   // start the transfer
00081   DHT_io.output();
00082   DHT_io = 0;
00083   // only 500uS for DHT22 but 18ms for DHT11
00084   (_DHTtype == 22) ? wait_ms(18) : wait(1);
00085   DHT_io = 1;
00086   wait_us(30);
00087   DHT_io.input();
00088   // wait till the sensor grabs the bus
00089   if (ERROR_NONE != stall(DHT_io, 1, 40))
00090   {
00091     return ERROR_NOT_PRESENT;
00092   }
00093   // sensor should signal low 80us and then hi 80us
00094   if (ERROR_NONE != stall(DHT_io, 0, 100))
00095   {
00096     return ERROR_SYNC_TIMEOUT;
00097   }
00098   if (ERROR_NONE != stall(DHT_io, 1, 100))
00099   {
00100     return ERROR_NO_PATIENCE;
00101   }
00102   // capture the data
00103   for (i = 0; i < 5; i++)
00104   {
00105     for (j = 0; j < 8; j++)
00106     {
00107       if (ERROR_NONE != stall(DHT_io, 0, 75))
00108       {
00109         return ERROR_DATA_TIMEOUT;
00110       }
00111       // logic 0 is 28us max, 1 is 70us
00112       wait_us(40);
00113       bit_value[i * 8 + j] = DHT_io;
00114       if (ERROR_NONE != stall(DHT_io, 1, 50))
00115       {
00116         return ERROR_DATA_TIMEOUT;
00117       }
00118     }
00119   }
00120   // store the data
00121   for (i = 0; i < 5; i++)
00122   {
00123     b = 0;
00124     for (j = 0; j < 8; j++)
00125     {
00126       if (bit_value[i * 8 + j] == 1)
00127       {
00128         b |= (1 << (7 - j));
00129       }
00130     }
00131     DHT_data[i] = b;
00132   }
00133 
00134   // uncomment to see the checksum error if it exists
00135   //printf(" 0x%02x + 0x%02x + 0x%02x + 0x%02x = 0x%02x \n", DHT_data[0], DHT_data[1], DHT_data[2], DHT_data[3], DHT_data[4]);
00136   data_valid = DHT_data[0] + DHT_data[1] + DHT_data[2] + DHT_data[3];
00137   if (DHT_data[4] == data_valid)
00138   {
00139     //_lastReadTime = currentTime;
00140     _lastTemperature = CalcTemperature();
00141     _lastHumidity = CalcHumidity();
00142 
00143   }
00144   else
00145   {
00146     err = ERROR_CHECKSUM;
00147   }
00148 
00149   return err;
00150 
00151 }
00152 
00153 float DHT::CalcTemperature()
00154 {
00155   int v;
00156 
00157   switch (_DHTtype)
00158   {
00159   case DHT11:
00160     v = DHT_data[2];
00161     return float(v);
00162   case DHT22:
00163     v = DHT_data[2] & 0x7F;
00164     v *= 256;
00165     v += DHT_data[3];
00166     v /= 10;
00167     if (DHT_data[2] & 0x80)
00168       v *= -1;
00169     return float(v);
00170   }
00171   return 0;
00172 }
00173 
00174 float DHT::ReadHumidity()
00175 {
00176   return _lastHumidity;
00177 }
00178 
00179 float DHT::ConvertCelciustoFarenheit(float const celsius)
00180 {
00181   return celsius * 9 / 5 + 32;
00182 }
00183 
00184 float DHT::ConvertCelciustoKelvin(float const celsius)
00185 {
00186   return celsius + 273.15;
00187 }
00188 
00189 // dewPoint function NOAA
00190 // reference: http://wahiduddin.net/calc/density_algorithms.htm
00191 float DHT::CalcdewPoint(float const celsius, float const humidity)
00192 {
00193   float A0 = 373.15 / (273.15 + celsius);
00194   float SUM = -7.90298 * (A0 - 1);
00195   SUM += 5.02808 * log10(A0);
00196   SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / A0))) - 1) ;
00197   SUM += 8.1328e-3 * (pow(10, (-3.49149 * (A0 - 1))) - 1) ;
00198   SUM += log10(1013.246);
00199   float VP = pow(10, SUM - 3) * humidity;
00200   float T = log(VP / 0.61078); // temp var
00201   return (241.88 * T) / (17.558 - T);
00202 }
00203 
00204 // delta max = 0.6544 wrt dewPoint()
00205 // 5x faster than dewPoint()
00206 // reference: http://en.wikipedia.org/wiki/Dew_point
00207 float DHT::CalcdewPointFast(float const celsius, float const humidity)
00208 {
00209   float a = 17.271;
00210   float b = 237.7;
00211   float temp = (a * celsius) / (b + celsius) + log(humidity / 100);
00212   float Td = (b * temp) / (a - temp);
00213   return Td;
00214 }
00215 
00216 float DHT::ReadTemperature(eScale Scale)
00217 {
00218   if (Scale == FARENHEIT)
00219     return ConvertCelciustoFarenheit(_lastTemperature);
00220   else if (Scale == KELVIN)
00221     return ConvertCelciustoKelvin(_lastTemperature);
00222   else
00223     return _lastTemperature;
00224 }
00225 
00226 float DHT::CalcHumidity()
00227 {
00228   int v;
00229 
00230   switch (_DHTtype)
00231   {
00232   case DHT11:
00233     v = DHT_data[0];
00234     return float(v);
00235   case DHT22:
00236     v = DHT_data[0];
00237     v *= 256;
00238     v += DHT_data[1];
00239     v /= 10;
00240     return float(v);
00241   }
00242   return 0;
00243 }
00244 
00245 


rosserial_mbed
Author(s): Gary Servin
autogenerated on Sat Oct 7 2017 03:08:46