@@ -134,38 +134,61 @@ boolean DHT::read(bool force) {
134
134
135
135
// Send start signal. See DHT datasheet for full signal diagram:
136
136
// 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.
144
138
pinMode (_pin, OUTPUT);
145
139
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
+ }
147
151
148
152
uint32_t cycles[80 ];
149
153
{
150
154
// Turn off interrupts temporarily because the next sections are timing critical
151
155
// 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.
152
158
InterruptLock lock;
153
159
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.
158
161
// Now start reading the data line to get the value from the DHT sensor.
159
162
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
+ }
161
183
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.
164
185
if (expectPulse (LOW) == 0 ) {
165
186
DEBUG_PRINTLN (F (" Timeout waiting for start signal low pulse." ));
166
187
_lastresult = false ;
167
188
return _lastresult;
168
189
}
190
+
191
+ // followed by a high signal for ~80 microseconds.
169
192
if (expectPulse (HIGH) == 0 ) {
170
193
DEBUG_PRINTLN (F (" Timeout waiting for start signal high pulse." ));
171
194
_lastresult = false ;
@@ -184,6 +207,7 @@ boolean DHT::read(bool force) {
184
207
cycles[i] = expectPulse (LOW);
185
208
cycles[i+1 ] = expectPulse (HIGH);
186
209
}
210
+ // Interrupts will turn back on when exiting this scope.
187
211
} // Timing critical code is now complete.
188
212
189
213
// Inspect pulses and determine which ones are 0 (high state cycle count < low
0 commit comments