Library for DHT11 DHT22 AM2302 and similar sensors. Now with value after decimal point for DHT22.

Dependents:   Seeed_Grove_Temp_Humidity_Example DHT11_Temp_Humidity IoT_W5500_MQTT

Fork of DHT by Components

Committer:
Sly_fox
Date:
Sat Jan 07 21:58:20 2017 +0000
Revision:
4:0667c68ef5e0
Parent:
3:6937e130feca
Child:
5:cce2105f7365
Changed variable v in the calculation of temperture and humidity from int to float in order to get value behind decimal point for DHT22 sensor.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wimpie 0:9b5b3200688f 1 /*
Wimpie 0:9b5b3200688f 2 * DHT Library for Digital-output Humidity and Temperature sensors
Wimpie 0:9b5b3200688f 3 *
Wimpie 0:9b5b3200688f 4 * Works with DHT11, DHT22
Wimpie 0:9b5b3200688f 5 * SEN11301P, Grove - Temperature&Humidity Sensor (Seeed Studio)
Wimpie 0:9b5b3200688f 6 * SEN51035P, Grove - Temperature&Humidity Sensor Pro (Seeed Studio)
Wimpie 0:9b5b3200688f 7 * AM2302 , temperature-humidity sensor
Wimpie 0:9b5b3200688f 8 * HM2303 , Digital-output humidity and temperature sensor
Wimpie 0:9b5b3200688f 9 *
Wimpie 0:9b5b3200688f 10 * Copyright (C) Wim De Roeve
Wimpie 0:9b5b3200688f 11 * based on DHT22 sensor library by HO WING KIT
sam_grove 2:df22ddf10d75 12 * Arduino DHT11 library
Wimpie 0:9b5b3200688f 13 *
Wimpie 0:9b5b3200688f 14 * Permission is hereby granted, free of charge, to any person obtaining a copy
Wimpie 0:9b5b3200688f 15 * of this software and associated documnetation files (the "Software"), to deal
Wimpie 0:9b5b3200688f 16 * in the Software without restriction, including without limitation the rights
Wimpie 0:9b5b3200688f 17 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
Wimpie 0:9b5b3200688f 18 * copies of the Software, and to permit persons to whom the Software is
Wimpie 0:9b5b3200688f 19 * furished to do so, subject to the following conditions:
Wimpie 0:9b5b3200688f 20 *
Wimpie 0:9b5b3200688f 21 * The above copyright notice and this permission notice shall be included in
Wimpie 0:9b5b3200688f 22 * all copies or substantial portions of the Software.
Wimpie 0:9b5b3200688f 23 *
Wimpie 0:9b5b3200688f 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Wimpie 0:9b5b3200688f 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Wimpie 0:9b5b3200688f 26 * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Wimpie 0:9b5b3200688f 27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Wimpie 0:9b5b3200688f 28 * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Wimpie 0:9b5b3200688f 29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
Wimpie 0:9b5b3200688f 30 * THE SOFTWARE.
Wimpie 0:9b5b3200688f 31 */
Wimpie 0:9b5b3200688f 32
Wimpie 0:9b5b3200688f 33 #include "DHT.h"
Wimpie 0:9b5b3200688f 34
sam_grove 2:df22ddf10d75 35 #define DHT_DATA_BIT_COUNT 40
Wimpie 0:9b5b3200688f 36
sam_grove 2:df22ddf10d75 37 DHT::DHT(PinName pin, eType DHTtype)
sam_grove 2:df22ddf10d75 38 {
Wimpie 0:9b5b3200688f 39 _pin = pin;
Wimpie 0:9b5b3200688f 40 _DHTtype = DHTtype;
sam_grove 2:df22ddf10d75 41 _firsttime = true;
sam_grove 2:df22ddf10d75 42 }
sam_grove 2:df22ddf10d75 43
sam_grove 2:df22ddf10d75 44 DHT::~DHT()
sam_grove 2:df22ddf10d75 45 {
sam_grove 2:df22ddf10d75 46
Wimpie 0:9b5b3200688f 47 }
Wimpie 0:9b5b3200688f 48
sam_grove 2:df22ddf10d75 49 eError DHT::stall(DigitalInOut &io, int const level, int const max_time)
sam_grove 2:df22ddf10d75 50 {
sam_grove 2:df22ddf10d75 51 int cnt = 0;
sam_grove 2:df22ddf10d75 52 while (level == io) {
sam_grove 2:df22ddf10d75 53 if (cnt > max_time) {
sam_grove 2:df22ddf10d75 54 return ERROR_NO_PATIENCE;
sam_grove 2:df22ddf10d75 55 }
sam_grove 2:df22ddf10d75 56 cnt++;
sam_grove 2:df22ddf10d75 57 wait_us(1);
sam_grove 2:df22ddf10d75 58 }
sam_grove 2:df22ddf10d75 59 return ERROR_NONE;
Wimpie 0:9b5b3200688f 60 }
Wimpie 0:9b5b3200688f 61
sam_grove 2:df22ddf10d75 62 eError DHT::readData()
sam_grove 2:df22ddf10d75 63 {
sam_grove 2:df22ddf10d75 64 uint8_t i = 0, j = 0, b = 0, data_valid = 0;
sam_grove 2:df22ddf10d75 65 uint32_t bit_value[DHT_DATA_BIT_COUNT] = {0};
Wimpie 0:9b5b3200688f 66
Wimpie 0:9b5b3200688f 67 eError err = ERROR_NONE;
Wimpie 0:9b5b3200688f 68 time_t currentTime = time(NULL);
Wimpie 0:9b5b3200688f 69
Wimpie 0:9b5b3200688f 70 DigitalInOut DHT_io(_pin);
Wimpie 0:9b5b3200688f 71
sam_grove 2:df22ddf10d75 72 // IO must be in hi state to start
sam_grove 2:df22ddf10d75 73 if (ERROR_NONE != stall(DHT_io, 0, 250)) {
sam_grove 2:df22ddf10d75 74 return BUS_BUSY;
Wimpie 0:9b5b3200688f 75 }
Wimpie 0:9b5b3200688f 76
sam_grove 2:df22ddf10d75 77 // start the transfer
Wimpie 0:9b5b3200688f 78 DHT_io.output();
Wimpie 0:9b5b3200688f 79 DHT_io = 0;
sam_grove 3:6937e130feca 80 wait_ms(18);
Wimpie 0:9b5b3200688f 81 DHT_io = 1;
sam_grove 2:df22ddf10d75 82 wait_us(30);
Wimpie 0:9b5b3200688f 83 DHT_io.input();
sam_grove 2:df22ddf10d75 84 // wait till the sensor grabs the bus
sam_grove 3:6937e130feca 85 if (ERROR_NONE != stall(DHT_io, 1, 100)) {
sam_grove 2:df22ddf10d75 86 return ERROR_NOT_PRESENT;
Wimpie 0:9b5b3200688f 87 }
sam_grove 2:df22ddf10d75 88 // sensor should signal low 80us and then hi 80us
sam_grove 2:df22ddf10d75 89 if (ERROR_NONE != stall(DHT_io, 0, 100)) {
sam_grove 2:df22ddf10d75 90 return ERROR_SYNC_TIMEOUT;
sam_grove 2:df22ddf10d75 91 }
sam_grove 2:df22ddf10d75 92 if (ERROR_NONE != stall(DHT_io, 1, 100)) {
sam_grove 2:df22ddf10d75 93 return ERROR_NO_PATIENCE;
sam_grove 2:df22ddf10d75 94 }
sam_grove 2:df22ddf10d75 95 // capture the data
Wimpie 0:9b5b3200688f 96 for (i = 0; i < 5; i++) {
Wimpie 0:9b5b3200688f 97 for (j = 0; j < 8; j++) {
sam_grove 2:df22ddf10d75 98 if (ERROR_NONE != stall(DHT_io, 0, 75)) {
sam_grove 2:df22ddf10d75 99 return ERROR_DATA_TIMEOUT;
sam_grove 2:df22ddf10d75 100 }
sam_grove 2:df22ddf10d75 101 // logic 0 is 28us max, 1 is 70us
Wimpie 0:9b5b3200688f 102 wait_us(40);
sam_grove 2:df22ddf10d75 103 bit_value[i*8+j] = DHT_io;
sam_grove 2:df22ddf10d75 104 if (ERROR_NONE != stall(DHT_io, 1, 50)) {
sam_grove 2:df22ddf10d75 105 return ERROR_DATA_TIMEOUT;
Wimpie 0:9b5b3200688f 106 }
Wimpie 0:9b5b3200688f 107 }
Wimpie 0:9b5b3200688f 108 }
sam_grove 2:df22ddf10d75 109 // store the data
Wimpie 0:9b5b3200688f 110 for (i = 0; i < 5; i++) {
Wimpie 0:9b5b3200688f 111 b=0;
Wimpie 0:9b5b3200688f 112 for (j=0; j<8; j++) {
sam_grove 2:df22ddf10d75 113 if (bit_value[i*8+j] == 1) {
sam_grove 2:df22ddf10d75 114 b |= (1 << (7-j));
Wimpie 0:9b5b3200688f 115 }
Wimpie 0:9b5b3200688f 116 }
Wimpie 0:9b5b3200688f 117 DHT_data[i]=b;
Wimpie 0:9b5b3200688f 118 }
Wimpie 0:9b5b3200688f 119
sam_grove 2:df22ddf10d75 120 // uncomment to see the checksum error if it exists
Sly_fox 4:0667c68ef5e0 121 // 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]);
sam_grove 2:df22ddf10d75 122 data_valid = DHT_data[0] + DHT_data[1] + DHT_data[2] + DHT_data[3];
sam_grove 2:df22ddf10d75 123 if (DHT_data[4] == data_valid) {
Wimpie 0:9b5b3200688f 124 _lastReadTime = currentTime;
sam_grove 2:df22ddf10d75 125 _lastTemperature = CalcTemperature();
sam_grove 2:df22ddf10d75 126 _lastHumidity = CalcHumidity();
Wimpie 0:9b5b3200688f 127
Wimpie 0:9b5b3200688f 128 } else {
Wimpie 0:9b5b3200688f 129 err = ERROR_CHECKSUM;
Wimpie 0:9b5b3200688f 130 }
Wimpie 0:9b5b3200688f 131
Wimpie 0:9b5b3200688f 132 return err;
Wimpie 0:9b5b3200688f 133
Wimpie 0:9b5b3200688f 134 }
Wimpie 0:9b5b3200688f 135
sam_grove 2:df22ddf10d75 136 float DHT::CalcTemperature()
sam_grove 2:df22ddf10d75 137 {
Sly_fox 4:0667c68ef5e0 138 float v;
Wimpie 0:9b5b3200688f 139
Wimpie 0:9b5b3200688f 140 switch (_DHTtype) {
Wimpie 0:9b5b3200688f 141 case DHT11:
Wimpie 0:9b5b3200688f 142 v = DHT_data[2];
Wimpie 0:9b5b3200688f 143 return float(v);
Wimpie 0:9b5b3200688f 144 case DHT22:
Wimpie 0:9b5b3200688f 145 v = DHT_data[2] & 0x7F;
Wimpie 0:9b5b3200688f 146 v *= 256;
Wimpie 0:9b5b3200688f 147 v += DHT_data[3];
Wimpie 0:9b5b3200688f 148 v /= 10;
Wimpie 0:9b5b3200688f 149 if (DHT_data[2] & 0x80)
Wimpie 0:9b5b3200688f 150 v *= -1;
Wimpie 0:9b5b3200688f 151 return float(v);
Wimpie 0:9b5b3200688f 152 }
Wimpie 0:9b5b3200688f 153 return 0;
Wimpie 0:9b5b3200688f 154 }
Wimpie 0:9b5b3200688f 155
sam_grove 2:df22ddf10d75 156 float DHT::ReadHumidity()
sam_grove 2:df22ddf10d75 157 {
Wimpie 0:9b5b3200688f 158 return _lastHumidity;
Wimpie 0:9b5b3200688f 159 }
Wimpie 0:9b5b3200688f 160
sam_grove 2:df22ddf10d75 161 float DHT::ConvertCelciustoFarenheit(float const celsius)
sam_grove 2:df22ddf10d75 162 {
Wimpie 0:9b5b3200688f 163 return celsius * 9 / 5 + 32;
Wimpie 0:9b5b3200688f 164 }
Wimpie 0:9b5b3200688f 165
sam_grove 2:df22ddf10d75 166 float DHT::ConvertCelciustoKelvin(float const celsius)
sam_grove 2:df22ddf10d75 167 {
sam_grove 3:6937e130feca 168 return celsius + 273.15f;
Wimpie 0:9b5b3200688f 169 }
Wimpie 0:9b5b3200688f 170
Wimpie 0:9b5b3200688f 171 // dewPoint function NOAA
Wimpie 0:9b5b3200688f 172 // reference: http://wahiduddin.net/calc/density_algorithms.htm
sam_grove 2:df22ddf10d75 173 float DHT::CalcdewPoint(float const celsius, float const humidity)
sam_grove 2:df22ddf10d75 174 {
sam_grove 3:6937e130feca 175 float A0= 373.15f/(273.15f + celsius);
Wimpie 0:9b5b3200688f 176 float SUM = -7.90298 * (A0-1);
sam_grove 3:6937e130feca 177 SUM += 5.02808f * log10(A0);
sam_grove 3:6937e130feca 178 SUM += -1.3816e-7 * (pow(10, (11.344f*(1-1/A0)))-1) ;
Wimpie 0:9b5b3200688f 179 SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
Wimpie 0:9b5b3200688f 180 SUM += log10(1013.246);
Wimpie 0:9b5b3200688f 181 float VP = pow(10, SUM-3) * humidity;
sam_grove 3:6937e130feca 182 float T = log(VP/0.61078f); // temp var
sam_grove 3:6937e130feca 183 return (241.88f * T) / (17.558f-T);
Wimpie 0:9b5b3200688f 184 }
Wimpie 0:9b5b3200688f 185
Wimpie 0:9b5b3200688f 186 // delta max = 0.6544 wrt dewPoint()
Wimpie 0:9b5b3200688f 187 // 5x faster than dewPoint()
Wimpie 0:9b5b3200688f 188 // reference: http://en.wikipedia.org/wiki/Dew_point
sam_grove 2:df22ddf10d75 189 float DHT::CalcdewPointFast(float const celsius, float const humidity)
Wimpie 0:9b5b3200688f 190 {
sam_grove 2:df22ddf10d75 191 float a = 17.271;
sam_grove 2:df22ddf10d75 192 float b = 237.7;
sam_grove 2:df22ddf10d75 193 float temp = (a * celsius) / (b + celsius) + log(humidity/100);
sam_grove 2:df22ddf10d75 194 float Td = (b * temp) / (a - temp);
sam_grove 2:df22ddf10d75 195 return Td;
Wimpie 0:9b5b3200688f 196 }
Wimpie 0:9b5b3200688f 197
sam_grove 2:df22ddf10d75 198 float DHT::ReadTemperature(eScale Scale)
sam_grove 2:df22ddf10d75 199 {
Wimpie 0:9b5b3200688f 200 if (Scale == FARENHEIT)
Wimpie 0:9b5b3200688f 201 return ConvertCelciustoFarenheit(_lastTemperature);
Wimpie 0:9b5b3200688f 202 else if (Scale == KELVIN)
Wimpie 0:9b5b3200688f 203 return ConvertCelciustoKelvin(_lastTemperature);
Wimpie 0:9b5b3200688f 204 else
Wimpie 0:9b5b3200688f 205 return _lastTemperature;
Wimpie 0:9b5b3200688f 206 }
Wimpie 0:9b5b3200688f 207
sam_grove 2:df22ddf10d75 208 float DHT::CalcHumidity()
sam_grove 2:df22ddf10d75 209 {
Sly_fox 4:0667c68ef5e0 210 float v; // needs to be float for DHT22 otherwise only zero after decimal point
Wimpie 0:9b5b3200688f 211 switch (_DHTtype) {
Wimpie 0:9b5b3200688f 212 case DHT11:
Wimpie 0:9b5b3200688f 213 v = DHT_data[0];
Wimpie 0:9b5b3200688f 214 return float(v);
Wimpie 0:9b5b3200688f 215 case DHT22:
Wimpie 0:9b5b3200688f 216 v = DHT_data[0];
Wimpie 0:9b5b3200688f 217 v *= 256;
Wimpie 0:9b5b3200688f 218 v += DHT_data[1];
Wimpie 0:9b5b3200688f 219 v /= 10;
Wimpie 0:9b5b3200688f 220 return float(v);
Wimpie 0:9b5b3200688f 221 }
Wimpie 0:9b5b3200688f 222 return 0;
Wimpie 0:9b5b3200688f 223 }
Wimpie 0:9b5b3200688f 224
Wimpie 0:9b5b3200688f 225