DHT11 used for Temperature & Humidity sensor.

Dependents:   LoRaWAN_mbed_lmic_agriculture_app

Fork of DHT by Components

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DHT.cpp Source File

DHT.cpp

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  *
00034  * Used by Giorgos Tsapparellas for Internet of Things (IoT) smart monitoring
00035  * device for agriculture using LoRaWAN technology.
00036  * 
00037  * Sensor Used: DHT11 - Digital-output Humidity and Temperature sensor.
00038  *
00039  * Date of issued copy: 10 January 2018
00040  *
00041  * Modifications: 
00042  * - No external modifications of the existing "AS IT IS" software.
00043  * - Added some external comments for meeting good principles of 
00044  *   source code re-usability.   
00045  ******************************************************************************/
00046 
00047 #include "DHT.h"
00048 
00049 #define DHT_DATA_BIT_COUNT 40 // Data bit count set to 40
00050 
00051 /* Uncomment this line for configuring pc variable for UART usage. */
00052 //Serial pc(USBTX, USBRX); // UART tranmitter(tx) and receiver(rx).
00053 
00054 /* 
00055 * DHT constructor.
00056 * Input parameters: PinName pin
00057 *                   eType DHTtype
00058 *
00059 */ 
00060 DHT::DHT(PinName pin, eType DHTtype)
00061 {
00062     
00063     _pin = pin;
00064     _DHTtype = DHTtype;
00065     _firsttime = true;
00066     
00067 } // end of DHT constructor. 
00068 
00069 /* 
00070 * Null DHT destructor.
00071 *
00072 */ 
00073 DHT::~DHT()
00074 {
00075     
00076 } // end of DHT destructor. 
00077 
00078 /* 
00079 * stall DHT function of type eError.
00080 *
00081 * Input parameters: DigitalInOut io
00082 *                   int const level
00083 *                   int const max_time
00084 *
00085 * Return: ERROR_NO_PATIENCE or ERROR_NONE
00086 */ 
00087 eError DHT::stall(DigitalInOut &io, int const level, int const max_time)
00088 {
00089     
00090     int cnt = 0;
00091     while (level == io) {
00092         if (cnt > max_time) {
00093             return ERROR_NO_PATIENCE;
00094         }
00095         cnt++;
00096         wait_us(1);
00097     }
00098     return ERROR_NONE;
00099     
00100 } // end of stall function.
00101 
00102 /* 
00103 * readData DHT function of type eError.
00104 *
00105 * Input parameters: None
00106 *
00107 * Return: Either BUS_BUSY, ERROR_NOT_PRESENT, ERROR_SYNC_TIMEOUT, 
00108 *         ERROR_NO_PATIENCE, ERROR_DATA_TIMEOUT or ERROR_CHECKSUM.     
00109 */ 
00110 eError DHT::readData()
00111 {
00112     uint8_t i = 0, j = 0, b = 0, data_valid = 0;
00113     uint32_t bit_value[DHT_DATA_BIT_COUNT] = {0};
00114 
00115     eError err = ERROR_NONE;
00116     time_t currentTime = time(NULL);
00117 
00118     DigitalInOut DHT_io(_pin);
00119 
00120     // I/O must be in high state to start
00121     if (ERROR_NONE != stall(DHT_io, 0, 250)) {
00122         return BUS_BUSY;
00123     }
00124 
00125     // Start the transfer
00126     DHT_io.output();
00127     DHT_io = 0;
00128     wait_ms(18);
00129     DHT_io = 1;
00130     wait_us(30);
00131     DHT_io.input();
00132     
00133     // Wait until the sensor grabs the bus
00134     if (ERROR_NONE != stall(DHT_io, 1, 100)) {
00135         return ERROR_NOT_PRESENT;
00136     }
00137     // Sensor should signal low 80us and then high 80us
00138     if (ERROR_NONE != stall(DHT_io, 0, 100)) {
00139         return ERROR_SYNC_TIMEOUT;
00140     }
00141     if (ERROR_NONE != stall(DHT_io, 1, 100)) {
00142         return ERROR_NO_PATIENCE;
00143     }
00144     // Capture the data
00145     for (i = 0; i < 5; i++) {
00146         for (j = 0; j < 8; j++) {
00147             if (ERROR_NONE != stall(DHT_io, 0, 75)) {
00148                 return ERROR_DATA_TIMEOUT;
00149             }
00150             // Logic 0 is 28us max, 1 is 70us
00151             wait_us(40);
00152             bit_value[i*8+j] = DHT_io;
00153             if (ERROR_NONE != stall(DHT_io, 1, 50)) {
00154                 return ERROR_DATA_TIMEOUT;
00155             }
00156         }
00157     }
00158     // Store the data
00159     for (i = 0; i < 5; i++) {
00160         b=0;
00161         for (j=0; j<8; j++) {
00162             if (bit_value[i*8+j] == 1) {
00163                 b |= (1 << (7-j));
00164             }
00165         }
00166         DHT_data[i]=b;
00167     }
00168 
00169     // Uncomment to see the checksum error if it exists
00170     // pc.printf(" 0x%02x + 0x%02x + 0x%02x + 0x%02x = 0x%02x \n", DHT_data[0],
00171     // DHT_data[1], DHT_data[2], DHT_data[3], DHT_data[4]);
00172     data_valid = DHT_data[0] + DHT_data[1] + DHT_data[2] + DHT_data[3];
00173     if (DHT_data[4] == data_valid) {
00174         _lastReadTime = currentTime;
00175         _lastTemperature = CalcTemperature();
00176         _lastHumidity = CalcHumidity();
00177 
00178     } else {
00179         err = ERROR_CHECKSUM;
00180     }
00181 
00182     return err;
00183     
00184 } // end of readData function.
00185 
00186 /* 
00187 * CalcTemperature DHT function of type float.
00188 *
00189 * Input parameters: None
00190 *
00191 * Return: float temperature value.     
00192 */ 
00193 float DHT::CalcTemperature()
00194 {
00195     
00196     int v;
00197 
00198     switch (_DHTtype) {
00199         case DHT11:
00200             v = DHT_data[2];
00201             return float(v);
00202         case DHT22:
00203             v = DHT_data[2] & 0x7F;
00204             v *= 256;
00205             v += DHT_data[3];
00206             v /= 10;
00207             if (DHT_data[2] & 0x80)
00208                 v *= -1;
00209             return float(v);
00210     }
00211     return 0;
00212     
00213 } // end of CalcTemperature function.
00214 
00215 /*
00216 * ReadHumidity DHT function of type float.
00217 *
00218 * Input parameters: None
00219 *
00220 * Return: float last humidity value.     
00221 */ 
00222 float DHT::ReadHumidity()
00223 {
00224     return _lastHumidity;
00225 } // end of ReadHumidity function.
00226 
00227 /*
00228 * ConvertCelsiustoFarenheit DHT function of type float.
00229 *
00230 * Input parameters: float const celsius
00231 *
00232 * Return: float farenheit temperature value.     
00233 */ 
00234 float DHT::ConvertCelciustoFarenheit(float const celsius)
00235 {
00236     return celsius * 9 / 5 + 32;
00237 } // end of ConvertCelciustoFarenheit function.
00238 
00239 /*
00240 * ConvertCelsiustoKelvin DHT function of type float.
00241 *
00242 * Input parameters: float const celsius
00243 *
00244 * Return: float kelvin temperature value.     
00245 */ 
00246 float DHT::ConvertCelciustoKelvin(float const celsius)
00247 {
00248     return celsius + 273.15f;
00249 } // end of ConvertCelciusKelvin function.
00250 
00251 /*
00252 * CalcdewPoint DHT function of type float.
00253 *
00254 * Input parameters: float const celsius
00255 *                   float const humidity
00256 *
00257 * Return: dewPoint.     
00258 * Reference: http://wahiduddin.net/calc/density_algorithms.htm
00259 */ 
00260 float DHT::CalcdewPoint(float const celsius, float const humidity)
00261 {
00262     float A0= 373.15f/(273.15f + celsius);
00263     float SUM = -7.90298 * (A0-1);
00264     SUM += 5.02808f * log10(A0);
00265     SUM += -1.3816e-7 * (pow(10, (11.344f*(1-1/A0)))-1) ;
00266     SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
00267     SUM += log10(1013.246);
00268     float VP = pow(10, SUM-3) * humidity;
00269     float T = log(VP/0.61078f);   // temp var
00270     return (241.88f * T) / (17.558f-T);
00271     
00272 } // end of CalcdewPoint function.
00273 
00274 /*
00275 * CalcdewPointFast DHT function of type float.
00276 *
00277 * Input parameters: float const celsius
00278 *                   float const humidity
00279 *
00280 * Return: 5x faster dewPoint.     
00281 * Reference: http://en.wikipedia.org/wiki/Dew_point
00282 */ 
00283 float DHT::CalcdewPointFast(float const celsius, float const humidity)
00284 {
00285     float a = 17.271;
00286     float b = 237.7;
00287     float temp = (a * celsius) / (b + celsius) + log(humidity/100);
00288     float Td = (b * temp) / (a - temp);
00289     return Td;
00290     
00291 } // end of CalcdewPointFast function 
00292 
00293 /*
00294 * ReadTemperature DHT function of type float.
00295 *
00296 * Input parameters: eScale Scale
00297 *
00298 * Return: float scaled temperature value.     
00299 * Reference: http://en.wikipedia.org/wiki/Dew_point
00300 */ 
00301 float DHT::ReadTemperature(eScale Scale)
00302 {
00303     if (Scale == FARENHEIT)
00304         return ConvertCelciustoFarenheit(_lastTemperature);
00305     else if (Scale == KELVIN)
00306         return ConvertCelciustoKelvin(_lastTemperature);
00307     else
00308         return _lastTemperature;
00309 } // end of ReadTemperature function.
00310 
00311 /*
00312 * Calc DHT function of type float.
00313 *
00314 * Input parameters: None
00315 *
00316 * Return: float humidity value.     
00317 */ 
00318 float DHT::CalcHumidity()
00319 {
00320     int v;
00321 
00322     switch (_DHTtype) {
00323         case DHT11:
00324             v = DHT_data[0];
00325             return float(v);
00326         case DHT22:
00327             v = DHT_data[0];
00328             v *= 256;
00329             v += DHT_data[1];
00330             v /= 10;
00331             return float(v);
00332     }
00333     return 0;
00334 } // end of CalcHumidity function.