diff --git a/README.md b/README.md index b58d867..d536b03 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ The default value is 69; keep in mind that the measurement time is changed accor The datasheet for the BH1750 chip can be obtained [here](http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf) -## Installation +## Installation [![arduino-library-badge](https://www.ardu-badge.com/badge/BH1750.svg?)](https://www.ardu-badge.com/BH1750) Click "Clone or download" -> "Download ZIP" button. @@ -156,4 +156,8 @@ Light: 333.0 lx Light: 335.0 lx Light: 332.0 lx ``` -There are more examples in the examples directory. + +## More Examples + +The ``examples`` directory contains more advanced use cases such as using different modes, I2C addresses and multiple Wire instances. + diff --git a/examples/BH1750two_i2c/BH1750two_i2c.ino b/examples/BH1750two_i2c/BH1750two_i2c.ino new file mode 100644 index 0000000..e336ca5 --- /dev/null +++ b/examples/BH1750two_i2c/BH1750two_i2c.ino @@ -0,0 +1,71 @@ +/* + + Example of BH1750 library usage. + + This example initialises two BH1750 objects using different TwoWire + instances (Wire and Wire1) and then makes a light level reading every second. + This is the case for boards such as the ESP8266 and ESP32 + + Connection: + + BH1750 A: + VCC -> 3V3 or 5V + GND -> GND + SCL -> SCL (19 in this example) + SDA -> SDA (18 in this example) + ADD -> (not connected) or GND + + BH1750 B: + VCC -> 3V3 or 5V + GND -> GND + SCL -> SCL (22 in this example) + SDA -> SDA (21 in this example) + 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 "BH1750.h" +#include "Wire.h" + +BH1750 bh1750_a; +BH1750 bh1750_b; + +void setup() { + Serial.begin(115200); + Wire.begin(18, 19); + Wire1.begin(21, 22); + bh1750_a.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire); + bh1750_b.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire1); +} + +int error_counter_1_a = 0; +int error_counter_2_a = 0; +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(); + + if (lround(light_level_a) == -1) { + error_counter_1_a++; + } + if (lround(light_level_a) == -2) { + error_counter_2_a++; + } + if (lround(light_level_b) == -1) { + error_counter_1_b++; + } + if (lround(light_level_b) == -2) { + error_counter_2_b++; + } + Serial.printf("A: %.0f lux %d:%d :: B: %.0f lux %d:%d\n", light_level_a, + error_counter_1_a, error_counter_2_a, light_level_b, + error_counter_1_b, error_counter_2_b); + delay(1000); +} diff --git a/library.json b/library.json index aba1d2e..01bc18a 100644 --- a/library.json +++ b/library.json @@ -1,11 +1,12 @@ { "name": "BH1750", - "keywords": "light, sensor", - "description": "Digital light sensor breakout boards containing the BH1750FVI IC", + "keywords": "BH1750FVI, light, lux, sensor, Arduino, ESP8266, ESP32", + "description": "Arduino library for the digital light sensor breakout boards containing the BH1750FVI IC. Arduino, ESP8266 & ESP32 compatible.", "repository": { "type": "git", "url": "https://github.com/claws/BH1750.git" }, "frameworks": "arduino", - "platforms": ["atmelavr", "atmelsam", "espressif8266"] + "platforms": ["atmelavr", "atmelsam", "espressif8266", "espressif32"], + "version": "1.1.4" } diff --git a/library.properties b/library.properties index abf5a97..76ff54c 100644 --- a/library.properties +++ b/library.properties @@ -2,9 +2,9 @@ name=BH1750 version=1.1.4 author=Christopher Laws maintainer=Christopher Laws -sentence=Digital light sensor breakout boards containing the BH1750FVI IC -paragraph=Pretty simple and robust BH1750 library +sentence=Arduino library for the digital light sensor breakout boards containing the BH1750FVI IC +paragraph=Pretty simple and robust BH1750 library. Arduino, ESP8266 & ESP32 compatible. category=Sensors url=https://github.com/claws/BH1750 -architectures=* +architectures=avr,sam,esp8266,esp32 includes=BH1750.h diff --git a/BH1750.cpp b/src/BH1750.cpp similarity index 87% rename from BH1750.cpp rename to src/BH1750.cpp index 3184a29..eedbe1d 100644 --- a/BH1750.cpp +++ b/src/BH1750.cpp @@ -30,17 +30,17 @@ // Legacy Wire.write() function fix #if (ARDUINO >= 100) - #define __wire_write(d) Wire.write(d) + #define __wire_write(d) I2C->write(d) #else - #define __wire_write(d) Wire.send(d) + #define __wire_write(d) I2C->send(d) #endif // Legacy Wire.read() function fix #if (ARDUINO >= 100) - #define __wire_read() Wire.read() + #define __wire_read() I2C->read() #else - #define __wire_read() Wire.receive() + #define __wire_read() I2C->receive() #endif @@ -53,17 +53,27 @@ BH1750::BH1750(byte addr) { BH1750_I2CADDR = addr; - + // Allows user to change TwoWire instance + I2C = &Wire; } /** * Configure sensor * @param mode Measurement mode + * @param addr Address of the sensor + * @param i2c TwoWire instance connected to I2C bus */ -bool BH1750::begin(Mode mode) { +bool BH1750::begin(Mode mode, byte addr, TwoWire *i2c) { // I2C is expected to be initialized outside this library + // But, allows a different address and TwoWire instance to be used + if(i2c) { + I2C = i2c; + } + if(addr) { + BH1750_I2CADDR = addr; + } //return to a known value setMTreg(BH1750_DEFAULT_MTREG); @@ -93,9 +103,9 @@ bool BH1750::configure(Mode mode) { case BH1750::ONE_TIME_LOW_RES_MODE: // Send mode to sensor - Wire.beginTransmission(BH1750_I2CADDR); - __wire_write((uint8_t)BH1750_MODE); - ack = Wire.endTransmission(); + I2C->beginTransmission(BH1750_I2CADDR); + __wire_write((uint8_t)mode); + ack = I2C->endTransmission(); // Wait a few moments to wake up _delay_ms(10); @@ -151,15 +161,15 @@ bool BH1750::setMTreg(byte MTreg) { // 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); + I2C->beginTransmission(BH1750_I2CADDR); __wire_write((0b01000 << 3) | (MTreg >> 5)); - ack = Wire.endTransmission(); - Wire.beginTransmission(BH1750_I2CADDR); + ack = I2C->endTransmission(); + I2C->beginTransmission(BH1750_I2CADDR); __wire_write((0b011 << 5 ) | (MTreg & 0b11111)); - ack = ack | Wire.endTransmission(); - Wire.beginTransmission(BH1750_I2CADDR); + ack = ack | I2C->endTransmission(); + I2C->beginTransmission(BH1750_I2CADDR); __wire_write(BH1750_MODE); - ack = ack | Wire.endTransmission(); + ack = ack | I2C->endTransmission(); // Wait a few moments to wake up _delay_ms(10); @@ -219,6 +229,11 @@ 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 @@ -252,7 +267,7 @@ float BH1750::readLightLevel(bool maxWait) { // Read two bytes from the sensor, which are low and high parts of the sensor // value - if (2 == Wire.requestFrom((int)BH1750_I2CADDR, (int)2)) { + if (2 == I2C->requestFrom((int)BH1750_I2CADDR, (int)2)) { unsigned int tmp = 0; tmp = __wire_read(); tmp <<= 8; diff --git a/BH1750.h b/src/BH1750.h similarity index 74% rename from BH1750.h rename to src/BH1750.h index f32412f..b788769 100644 --- a/BH1750.h +++ b/src/BH1750.h @@ -29,7 +29,7 @@ // No active state #define BH1750_POWER_DOWN 0x00 -// Wating for measurement command +// Waiting for measurement command #define BH1750_POWER_ON 0x01 // Reset data register value - not accepted in POWER_DOWN mode @@ -45,22 +45,23 @@ class BH1750 { enum Mode { UNCONFIGURED = 0, - // Measurement at 1lx resolution. Measurement time is approx 120ms. + // Measurement at 1 lux resolution. Measurement time is approx 120ms. CONTINUOUS_HIGH_RES_MODE = 0x10, - // Measurement at 0.5lx resolution. Measurement time is approx 120ms. + // Measurement at 0.5 lux resolution. Measurement time is approx 120ms. CONTINUOUS_HIGH_RES_MODE_2 = 0x11, - // Measurement at 4lx resolution. Measurement time is approx 16ms. + // Measurement at 4 lux resolution. Measurement time is approx 16ms. CONTINUOUS_LOW_RES_MODE = 0x13, - // Measurement at 1lx resolution. Measurement time is approx 120ms. + // Measurement at 1 lux resolution. Measurement time is approx 120ms. ONE_TIME_HIGH_RES_MODE = 0x20, - // Measurement at 0.5lx resolution. Measurement time is approx 120ms. + // Measurement at 0.5 lux resolution. Measurement time is approx 120ms. ONE_TIME_HIGH_RES_MODE_2 = 0x21, - // Measurement at 1lx resolution. Measurement time is approx 120ms. + // Measurement at 4 lux resolution. Measurement time is approx 16ms. ONE_TIME_LOW_RES_MODE = 0x23 }; BH1750(byte addr = 0x23); - bool begin(Mode mode = CONTINUOUS_HIGH_RES_MODE); + bool begin(Mode mode = CONTINUOUS_HIGH_RES_MODE, byte addr = 0x23, + TwoWire* i2c = nullptr); bool configure(Mode mode); bool setMTreg(byte MTreg); float readLightLevel(bool maxWait = false); @@ -73,7 +74,7 @@ class BH1750 { // for more information. const float BH1750_CONV_FACTOR = 1.2; Mode BH1750_MODE = UNCONFIGURED; - + TwoWire* I2C; }; #endif