olewolf / DHT_nonblocking

Non-blocking Arduino library for the DHT11, DHT21, and DHT22 sensors
GNU General Public License v3.0
37 stars 28 forks source link

Fails when delay() is used anywhere in code #6

Open grandehombre opened 4 years ago

grandehombre commented 4 years ago

Hi Ole, Thanks for creating the library and sharing it with us!

I have encountered a strange issue, whereby if I use delay() in my code, the library never returns true in dht_sensor.measure().

Any ideas?

Cheers, Nick

[Update 18 nov 2019] It appears the error comes about if delay() is used in every iteration of loop(). If I put a conditional so it is only used some of the time, all is well. e.g.

**int loop_ctr** is defined in global scope

void loop() {
  // do stuff
 // ..
if (++loop_ctr % 10 == 0) {
   // blink LEDs and use delay()
}
void loop( ) {
  float temperature;
  float humidity;

  /* Measure temperature and humidity.  If the functions returns
     true, then a measurement is available. */
  if ( measure_environment( &temperature, &humidity ) == true )
  {
    Serial.print( "T = " );
    Serial.print( temperature, 1 );
    Serial.print( " deg. C, H = " );
    Serial.print( humidity, 1 );
    Serial.println( "%" );
  }

// the delay() calls below stop it from working
  for (int i = 0; i < 2; i++) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(300);
    digitalWrite(LED_BUILTIN, LOW);
    delay(300);
  }
}

/*
   Poll for a measurement, keeping the state machine alive.  Returns true if a measurement is available.
**** WARNING!!!!  Using delay() in the code causes the DHT-nonblocking lib to always report the the sensor is not ready for reading!!!!
*/
static bool measure_environment(float *temperature, float *humidity) {
  bool ok = false;
  if ( millis( ) - measurement_timestamp > 3000ul )   {
// this never seems to return true, due to the delay() calls in loop()
    if ( dht_sensor.measure( temperature, humidity ) == true )     {
      measurement_timestamp = millis( );
      ok = true;
    }
  }
  return ok;
}
olewolf commented 4 years ago

The library relies on being called repeatedly so a delay() will indeed cause the non-blocking read to fail. In fact, any operation that takes a long time to execute is likely to cause the non-blocking read to fail.

If you need the best of two worlds--a non-blocking read and the use of delay()--you'd have to either use an operating system or rewrite the non-blocking read so it relies on timer interrupts.

grandehombre commented 4 years ago

Thank you very much for replying Ole! In the end, I found that if I use millis() to detect a gap of, say 4 seconds, and then blink the lights using delay(), it all works. This method gives the library time to do its work and only holds it up every x seconds. This is in line with what you just said, so all should be fine.

Thanks again,

Cheers, Nick