Skip to content

Commit 52d6e23

Browse files
committed
Applied DHT22 library FIX as per adafruit/DHT-sensor-library#94 (comment)
1 parent 1c74a7b commit 52d6e23

File tree

1 file changed

+39
-15
lines changed
  • ESP32_Heltec_V1_LoRa_Mote/libraries/DHT_sensor_library

1 file changed

+39
-15
lines changed

ESP32_Heltec_V1_LoRa_Mote/libraries/DHT_sensor_library/DHT.cpp

+39-15
Original file line numberDiff line numberDiff line change
@@ -134,38 +134,61 @@ boolean DHT::read(bool force) {
134134

135135
// Send start signal. See DHT datasheet for full signal diagram:
136136
// http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
137-
138-
// Go into high impedence state to let pull-up raise data line level and
139-
// start the reading process.
140-
digitalWrite(_pin, HIGH);
141-
delay(250);
142-
143-
// First set data line low for 20 milliseconds.
137+
// First set data line low to send start signal.
144138
pinMode(_pin, OUTPUT);
145139
digitalWrite(_pin, LOW);
146-
delay(20);
140+
// set wait time according to sensor type.
141+
switch (_type) {
142+
case DHT22:
143+
case DHT21:
144+
delayMicroseconds(1100); //data sheet says at least 1ms, 1.1ms should be ok
145+
break;
146+
case DHT11:
147+
default:
148+
delay(20); //data sheet says at least 18ms, 20ms just to be safe
149+
break;
150+
}
147151

148152
uint32_t cycles[80];
149153
{
150154
// Turn off interrupts temporarily because the next sections are timing critical
151155
// and we don't want any interruptions.
156+
// NOTE: From this point we cannot use function such as delay(), delayMicroseconds(),
157+
// Those functions among others rely on interrupts.
152158
InterruptLock lock;
153159

154-
// End the start signal by setting data line high for 40 microseconds.
155-
digitalWrite(_pin, HIGH);
156-
delayMicroseconds(40);
157-
160+
// End of the start signal.
158161
// Now start reading the data line to get the value from the DHT sensor.
159162
pinMode(_pin, INPUT_PULLUP);
160-
delayMicroseconds(10); // Delay a bit to let sensor pull data line low.
163+
// from this point we listen, it's sensor's turn to talk.
164+
165+
166+
// The following step is a busy-wait loop to resume processing only
167+
// when the data line has been pulled LOW by the sensor.
168+
//
169+
// To avoid infinite loops here, we use a counter as a timeout.
170+
// 700 iterations is about 4 ms on a 16Mhz processor. The sensor should
171+
// set the pin LOW within 20 to 40 microseconds.
172+
// The (F_CPU / 16000000.0) is a ratio to keep the timeout to approximately
173+
// the same period if processor used runs at a different frequency.
174+
unsigned long timesup = (F_CPU / 16000000.0) * 700;
175+
unsigned long count = 0;
176+
while (digitalRead(_pin) == HIGH && ++count < timesup)
177+
;
178+
if (count == timesup) {
179+
DEBUG_PRINTLN(F("Timeout waiting sensor to pull the data line LOW."));
180+
_lastresult = false;
181+
return _lastresult;
182+
}
161183

162-
// First expect a low signal for ~80 microseconds followed by a high signal
163-
// for ~80 microseconds again.
184+
// expect a low signal for ~80 microseconds.
164185
if (expectPulse(LOW) == 0) {
165186
DEBUG_PRINTLN(F("Timeout waiting for start signal low pulse."));
166187
_lastresult = false;
167188
return _lastresult;
168189
}
190+
191+
// followed by a high signal for ~80 microseconds.
169192
if (expectPulse(HIGH) == 0) {
170193
DEBUG_PRINTLN(F("Timeout waiting for start signal high pulse."));
171194
_lastresult = false;
@@ -184,6 +207,7 @@ boolean DHT::read(bool force) {
184207
cycles[i] = expectPulse(LOW);
185208
cycles[i+1] = expectPulse(HIGH);
186209
}
210+
// Interrupts will turn back on when exiting this scope.
187211
} // Timing critical code is now complete.
188212

189213
// Inspect pulses and determine which ones are 0 (high state cycle count < low

0 commit comments

Comments
 (0)