RobTillaart / DHTNew

Arduino library for DHT11 and DHT22 with automatic sensor recognition
MIT License
98 stars 15 forks source link

calculateReadDelay() #40

Closed budulinek closed 3 years ago

budulinek commented 3 years ago

OK, I have one more thing in the pipeline. I really like the idea of calculating _readDelay based on real life reading interval (see the example dhtnew_setReadDelay.ino) . I have two DHT22, both of them have real life read interval 442 ms (instead of default 2000 ms).

So I propose this function to calculate _readDelay based on real life read interval. It is a "brute force" method, but very fast. The alternative would be:

uint16_t DHTNEW::calculateReadDelay()
{
  if (getType() == 0) return _readDelay;
  _readDelay = DHTLIB_DHT22_READ_DELAY;
  if (_type == 11) _readDelay = DHTLIB_DHT11_READ_DELAY;
  // finish previous reading (if there was some) and start new one
  while (millis() - _lastRead < _readDelay);
  _read();

  uint16_t step = _readDelay;
  while (step)
  {
    step /= 2;
    Serial.println(_readDelay);
    delay(_readDelay);
    if (_read() == DHTLIB_OK) _readDelay -= step;
    else {
      delay(_readDelay);
      _read();
      _readDelay += step;
    }
  }
  // safety margin
  _readDelay += DHTLIB_READ_DELAY_MARGIN;
  return _readDelay;
}

The alternative is based on the example sketch, it is nice, elegant and accurate, but very slow (can take up between 8 and 30 seconds).

RobTillaart commented 3 years ago

I edited your comment above to do syntax highlighting, click edit to have a look, its just adding cpp behind the backquotes. Come back to this proposal later this weekend (I hope)

Concern I have is that it might grow the codebase while it is used only once I think.

budulinek commented 3 years ago

Yes, that is fair concern.

RobTillaart commented 3 years ago

I did not investigate readDelay behavior in depth yet, and one of the questions that need to be answered is the following:

If you measure the minimum readDelay @ 25°C or @ 0°C there is a serious chance they differ. Physical processes tend to be temperature dependent, sometimes more, sometimes less.

To be sure to understand I estimate one should map the minimum readDelay for at least 10 or so devices, for the full temperature and humidity range. But fair enough if the first sensor has a constant readDelay over both its C and RH range I expect others will also be constant as there seems no temperature or humidity dependency. If it is a first degree (linear) relation RD = alpha x T + beta x RH + gamma thinks get a bit more complicated. Easy solution is to do

 readDelay = max( minimumReadDelay(for all temperature and humidity combinations));

And I assume that is just how the values 1000 and 2000 came to be.

So research is needed to prevent problems due to using a local optimum.

RobTillaart commented 3 years ago

People can use the example setReadDelay.ino and use the found value in their sketch with setReadDelay(..)

That is a solution that can be done per sensor, and per sketch without adding footprint to the library.

Seems sufficient to close this issue.