1- /* DHT library
1+ /* DHT library
22
33MIT license
44written by Adafruit Industries
@@ -9,8 +9,9 @@ written by Adafruit Industries
99DHT::DHT (uint8_t pin, uint8_t type, uint8_t count) {
1010 _pin = pin;
1111 _type = type;
12- _count = count;
13- firstreading = true ;
12+ _firstreading = true ;
13+ // Note that count is now ignored as the DHT reading algorithm adjusts itself
14+ // basd on the speed of the processor.
1415}
1516
1617void DHT::begin (void ) {
@@ -22,158 +23,198 @@ void DHT::begin(void) {
2223
2324// boolean S == Scale. True == Farenheit; False == Celcius
2425float DHT::readTemperature (bool S) {
25- float f;
26+ float f = NAN ;
2627
2728 if (read ()) {
2829 switch (_type) {
2930 case DHT11:
3031 f = data[2 ];
31- if (S)
32- f = convertCtoF (f);
33-
34- return f ;
32+ if (S) {
33+ f = convertCtoF (f);
34+ }
35+ break ;
3536 case DHT22:
3637 case DHT21:
3738 f = data[2 ] & 0x7F ;
3839 f *= 256 ;
3940 f += data[3 ];
4041 f /= 10 ;
41- if (data[2 ] & 0x80 )
42- f *= -1 ;
43- if (S)
44- f = convertCtoF (f);
45-
46- return f;
42+ if (data[2 ] & 0x80 ) {
43+ f *= -1 ;
44+ }
45+ if (S) {
46+ f = convertCtoF (f);
47+ }
48+ break ;
4749 }
4850 }
49- return NAN ;
51+ return f ;
5052}
5153
5254float DHT::convertCtoF (float c) {
53- return c * 9 / 5 + 32 ;
55+ return c * 9 / 5 + 32 ;
5456}
5557
5658float DHT::convertFtoC (float f) {
57- return (f - 32 ) * 5 / 9 ;
59+ return (f - 32 ) * 5 / 9 ;
5860}
5961
6062float DHT::readHumidity (void ) {
61- float f;
63+ float f = NAN ;
6264 if (read ()) {
6365 switch (_type) {
6466 case DHT11:
6567 f = data[0 ];
66- return f ;
68+ break ;
6769 case DHT22:
6870 case DHT21:
6971 f = data[0 ];
7072 f *= 256 ;
7173 f += data[1 ];
7274 f /= 10 ;
73- return f ;
75+ break ;
7476 }
7577 }
76- return NAN ;
78+ return f ;
7779}
7880
7981float DHT::computeHeatIndex (float tempFahrenheit, float percentHumidity) {
8082 // Adapted from equation at: https://github.com/adafruit/DHT-sensor-library/issues/9 and
8183 // Wikipedia: http://en.wikipedia.org/wiki/Heat_index
82- return -42.379 +
83- 2.04901523 * tempFahrenheit +
84+ return -42.379 +
85+ 2.04901523 * tempFahrenheit +
8486 10.14333127 * percentHumidity +
8587 -0.22475541 * tempFahrenheit*percentHumidity +
8688 -0.00683783 * pow (tempFahrenheit, 2 ) +
87- -0.05481717 * pow (percentHumidity, 2 ) +
88- 0.00122874 * pow (tempFahrenheit, 2 ) * percentHumidity +
89+ -0.05481717 * pow (percentHumidity, 2 ) +
90+ 0.00122874 * pow (tempFahrenheit, 2 ) * percentHumidity +
8991 0.00085282 * tempFahrenheit*pow (percentHumidity, 2 ) +
9092 -0.00000199 * pow (tempFahrenheit, 2 ) * pow (percentHumidity, 2 );
9193}
9294
93-
9495boolean DHT::read (void ) {
95- uint8_t laststate = HIGH;
96- uint8_t counter = 0 ;
97- uint8_t j = 0 , i;
98- unsigned long currenttime;
99-
10096 // Check if sensor was read less than two seconds ago and return early
10197 // to use last reading.
102- currenttime = millis ();
98+ uint32_t currenttime = millis ();
10399 if (currenttime < _lastreadtime) {
104100 // ie there was a rollover
105101 _lastreadtime = 0 ;
106102 }
107- if (!firstreading && ((currenttime - _lastreadtime) < 2000 )) {
108- return true ; // return last correct measurement
109- // delay(2000 - (currenttime - _lastreadtime));
103+ if (!_firstreading && ((currenttime - _lastreadtime) < 2000 )) {
104+ return _lastresult; // return last correct measurement
110105 }
111- firstreading = false ;
112- /*
113- Serial.print("Currtime: "); Serial.print(currenttime);
114- Serial.print(" Lasttime: "); Serial.print(_lastreadtime);
115- */
106+ _firstreading = false ;
116107 _lastreadtime = millis ();
117108
109+ // Reset 40 bits of received data to zero.
118110 data[0 ] = data[1 ] = data[2 ] = data[3 ] = data[4 ] = 0 ;
119-
120- // pull the pin high and wait 250 milliseconds
111+
112+ // Send start signal. See DHT datasheet for full signal diagram:
113+ // http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
114+
115+ // Go into high impedence state to let pull-up raise data line level and
116+ // start the reading process.
121117 digitalWrite (_pin, HIGH);
122118 delay (250 );
123119
124- // now pull it low for ~ 20 milliseconds
120+ // First set data line low for 20 milliseconds.
125121 pinMode (_pin, OUTPUT);
126122 digitalWrite (_pin, LOW);
127123 delay (20 );
124+
125+ // Turn off interrupts temporarily because the next sections are timing critical
126+ // and we don't want any interruptions.
128127 noInterrupts ();
128+
129+ // End the start signal by setting data line high for 40 microseconds.
129130 digitalWrite (_pin, HIGH);
130131 delayMicroseconds (40 );
132+
133+ // Now start reading the data line to get the value from the DHT sensor.
131134 pinMode (_pin, INPUT);
135+ delayMicroseconds (10 ); // Delay a bit to let sensor pull data line low.
136+
137+ // First expect a low signal for ~80 microseconds followed by a high signal
138+ // for ~80 microseconds again.
139+ if (expectPulse (LOW) == 0 ) {
140+ DEBUG_PRINTLN (F (" Timeout waiting for start signal low pulse." ));
141+ _lastresult = false ;
142+ return _lastresult;
143+ }
144+ if (expectPulse (HIGH) == 0 ) {
145+ DEBUG_PRINTLN (F (" Timeout waiting for start signal high pulse." ));
146+ _lastresult = false ;
147+ return _lastresult;
148+ }
132149
133- // read in timings
134- for ( i=0 ; i< MAXTIMINGS; i++) {
135- counter = 0 ;
136- while (digitalRead (_pin) == laststate) {
137- counter++;
138- delayMicroseconds (1 );
139- if (counter == 255 ) {
140- break ;
141- }
150+ // Now read the 40 bits sent by the sensor. Each bit is sent as a 50
151+ // microsecond low pulse followed by a variable length high pulse. If the
152+ // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds
153+ // then it's a 1. We measure the cycle count of the initial 50us low pulse
154+ // and use that to compare to the cycle count of the high pulse to determine
155+ // if the bit is a 0 (high state cycle count < low state cycle count), or a
156+ // 1 (high state cycle count > low state cycle count).
157+ for (int i=0 ; i<40 ; ++i) {
158+ uint32_t lowCycles = expectPulse (LOW);
159+ if (lowCycles == 0 ) {
160+ DEBUG_PRINTLN (F (" Timeout waiting for bit low pulse." ));
161+ _lastresult = false ;
162+ return _lastresult;
142163 }
143- laststate = digitalRead (_pin);
144-
145- if (counter == 255 ) break ;
146-
147- // ignore first 3 transitions
148- if ((i >= 4 ) && (i%2 == 0 )) {
149- // shove each bit into the storage bytes
150- data[j/8 ] <<= 1 ;
151- if (counter > _count)
152- data[j/8 ] |= 1 ;
153- j++;
164+ uint32_t highCycles = expectPulse (HIGH);
165+ if (highCycles == 0 ) {
166+ DEBUG_PRINTLN (F (" Timeout waiting for bit high pulse." ));
167+ _lastresult = false ;
168+ return _lastresult;
154169 }
155-
170+ data[i/8 ] <<= 1 ;
171+ // Now compare the low and high cycle times to see if the bit is a 0 or 1.
172+ if (highCycles > lowCycles) {
173+ // High cycles are greater than 50us low cycle count, must be a 1.
174+ data[i/8 ] |= 1 ;
175+ }
176+ // Else high cycles are less than (or equal to, a weird case) the 50us low
177+ // cycle count so this must be a zero. Nothing needs to be changed in the
178+ // stored data.
156179 }
157180
181+ // Re-enable interrupts, timing critical code is complete.
158182 interrupts ();
159-
160- /*
161- Serial.println(j, DEC);
162- Serial.print(data[0], HEX); Serial.print(", ");
163- Serial.print(data[1], HEX); Serial.print(", ");
164- Serial.print(data[2], HEX); Serial.print(", ");
165- Serial.print(data[3], HEX); Serial.print(", ");
166- Serial.print(data[4], HEX); Serial.print(" =? ");
167- Serial.println(data[0] + data[1] + data[2] + data[3], HEX);
168- */
169-
170- // check we read 40 bits and that the checksum matches
171- if ((j >= 40 ) &&
172- (data[4 ] == ((data[0 ] + data[1 ] + data[2 ] + data[3 ]) & 0xFF )) ) {
173- return true ;
174- }
175-
176183
177- return false ;
184+ DEBUG_PRINTLN (F (" Received:" ));
185+ DEBUG_PRINT (data[0 ], HEX); DEBUG_PRINT (F (" , " ));
186+ DEBUG_PRINT (data[1 ], HEX); DEBUG_PRINT (F (" , " ));
187+ DEBUG_PRINT (data[2 ], HEX); DEBUG_PRINT (F (" , " ));
188+ DEBUG_PRINT (data[3 ], HEX); DEBUG_PRINT (F (" , " ));
189+ DEBUG_PRINT (data[4 ], HEX); DEBUG_PRINT (F (" =? " ));
190+ DEBUG_PRINTLN (data[0 ] + data[1 ] + data[2 ] + data[3 ], HEX);
191+
192+ // Check we read 40 bits and that the checksum matches.
193+ if (data[4 ] == ((data[0 ] + data[1 ] + data[2 ] + data[3 ]) & 0xFF )) {
194+ _lastresult = true ;
195+ return _lastresult;
196+ }
197+ else {
198+ DEBUG_PRINTLN (F (" Checksum failure!" ));
199+ _lastresult = false ;
200+ return _lastresult;
201+ }
202+ }
178203
204+ // Expect the signal line to be at the specified level for a period of time and
205+ // return a count of loop cycles spent at that level (this cycle count can be
206+ // used to compare the relative time of two pulses). If more than a millisecond
207+ // ellapses without the level changing then the call fails with a 0 response.
208+ uint32_t DHT::expectPulse (bool level) {
209+ uint32_t count = 0 ;
210+ uint32_t end = micros () + 1000 ;
211+ // Loop while counting cycles until the level changes.
212+ while (digitalRead (_pin) == level) {
213+ count++;
214+ if (micros () >= end) {
215+ // Exceeded timeout waiting for level to change, fail.
216+ return 0 ;
217+ }
218+ }
219+ return count;
179220}
0 commit comments