Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00071
00072 DigitalInOut DHT_io(_pin);
00073
00074
00075 if (ERROR_NONE != stall(DHT_io, 0, 250))
00076 {
00077 return BUS_BUSY;
00078 }
00079
00080
00081 DHT_io.output();
00082 DHT_io = 0;
00083
00084 (_DHTtype == 22) ? wait_ms(18) : wait(1);
00085 DHT_io = 1;
00086 wait_us(30);
00087 DHT_io.input();
00088
00089 if (ERROR_NONE != stall(DHT_io, 1, 40))
00090 {
00091 return ERROR_NOT_PRESENT;
00092 }
00093
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
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
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
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
00135
00136 data_valid = DHT_data[0] + DHT_data[1] + DHT_data[2] + DHT_data[3];
00137 if (DHT_data[4] == data_valid)
00138 {
00139
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
00190
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);
00201 return (241.88 * T) / (17.558 - T);
00202 }
00203
00204
00205
00206
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