mirror of
https://github.com/claws/BH1750.git
synced 2026-07-27 19:56:17 +00:00
Executable → Regular
+106
-28
@@ -132,20 +132,88 @@ bool BH1750::configure(Mode mode) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure BH1750 MTreg value
|
||||
* MT reg = Measurement Time register
|
||||
* @param MTreg a value between 32 and 254. Default: 69
|
||||
* @return bool true if MTReg successful set
|
||||
* false if MTreg not changed or parameter out of range
|
||||
*/
|
||||
bool BH1750::setMTreg(byte MTreg) {
|
||||
//Bug: lowest value seems to be 32!
|
||||
if (MTreg <= 31 || MTreg > 254) {
|
||||
Serial.println(F("[BH1750] ERROR: MTreg out of range"));
|
||||
return false;
|
||||
}
|
||||
byte ack = 5;
|
||||
// Send MTreg and the current mode to the sensor
|
||||
// High bit: 01000_MT[7,6,5]
|
||||
// Low bit: 011_MT[4,3,2,1,0]
|
||||
Wire.beginTransmission(BH1750_I2CADDR);
|
||||
__wire_write((0b01000 << 3) | (MTreg >> 5));
|
||||
ack = Wire.endTransmission();
|
||||
Wire.beginTransmission(BH1750_I2CADDR);
|
||||
__wire_write((0b011 << 5 ) | (MTreg & 0b111));
|
||||
ack = ack | Wire.endTransmission();
|
||||
Wire.beginTransmission(BH1750_I2CADDR);
|
||||
__wire_write(BH1750_MODE);
|
||||
ack = ack | Wire.endTransmission();
|
||||
|
||||
// Wait a few moments to wake up
|
||||
_delay_ms(10);
|
||||
|
||||
// Check result code
|
||||
switch (ack) {
|
||||
case 0:
|
||||
BH1750_MTreg = MTreg;
|
||||
//Delay for specific continious 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"));
|
||||
break;
|
||||
case 2: // received NACK on transmit of address
|
||||
Serial.println(F("[BH1750] ERROR: received NACK on transmit of address"));
|
||||
break;
|
||||
case 3: // received NACK on transmit of data
|
||||
Serial.println(F("[BH1750] ERROR: received NACK on transmit of data"));
|
||||
break;
|
||||
case 4: // other error
|
||||
Serial.println(F("[BH1750] ERROR: other error"));
|
||||
break;
|
||||
default:
|
||||
Serial.println(F("[BH1750] ERROR: undefined error"));
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read light level from sensor
|
||||
* @return Light level in lux (0 ~ 65535)
|
||||
* The return value differs if the MTreg value is changed. The global maximum value is noted in the square brackets
|
||||
* @return Light level in lux (0.0 ~ 54612,5 [117758,203])
|
||||
* -1 : no valid return value
|
||||
* -2 : sensor not configured
|
||||
*/
|
||||
uint16_t BH1750::readLightLevel(bool maxWait) {
|
||||
float BH1750::readLightLevel(bool maxWait) {
|
||||
|
||||
if (BH1750_MODE == UNCONFIGURED) {
|
||||
Serial.println(F("[BH1750] Device is not configured!"));
|
||||
return 0;
|
||||
return -2.0;
|
||||
}
|
||||
|
||||
// Measurement result will be stored here
|
||||
uint16_t level=65535;
|
||||
float level = -1.0;
|
||||
|
||||
// Send mode to sensor
|
||||
Wire.beginTransmission(BH1750_I2CADDR);
|
||||
@@ -165,42 +233,52 @@ uint16_t BH1750::readLightLevel(bool maxWait) {
|
||||
switch (BH1750_MODE) {
|
||||
|
||||
case BH1750::ONE_TIME_LOW_RES_MODE:
|
||||
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:
|
||||
|
||||
if (BH1750_MODE == BH1750::ONE_TIME_LOW_RES_MODE) {
|
||||
maxWait ? _delay_ms(24) : _delay_ms(16);
|
||||
}
|
||||
else {
|
||||
maxWait ? _delay_ms(180) :_delay_ms(120);
|
||||
}
|
||||
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
|
||||
Wire.requestFrom(BH1750_I2CADDR, 2);
|
||||
if (Wire.available() == 2) {
|
||||
level = __wire_read();
|
||||
level <<= 8;
|
||||
level |= __wire_read();
|
||||
if (2 == Wire.requestFrom((int)BH1750_I2CADDR, (int)2)) {
|
||||
unsigned int tmp = 0;
|
||||
tmp = __wire_read();
|
||||
tmp <<= 8;
|
||||
tmp |= __wire_read();
|
||||
level = tmp;
|
||||
}
|
||||
|
||||
// Print raw value if debug enabled
|
||||
#ifdef BH1750_DEBUG
|
||||
Serial.print(F("[BH1750] Raw value: "));
|
||||
Serial.println(level);
|
||||
#endif
|
||||
if (level != -1.0) {
|
||||
// Print raw value if debug enabled
|
||||
#ifdef BH1750_DEBUG
|
||||
Serial.print(F("[BH1750] Raw value: "));
|
||||
Serial.println(level);
|
||||
#endif
|
||||
|
||||
// Convert raw value to lux
|
||||
level /= 1.2;
|
||||
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
|
||||
}
|
||||
if (BH1750_MODE == BH1750::ONE_TIME_HIGH_RES_MODE_2 || BH1750_MODE == BH1750::CONTINUOUS_HIGH_RES_MODE_2) {
|
||||
level /= 2;
|
||||
}
|
||||
// Convert raw value to lux
|
||||
level /= BH1750_CONV_FACTOR;
|
||||
|
||||
// Print converted value if debug enabled
|
||||
#ifdef BH1750_DEBUG
|
||||
Serial.print(F("[BH1750] Converted value: "));
|
||||
Serial.println(level);
|
||||
#endif
|
||||
// Print converted value if debug enabled
|
||||
#ifdef BH1750_DEBUG
|
||||
Serial.print(F("[BH1750] Converted float value: "));
|
||||
Serial.println(level);
|
||||
#endif
|
||||
}
|
||||
|
||||
return level;
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
// Reset data register value - not accepted in POWER_DOWN mode
|
||||
#define BH1750_RESET 0x07
|
||||
|
||||
// Default MTreg value
|
||||
#define BH1750_DEFAULT_MTREG 69
|
||||
|
||||
class BH1750 {
|
||||
|
||||
public:
|
||||
@@ -60,10 +63,15 @@ class BH1750 {
|
||||
BH1750(byte addr = 0x23);
|
||||
bool begin(Mode mode = CONTINUOUS_HIGH_RES_MODE);
|
||||
bool configure(Mode mode);
|
||||
uint16_t readLightLevel(bool maxWait = false);
|
||||
bool setMTreg(byte MTreg);
|
||||
float readLightLevel(bool maxWait = false);
|
||||
|
||||
private:
|
||||
int BH1750_I2CADDR;
|
||||
byte BH1750_I2CADDR;
|
||||
byte BH1750_MTreg = (byte)BH1750_DEFAULT_MTREG;
|
||||
// Correction factor used to calculate lux. Typical value is 1.2 but can range from 0.96 to 1.44.
|
||||
// See data sheet (p.2, Measurement Accuracy) for more information.
|
||||
const float BH1750_CONV_FACTOR = 1.2;
|
||||
Mode BH1750_MODE = UNCONFIGURED;
|
||||
|
||||
};
|
||||
|
||||
@@ -39,6 +39,23 @@ back into One-Time mode. This library has been implemented to automatically
|
||||
reconfigure the sensor when you next attempt a measurement so you should not
|
||||
have to worry about such low level details.
|
||||
|
||||
Usually you will get an integer value which represent the lux equivalent.
|
||||
- Low Resolution Mode - (generic range: 0.0 up to 54612.5 lux)
|
||||
- High Resolution Mode - (generic range: 0.0 up to 54612.5 lux)
|
||||
- High Resolution Mode 2 - (generic range: 0.0 up to 27306.25 lux)
|
||||
|
||||
The sensor itself returns a 16 bit unsigned integer. Therefore the maximum value is limited in general.
|
||||
The standard conversion between the so called 'counts' to lux is 1/1.2, that means you get a smaller value.
|
||||
As we use float, if an error occurs you will get a negative value.
|
||||
- -1 no valid data was transmitted from the sensor
|
||||
- -2 device is not configured
|
||||
Otherwise the measured counts are converted to lux and returned. If no advanced parameters are changed the maximum lux value is 54612.5 lx.
|
||||
|
||||
As the sensor counts impact of light in a specific time frame you could change this time frame.
|
||||
This is needed if you use an overlay windows or compensate environmental influence like darkness.
|
||||
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)
|
||||
|
||||
|
||||
@@ -117,7 +134,7 @@ void setup(){
|
||||
|
||||
void loop() {
|
||||
|
||||
uint16_t lux = lightMeter.readLightLevel();
|
||||
float lux = lightMeter.readLightLevel();
|
||||
Serial.print("Light: ");
|
||||
Serial.print(lux);
|
||||
Serial.println(" lx");
|
||||
@@ -131,12 +148,12 @@ void loop() {
|
||||
Moving the sensor to face more light results in the lux measurements increasing.
|
||||
```
|
||||
BH1750 Test
|
||||
Light: 70 lx
|
||||
Light: 70 lx
|
||||
Light: 59 lx
|
||||
Light: 328 lx
|
||||
Light: 333 lx
|
||||
Light: 335 lx
|
||||
Light: 332 lx
|
||||
Light: 70.0 lx
|
||||
Light: 70.0 lx
|
||||
Light: 59.0 lx
|
||||
Light: 328.0 lx
|
||||
Light: 333.0 lx
|
||||
Light: 335.0 lx
|
||||
Light: 332.0 lx
|
||||
```
|
||||
There are more examples in the examples directory.
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <BH1750.h>
|
||||
|
||||
/*
|
||||
|
||||
BH1750 can be physically configured to use two I2C addresses:
|
||||
- 0x23 (most common) (if ADD pin had < 0.7VCC voltage)
|
||||
- 0x5C (if ADD pin had > 0.7VCC voltage)
|
||||
@@ -87,7 +86,7 @@ void setup(){
|
||||
|
||||
void loop() {
|
||||
|
||||
uint16_t lux = lightMeter.readLightLevel();
|
||||
float lux = lightMeter.readLightLevel();
|
||||
Serial.print("Light: ");
|
||||
Serial.print(lux);
|
||||
Serial.println(" lx");
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
|
||||
Example of BH1750 library usage.
|
||||
|
||||
This example initialises the BH1750 object using the default high resolution
|
||||
one shot mode and then makes a light level reading every five second.
|
||||
After the measurement the MTreg value is changed according to the result:
|
||||
lux > 40000 ==> MTreg = 32
|
||||
lux < 40000 ==> MTreg = 69 (default)
|
||||
lux < 10 ==> MTreg = 138
|
||||
Remember to test your specific sensor! Maybe the MTreg value range from 32 up to 254 is not applicable to your unit.
|
||||
|
||||
Connection:
|
||||
|
||||
VCC -> 3V3 or 5V
|
||||
GND -> GND
|
||||
SCL -> SCL (A5 on Arduino Uno, Leonardo, etc or 21 on Mega and Due, on esp8266 free selectable)
|
||||
SDA -> SDA (A4 on Arduino Uno, Leonardo, etc or 20 on Mega and Due, on esp8266 free selectable)
|
||||
ADD -> (not connected) or GND
|
||||
|
||||
ADD pin is used to set sensor I2C address. If it has voltage greater or equal to
|
||||
0.7VCC voltage (e.g. you've connected it to VCC) the sensor address will be
|
||||
0x5C. In other case (if ADD voltage less than 0.7 * VCC) the sensor address will
|
||||
be 0x23 (by default).
|
||||
|
||||
*/
|
||||
|
||||
#include <Wire.h>
|
||||
#include <BH1750.h>
|
||||
|
||||
BH1750 lightMeter;
|
||||
|
||||
void setup(){
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
// Initialize the I2C bus (BH1750 library doesn't do this automatically)
|
||||
Wire.begin();
|
||||
// On esp8266 you can select SCL and SDA pins using Wire.begin(D4, D3);
|
||||
|
||||
lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE);
|
||||
//lightMeter.setMTreg(69); //not needed, only mentioning it
|
||||
|
||||
Serial.println(F("BH1750 Test begin"));
|
||||
|
||||
}
|
||||
|
||||
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 (lux < 0) {
|
||||
Serial.println(F("[DEBUG]: 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 default value for normal 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 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("--------------------------------------"));
|
||||
delay(5000);
|
||||
}
|
||||
@@ -33,7 +33,7 @@ void setup(){
|
||||
|
||||
void loop() {
|
||||
|
||||
uint16_t lux = lightMeter.readLightLevel();
|
||||
float lux = lightMeter.readLightLevel();
|
||||
Serial.print("Light: ");
|
||||
Serial.print(lux);
|
||||
Serial.println(" lx");
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <Wire.h>
|
||||
#include <BH1750.h>
|
||||
|
||||
@@ -43,7 +44,7 @@ void setup(){
|
||||
|
||||
void loop() {
|
||||
|
||||
uint16_t lux = lightMeter.readLightLevel();
|
||||
float lux = lightMeter.readLightLevel();
|
||||
Serial.print("Light: ");
|
||||
Serial.print(lux);
|
||||
Serial.println(" lx");
|
||||
|
||||
+2
-1
@@ -14,9 +14,9 @@ BH1750 KEYWORD1
|
||||
|
||||
begin KEYWORD2
|
||||
configure KEYWORD2
|
||||
setMTreg KEYWORD2
|
||||
readLightLevel KEYWORD2
|
||||
|
||||
|
||||
#######################################
|
||||
# Instances (KEYWORD2)
|
||||
#######################################
|
||||
@@ -31,3 +31,4 @@ BH1750_CONTINUOUS_LOW_RES_MODE LITERAL1
|
||||
BH1750_ONE_TIME_HIGH_RES_MODE LITERAL1
|
||||
BH1750_ONE_TIME_HIGH_RES_MODE_2 LITERAL1
|
||||
BH1750_ONE_TIME_LOW_RES_MODE LITERAL1
|
||||
BH1750_DEFAULT_MTREG LITERAL1
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
name=BH1750
|
||||
version=1.1.3
|
||||
version=1.1.4
|
||||
author=Christopher Laws
|
||||
maintainer=Christopher Laws
|
||||
sentence=Digital light sensor breakout boards containing the BH1750FVI IC
|
||||
|
||||
Reference in New Issue
Block a user