mirror of
https://github.com/claws/BH1750.git
synced 2026-07-27 19:56:17 +00:00
@@ -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 [](https://www.ardu-badge.com/BH1750)
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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++;
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ begin KEYWORD2
|
||||
configure KEYWORD2
|
||||
setMTreg KEYWORD2
|
||||
readLightLevel KEYWORD2
|
||||
|
||||
measurementReady KEYWORD2
|
||||
#######################################
|
||||
# Instances (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
+47
-56
@@ -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;
|
||||
|
||||
+4
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user