From 2a8adf0c316343912e4a482011d6b7d98ef5daad Mon Sep 17 00:00:00 2001 From: coelner Date: Fri, 14 Aug 2020 18:01:33 +0200 Subject: [PATCH] upstream related #61 , #59 , #53 --- README.md | 3 +- examples/BH1750advanced/BH1750advanced.ino | 12 +- .../BH1750autoadjust/BH1750autoadjust.ino | 66 +++++------ examples/BH1750onetime/BH1750onetime.ino | 6 +- examples/BH1750two_i2c/BH1750two_i2c.ino | 6 +- keywords.txt | 2 +- src/BH1750.cpp | 103 ++++++++---------- src/BH1750.h | 5 +- 8 files changed, 102 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index d536b03..876004e 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,8 @@ This is needed if you use an overlay windows or compensate environmental influen This time frame is defined by a register which is called MTreg. Therefore you could choose a value between 32 and 254. The default value is 69; keep in mind that the measurement time is changed accordingly. -The datasheet for the BH1750 chip can be obtained [here](http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf) +The datasheet for the BH1750 chip can be obtained +[here](https://www.mouser.de/datasheet/2/348/Rohm_11162017_ROHMS34826-1-1279292.pdf)[2011.11 Rev.D] ## Installation [![arduino-library-badge](https://www.ardu-badge.com/badge/BH1750.svg?)](https://www.ardu-badge.com/BH1750) diff --git a/examples/BH1750advanced/BH1750advanced.ino b/examples/BH1750advanced/BH1750advanced.ino index 0d9851e..d03f051 100644 --- a/examples/BH1750advanced/BH1750advanced.ino +++ b/examples/BH1750advanced/BH1750advanced.ino @@ -85,11 +85,11 @@ void setup(){ void loop() { - - float lux = lightMeter.readLightLevel(); - Serial.print("Light: "); - Serial.print(lux); - Serial.println(" lx"); - delay(1000); + if (lightMeter.measurementReady()) { + float lux = lightMeter.readLightLevel(); + Serial.print("Light: "); + Serial.print(lux); + Serial.println(" lx"); + } } diff --git a/examples/BH1750autoadjust/BH1750autoadjust.ino b/examples/BH1750autoadjust/BH1750autoadjust.ino index d256f7c..8ac7e71 100644 --- a/examples/BH1750autoadjust/BH1750autoadjust.ino +++ b/examples/BH1750autoadjust/BH1750autoadjust.ino @@ -49,48 +49,50 @@ void setup(){ void loop() { //we use here the maxWait option due fail save - float lux = lightMeter.readLightLevel(true); - Serial.print(F("Light: ")); - Serial.print(lux); - Serial.println(F(" lx")); + if (lightMeter.measurementReady(true)) { + float lux = lightMeter.readLightLevel(); + Serial.print(F("Light: ")); + Serial.print(lux); + Serial.println(F(" lx")); - if (lux < 0) { - Serial.println(F("Error condition detected")); - } - else { - if (lux > 40000.0) { - // reduce measurement time - needed in direct sun light - if (lightMeter.setMTreg(32)) { - Serial.println(F("Setting MTReg to low value for high light environment")); - } - else { - Serial.println(F("Error setting MTReg to low value for high light environment")); - } + if (lux < 0) { + Serial.println(F("Error condition detected")); } else { - if (lux > 10.0) { - // typical light environment - if (lightMeter.setMTreg(69)) { - Serial.println(F("Setting MTReg to default value for normal light environment")); - } - else { - Serial.println(F("Error setting MTReg to default value for normal light environment")); - } + if (lux > 40000.0) { + // reduce measurement time - needed in direct sun light + if (lightMeter.setMTreg(32)) { + Serial.println(F("Setting MTReg to low value for high light environment")); } else { - if (lux <= 10.0) { - //very low light environment - if (lightMeter.setMTreg(138)) { - Serial.println(F("Setting MTReg to high value for low light environment")); + Serial.println(F("Error setting MTReg to low value for high light environment")); + } + } + else { + if (lux > 10.0) { + // typical light environment + if (lightMeter.setMTreg(69)) { + Serial.println(F("Setting MTReg to default value for normal light environment")); } else { - Serial.println(F("Error setting MTReg to high value for low light environment")); + Serial.println(F("Error setting MTReg to default value for normal light environment")); } } - } - } + else { + if (lux <= 10.0) { + //very low light environment + if (lightMeter.setMTreg(138)) { + Serial.println(F("Setting MTReg to high value for low light environment")); + } + else { + Serial.println(F("Error setting MTReg to high value for low light environment")); + } + } + } + } + } + Serial.println(F("--------------------------------------")); } - Serial.println(F("--------------------------------------")); delay(5000); } diff --git a/examples/BH1750onetime/BH1750onetime.ino b/examples/BH1750onetime/BH1750onetime.ino index 2988a85..c22ff9a 100644 --- a/examples/BH1750onetime/BH1750onetime.ino +++ b/examples/BH1750onetime/BH1750onetime.ino @@ -33,10 +33,12 @@ void setup(){ void loop() { + while (!lightMeter.measurementReady(true)) { + yield(); + } float lux = lightMeter.readLightLevel(); Serial.print("Light: "); Serial.print(lux); Serial.println(" lx"); - delay(1000); - + lightMeter.configure(BH1750::ONE_TIME_HIGH_RES_MODE); } diff --git a/examples/BH1750two_i2c/BH1750two_i2c.ino b/examples/BH1750two_i2c/BH1750two_i2c.ino index e336ca5..49bcd8e 100644 --- a/examples/BH1750two_i2c/BH1750two_i2c.ino +++ b/examples/BH1750two_i2c/BH1750two_i2c.ino @@ -49,8 +49,10 @@ int error_counter_1_b = 0; int error_counter_2_b = 0; void loop() { - const float light_level_a = bh1750_a.readLightLevel(); - const float light_level_b = bh1750_b.readLightLevel(); + float light_level_a; + if (bh1750_a.measurementReady()) { light_level_a = bh1750_a.readLightLevel(); } + float light_level_b; + if (bh1750_b.measurementReady()) { light_level_b = bh1750_b.readLightLevel(); } if (lround(light_level_a) == -1) { error_counter_1_a++; diff --git a/keywords.txt b/keywords.txt index fa9a921..b7c12da 100644 --- a/keywords.txt +++ b/keywords.txt @@ -16,7 +16,7 @@ begin KEYWORD2 configure KEYWORD2 setMTreg KEYWORD2 readLightLevel KEYWORD2 - +measurementReady KEYWORD2 ####################################### # Instances (KEYWORD2) ####################################### diff --git a/src/BH1750.cpp b/src/BH1750.cpp index 6c5f044..f7916e6 100644 --- a/src/BH1750.cpp +++ b/src/BH1750.cpp @@ -77,7 +77,6 @@ bool BH1750::begin(Mode mode, byte addr, TwoWire *i2c) { // Configure sensor in specified mode and set default MTreg return (configure(mode) && setMTreg(BH1750_DEFAULT_MTREG)); - } @@ -120,6 +119,7 @@ bool BH1750::configure(Mode mode) { switch (ack) { case 0: BH1750_MODE = mode; + lastReadTimestamp = millis(); return true; case 1: // too long for transmit buffer Serial.println(F("[BH1750] ERROR: too long for transmit buffer")); @@ -176,18 +176,6 @@ bool BH1750::setMTreg(byte MTreg) { switch (ack) { case 0: BH1750_MTreg = MTreg; - // Delay for specific continuous mode to get valid values - switch (BH1750_MODE) { - case BH1750::CONTINUOUS_LOW_RES_MODE: - _delay_ms(24 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG); - break; - case BH1750::CONTINUOUS_HIGH_RES_MODE: - case BH1750::CONTINUOUS_HIGH_RES_MODE_2: - _delay_ms(180 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG); - break; - default: - break; - } return true; case 1: // too long for transmit buffer Serial.println(F("[BH1750] ERROR: too long for transmit buffer")); @@ -209,6 +197,44 @@ bool BH1750::setMTreg(byte MTreg) { return false; } +/** + * 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) { + unsigned long delaytime = 0; + 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: + maxWait ? delaytime = (180 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG) : delaytime = (120 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG); + break; + case BH1750::CONTINUOUS_LOW_RES_MODE: + case BH1750::ONE_TIME_LOW_RES_MODE: + // Send mode to sensor + maxWait ? delaytime = (24 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG) : delaytime = (16 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG); + break; + default: + break; + } + // 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 >= delaytime) { + return true; + } + else + return false; +} + /** * Read light level from sensor * The return value range differs if the MTreg value is changed. The global @@ -217,7 +243,7 @@ bool BH1750::setMTreg(byte MTreg) { * -1 : no valid return value * -2 : sensor not configured */ -float BH1750::readLightLevel(bool maxWait) { +float BH1750::readLightLevel() { if (BH1750_MODE == UNCONFIGURED) { Serial.println(F("[BH1750] Device is not configured!")); @@ -227,42 +253,6 @@ float BH1750::readLightLevel(bool maxWait) { // Measurement result will be stored here float level = -1.0; - // Send mode to sensor - I2C->beginTransmission(BH1750_I2CADDR); - __wire_write((uint8_t)BH1750_MODE); - I2C->endTransmission(); - - // Wait for measurement to be taken. - // 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. - // A continuous mode measurement can be read immediately after re-sending - // the mode command. - - switch (BH1750_MODE) { - - case BH1750::ONE_TIME_LOW_RES_MODE: - // Send mode to sensor - Wire.beginTransmission(BH1750_I2CADDR); - __wire_write((uint8_t)BH1750_MODE); - Wire.endTransmission(); - maxWait ? _delay_ms(24 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG) : _delay_ms(16 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG); - break; - case BH1750::ONE_TIME_HIGH_RES_MODE: - case BH1750::ONE_TIME_HIGH_RES_MODE_2: - // Send mode to sensor - Wire.beginTransmission(BH1750_I2CADDR); - __wire_write((uint8_t)BH1750_MODE); - Wire.endTransmission(); - maxWait ? _delay_ms(180 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG) :_delay_ms(120 * BH1750_MTreg/(byte)BH1750_DEFAULT_MTREG); - break; - default: - break; - } - // Read two bytes from the sensor, which are low and high parts of the sensor // value if (2 == I2C->requestFrom((int)BH1750_I2CADDR, (int)2)) { @@ -272,6 +262,7 @@ float BH1750::readLightLevel(bool maxWait) { tmp |= __wire_read(); level = tmp; } + lastReadTimestamp = millis(); if (level != -1.0) { // Print raw value if debug enabled @@ -281,12 +272,12 @@ float BH1750::readLightLevel(bool maxWait) { #endif if (BH1750_MTreg != BH1750_DEFAULT_MTREG) { - level *= (float)((byte)BH1750_DEFAULT_MTREG/(float)BH1750_MTreg); - // Print MTreg factor if debug enabled - #ifdef BH1750_DEBUG - Serial.print(F("[BH1750] MTreg factor: ")); - Serial.println( String((float)((byte)BH1750_DEFAULT_MTREG/(float)BH1750_MTreg)) ); - #endif + level *= (float)((byte)BH1750_DEFAULT_MTREG/(float)BH1750_MTreg); + // Print MTreg factor if debug enabled + #ifdef BH1750_DEBUG + Serial.print(F("[BH1750] MTreg factor: ")); + Serial.println( String((float)((byte)BH1750_DEFAULT_MTREG/(float)BH1750_MTreg)) ); + #endif } if (BH1750_MODE == BH1750::ONE_TIME_HIGH_RES_MODE_2 || BH1750_MODE == BH1750::CONTINUOUS_HIGH_RES_MODE_2) { level /= 2; diff --git a/src/BH1750.h b/src/BH1750.h index b788769..dd4575c 100644 --- a/src/BH1750.h +++ b/src/BH1750.h @@ -44,6 +44,7 @@ class BH1750 { enum Mode { + // same as Power Down UNCONFIGURED = 0, // Measurement at 1 lux resolution. Measurement time is approx 120ms. CONTINUOUS_HIGH_RES_MODE = 0x10, @@ -64,7 +65,8 @@ class BH1750 { TwoWire* i2c = nullptr); bool configure(Mode mode); bool setMTreg(byte MTreg); - float readLightLevel(bool maxWait = false); + bool measurementReady(bool maxWait = false); + float readLightLevel(); private: byte BH1750_I2CADDR; @@ -75,6 +77,7 @@ class BH1750 { const float BH1750_CONV_FACTOR = 1.2; Mode BH1750_MODE = UNCONFIGURED; TwoWire* I2C; + unsigned long lastReadTimestamp; }; #endif