diff --git a/DHT.cpp b/DHT.cpp index c1e687d..79f6a40 100644 --- a/DHT.cpp +++ b/DHT.cpp @@ -143,47 +143,46 @@ boolean DHT::read(void) { digitalWrite(_pin, LOW); delay(20); - // Turn off interrupts temporarily because the next sections are timing critical - // and we don't want any interruptions. - noInterrupts(); - - // End the start signal by setting data line high for 40 microseconds. - digitalWrite(_pin, HIGH); - delayMicroseconds(40); - - // Now start reading the data line to get the value from the DHT sensor. - pinMode(_pin, INPUT); - delayMicroseconds(10); // Delay a bit to let sensor pull data line low. - - // First expect a low signal for ~80 microseconds followed by a high signal - // for ~80 microseconds again. - if (expectPulse(LOW) == 0) { - DEBUG_PRINTLN(F("Timeout waiting for start signal low pulse.")); - _lastresult = false; - return _lastresult; - } - if (expectPulse(HIGH) == 0) { - DEBUG_PRINTLN(F("Timeout waiting for start signal high pulse.")); - _lastresult = false; - return _lastresult; - } - - // Now read the 40 bits sent by the sensor. Each bit is sent as a 50 - // microsecond low pulse followed by a variable length high pulse. If the - // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds - // then it's a 1. We measure the cycle count of the initial 50us low pulse - // and use that to compare to the cycle count of the high pulse to determine - // if the bit is a 0 (high state cycle count < low state cycle count), or a - // 1 (high state cycle count > low state cycle count). Note that for speed all - // the pulses are read into a array and then examined in a later step. uint32_t cycles[80]; - for (int i=0; i<80; i+=2) { - cycles[i] = expectPulse(LOW); - cycles[i+1] = expectPulse(HIGH); - } + { + // Turn off interrupts temporarily because the next sections are timing critical + // and we don't want any interruptions. + InterruptLock lock; - // Re-enable interrupts, timing critical code is complete. - interrupts(); + // End the start signal by setting data line high for 40 microseconds. + digitalWrite(_pin, HIGH); + delayMicroseconds(40); + + // Now start reading the data line to get the value from the DHT sensor. + pinMode(_pin, INPUT); + delayMicroseconds(10); // Delay a bit to let sensor pull data line low. + + // First expect a low signal for ~80 microseconds followed by a high signal + // for ~80 microseconds again. + if (expectPulse(LOW) == 0) { + DEBUG_PRINTLN(F("Timeout waiting for start signal low pulse.")); + _lastresult = false; + return _lastresult; + } + if (expectPulse(HIGH) == 0) { + DEBUG_PRINTLN(F("Timeout waiting for start signal high pulse.")); + _lastresult = false; + return _lastresult; + } + + // Now read the 40 bits sent by the sensor. Each bit is sent as a 50 + // microsecond low pulse followed by a variable length high pulse. If the + // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds + // then it's a 1. We measure the cycle count of the initial 50us low pulse + // and use that to compare to the cycle count of the high pulse to determine + // if the bit is a 0 (high state cycle count < low state cycle count), or a + // 1 (high state cycle count > low state cycle count). Note that for speed all + // the pulses are read into a array and then examined in a later step. + for (int i=0; i<80; i+=2) { + cycles[i] = expectPulse(LOW); + cycles[i+1] = expectPulse(HIGH); + } + } // Timing critical code is now complete. // Inspect pulses and determine which ones are 0 (high state cycle count < low // state cycle count), or 1 (high state cycle count > low state cycle count). diff --git a/DHT.h b/DHT.h index 37fae0f..dd4d1f5 100644 --- a/DHT.h +++ b/DHT.h @@ -57,4 +57,15 @@ class DHT { }; +class InterruptLock { + public: + InterruptLock() { + noInterrupts(); + } + ~InterruptLock() { + interrupts(); + } + +}; + #endif