claws / BH1750

An Arduino library for the digital light sensor breakout boards containing the BH1750FVI IC
MIT License
252 stars 108 forks source link

clarification on executing next OneTime measurment and getting delay time #88

Open nekitoss opened 1 year ago

nekitoss commented 1 year ago

Because at some point was removed this fix for auto-start one-time measurement (maybe because it sarted at reading moment) And because it is not clear from README.md (but still present in example), that you need to start one-time measurement again by calling lightMeter.configure(BH1750::ONE_TIME_HIGH_RES_MODE); (and not just use readLightLevel() )

I suggest clarifiyng that in README.md:35

When the One-Time mode is used your sensor will go into Power Down mode when it completes the measurement and you've read it. 
You will need to run `configure()` each time you want to start measuring before you read the results.

and in example BH1750onetime.ino

  Serial.println(" lx");
  //run new one-time measurement
  lightMeter.configure(BH1750::ONE_TIME_HIGH_RES_MODE);
}

Also because my battery-powered device sleeps between the start and end of measurement - I cannot rely on measurementReady() function, because millis() are "paused" during sleep, if I remember correctly.

So I suggest adding a function, that gives you back delay time, and reusing that function in the beginning of measurementReady() function. Here is quick sketch (sorry, if any bad function names or mistakes - i do not program on C++):

/**
 * Calculates time needed for measurement
 * @param maxWait a boolean if to wait for typical or maximum delay
 * @return a number of milliseconds to wait
 */
unsigned long BH1750::getMeasurementTime(bool maxWait) {
  switch (BH1750_MODE) {
    case BH1750::CONTINUOUS_HIGH_RES_MODE:
    case BH1750::CONTINUOUS_HIGH_RES_MODE_2:
    case BH1750::ONE_TIME_HIGH_RES_MODE:
    case BH1750::ONE_TIME_HIGH_RES_MODE_2:
      return maxWait ? delaytime = (180 * BH1750_MTreg / (byte)BH1750_DEFAULT_MTREG)
              : delaytime = (120 * BH1750_MTreg / (byte)BH1750_DEFAULT_MTREG);
    case BH1750::CONTINUOUS_LOW_RES_MODE:
    case BH1750::ONE_TIME_LOW_RES_MODE:
      return maxWait ? delaytime = (24 * BH1750_MTreg / (byte)BH1750_DEFAULT_MTREG)
              : delaytime = (16 * BH1750_MTreg / (byte)BH1750_DEFAULT_MTREG);
    default:
      return 180;
  }
}

/**
 * Checks whether enough time has gone to read a new value
 * @param maxWait a boolean if to wait for typical or maximum delay
 * @return a boolean if a new measurement is possible
 */
bool BH1750::measurementReady(bool maxWait) {
  // Wait for new measurement to be possible.
  // Measurements have a maximum measurement time and a typical measurement
  // time. The maxWait argument determines which measurement wait time is
  // used when a one-time mode is being used. The typical (shorter)
  // measurement time is used by default and if maxWait is set to True then
  // the maximum measurement time will be used. See data sheet pages 2, 5
  // and 7 for more details.
  unsigned long currentTimestamp = millis();
  if (currentTimestamp - lastReadTimestamp >= getMeasurementTime(maxWait)) {
    return true;
  } else
    return false;
}

I can make a PR if these changes are acceptable (or you can do it by yourself, if it is more comfortable).

nekitoss commented 1 year ago

Another idea is to create startOneTimeMeasure(), which will just start measure using already set (with validation) ONE_TIME mode, and, unlike conigure(), it won't be waiting 10ms to sensor receive command (if i understood corretly that delay in case someone tries to do something just right after), which will allow non-blocking flow

coelner commented 1 year ago

I think this library will not get any further attention, maybe you should consider to fork and patch.

The sleep in general is not the problem, but most of the arduino devices doesn't restore their RAM. therefore the library needs to get initialized after every wakepup. However, the instance of this library stores the last value and no, there is no getter for this currently: https://github.com/claws/BH1750/blob/b6986b553faed246ee267801ca23ccaea038d7cc/src/BH1750.h#L81

this here: https://github.com/claws/BH1750/blob/b6986b553faed246ee267801ca23ccaea038d7cc/src/BH1750.cpp#L102 is because of the behavior of this chip, AFAIK it needs this time by itself. This value seems to work for most of the users, but feel free to look here: https://github.com/Starmbi/hp_BH1750/wiki/

As far as I remember you should be able to trigger a OneTime command, got to sleep the right amount of time and read then the sensor. The sensor itself stores the last measurement in the register until a new measurement is completed. (Need confirmation). A get function for the wait delay could be useful, but is unlikely to happen. On a battery driven design, you could sleep long enough to be sure that this chip is ready to deliver a new value (e.g. 500ms). If you want both, like maximum battery saving AND fastest refresh rate on hard timings, then this library is not useful.