diff --git a/BH1750/LICENSE b/BH1750/LICENSE
new file mode 100644
index 0000000..604d838
--- /dev/null
+++ b/BH1750/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 claws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/BH1750/README.md b/BH1750/README.md
new file mode 100644
index 0000000..8d6e0b6
--- /dev/null
+++ b/BH1750/README.md
@@ -0,0 +1,165 @@
+# BH1750
+
+[![Build Status](https://travis-ci.org/claws/BH1750.svg?branch=master)](https://travis-ci.org/claws/BH1750)
+
+This package contains an Arduino library for digital light sensor breakout boards containing the
+BH1750FVI IC.
+
+The BH1750 board uses I2C for communication which requires two pins to
+communicate with the device. Configuring the I2C bus must be done in user code
+(not library code). This approach has been adopted so it can be done once and
+will better support the various options for different platforms.
+
+A common module containing the BH1750 component is the GY-30 shown below.
+
+![GY-30 Module image](resources/gy30-module.jpg)
+
+
+## Overview
+
+The BH1750 has six different measurement modes which are divided in two groups;
+continuous and one-time measurements. In continuous mode the sensor
+continuously measures lightness value. In one-time mode, the sensor makes only
+one measurement and then goes into Power Down mode.
+
+Each mode has three different precisions:
+
+ - Low Resolution Mode - (4 lx precision, 16ms measurement time)
+ - High Resolution Mode - (1 lx precision, 120ms measurement time)
+ - High Resolution Mode 2 - (0.5 lx precision, 120ms measurement time)
+
+By default, this library uses Continuous High Resolution Mode, but you can
+change this to a different mode by passing the mode argument to
+BH1750.begin().
+
+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. When the sensor is powered up
+again it returns to the default mode which means it needs to be reconfigured
+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 window or compensate for 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](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)
+
+- **(For Arduino >= 1.5.x)** Install this package by searching for it in the
+ Arduino Library Manager and then clicking ``install``. Alternatively, this
+ library can be installed manually by clicking "Clone or download" -> "Download ZIP"
+ button. Then open Arduino IDE, click `Sketch -> Include library -> Add .ZIP library`
+ and select the downloaded archive.
+
+- **(For Arduino < 1.5.x)** Download this package as an archive by clicking
+ "Clone or download" -> "Download ZIP" button. Then extract the archive to
+ ``/My Documents/Arduino/libraries/`` folder and rename
+ it to `BH1750`. Restart IDE.
+
+The following YouTube [video](https://youtu.be/ACTMQvPVMLs) (specifically from
+7:20 onwards) provides a good overview of manually installing this library and
+loading an example using the Arduino IDE.
+
+[![BH1750 Video Tutorial](https://img.youtube.com/vi/ACTMQvPVMLs/0.jpg)](https://youtu.be/ACTMQvPVMLs?t=437)
+
+Information about the library installation process - https://www.arduino.cc/en/Guide/Libraries
+
+
+## Example
+
+An example using the BH1750 library in conjunction with the GY-30 board
+(which contains the BH1750 component) is presented below. The example
+code uses the BH1750 library in the default continuous high precision
+mode when making light measurements.
+
+### Wiring
+
+Connections:
+
+ - VCC -> 3V3 or 5V
+ - GND -> GND
+ - SCL -> SCL (A5 on Arduino Nano, Uno, Leonardo, etc or 21 on Mega and Due, on esp8266 free selectable)
+ - SDA -> SDA (A4 on Arduino Nano, Uno, Leonardo, etc or 20 on Mega and Due, on esp8266 free selectable)
+ - ADD -> NC/GND or VCC (see below)
+
+The ADD pin is used to set the sensor I2C address. By default (if ADD voltage
+less than 0.7 * VCC) the sensor address will be 0x23. 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.
+
+Wiring up the GY-30 sensor board to an Arduino is shown in the diagram below.
+
+![Example wiring diagram image](resources/wiring-diagram-gy30-module.png)
+
+*The image above was created using [Fritzing](http://fritzing.org/home/) and
+the GY-30 module was obtained from [here](http://omnigatherum.ca/wp/?p=6)*.
+
+### Code
+
+Upload the BH1750 test code to your Arduino.
+
+``` c++
+#include
+#include
+
+BH1750 lightMeter;
+
+void setup(){
+
+ Serial.begin(9600);
+
+ // Initialize the I2C bus (BH1750 library doesn't do this automatically)
+ // On esp8266 devices you can select SCL and SDA pins using Wire.begin(D4, D3);
+ Wire.begin();
+
+ lightMeter.begin();
+ Serial.println(F("BH1750 Test"));
+
+}
+
+void loop() {
+
+ float lux = lightMeter.readLightLevel();
+ Serial.print("Light: ");
+ Serial.print(lux);
+ Serial.println(" lx");
+ delay(1000);
+
+}
+```
+
+### Output
+
+Moving the sensor to face more light results in the lux measurements increasing.
+```
+BH1750 Test
+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
+```
+
+## More Examples
+
+The ``examples`` directory contains more advanced use cases such as using different modes, I2C addresses and multiple Wire instances.
+
diff --git a/BH1750/build-examples.bash b/BH1750/build-examples.bash
new file mode 100644
index 0000000..c2916bc
--- /dev/null
+++ b/BH1750/build-examples.bash
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+#
+# A simple script to automate building BH1750 examples.
+#
+# Example (MacOSX):
+# $ ARDUINO_IDE_PATH=/Applications/Arduino.app/Contents/Java ./build-examples.bash
+#
+
+# Path to script directory.
+SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
+LIBNAME="$(basename "$SCRIPTPATH")"
+
+if [[ -z "${ARDUINO_IDE_PATH}" ]]; then
+ echo "ARDUINO_IDE_PATH env var is not set"
+ exit 1
+fi
+
+# Link BH1750 library into Arduino libraries directory
+ln -s $SCRIPTPATH $ARDUINO_IDE_PATH/libraries/
+
+cd $ARDUINO_IDE_PATH
+
+for sketch in `find $SCRIPTPATH/examples -name '*.ino'`
+do
+ echo "Compiling $sketch"
+ ./arduino-builder -hardware ./hardware -tools ./hardware/tools/avr -tools ./tools-builder -libraries ./libraries -fqbn arduino:avr:uno --prefs "compiler.warning_level=all" $sketch
+ # ./arduino-builder -hardware ./hardware -tools ./hardware/tools/avr -tools ./tools-builder -libraries ./libraries -fqbn esp8266:esp8266:generic --prefs "compiler.warning_level=all" $sketch
+ if [ $? -ne 0 ]; then
+ echo -e "\xe2\x9c\x96" # check icon
+ else
+ echo -e "\xe2\x9c\x93" # tick icon
+ fi
+done
+
+# Unlink BH1750 library from Arduino libraries directory
+unlink $ARDUINO_IDE_PATH/libraries/$LIBNAME
diff --git a/BH1750/component.mk b/BH1750/component.mk
new file mode 100644
index 0000000..27ad11a
--- /dev/null
+++ b/BH1750/component.mk
@@ -0,0 +1 @@
+COMPONENT_ADD_INCLUDEDIRS := .
diff --git a/BH1750/examples/BH1750advanced/BH1750advanced.ino b/BH1750/examples/BH1750advanced/BH1750advanced.ino
new file mode 100644
index 0000000..d03f051
--- /dev/null
+++ b/BH1750/examples/BH1750advanced/BH1750advanced.ino
@@ -0,0 +1,95 @@
+/*
+
+ Advanced BH1750 library usage example
+
+ This example has some comments about advanced usage features.
+
+ 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
+#include
+
+/*
+ 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)
+
+ Library uses 0x23 address as default, but you can define any other address.
+ If you had troubles with default value - try to change it to 0x5C.
+
+*/
+BH1750 lightMeter(0x23);
+
+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);
+
+ /*
+
+ BH1750 has six different measurement modes. They are divided in two groups;
+ continuous and one-time measurements. In continuous mode, sensor continuously
+ measures lightness value. In one-time mode the sensor makes only one
+ measurement and then goes into Power Down mode.
+
+ Each mode, has three different precisions:
+
+ - Low Resolution Mode - (4 lx precision, 16ms measurement time)
+ - High Resolution Mode - (1 lx precision, 120ms measurement time)
+ - High Resolution Mode 2 - (0.5 lx precision, 120ms measurement time)
+
+ By default, the library uses Continuous High Resolution Mode, but you can
+ set any other mode, by passing it to BH1750.begin() or BH1750.configure()
+ functions.
+
+ [!] Remember, if you use One-Time mode, your sensor will go to Power Down
+ mode each time, when it completes a measurement and you've read it.
+
+ Full mode list:
+
+ BH1750_CONTINUOUS_LOW_RES_MODE
+ BH1750_CONTINUOUS_HIGH_RES_MODE (default)
+ BH1750_CONTINUOUS_HIGH_RES_MODE_2
+
+ BH1750_ONE_TIME_LOW_RES_MODE
+ BH1750_ONE_TIME_HIGH_RES_MODE
+ BH1750_ONE_TIME_HIGH_RES_MODE_2
+
+ */
+
+ // begin returns a boolean that can be used to detect setup problems.
+ if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
+ Serial.println(F("BH1750 Advanced begin"));
+ }
+ else {
+ Serial.println(F("Error initialising BH1750"));
+ }
+
+}
+
+
+void loop() {
+ if (lightMeter.measurementReady()) {
+ float lux = lightMeter.readLightLevel();
+ Serial.print("Light: ");
+ Serial.print(lux);
+ Serial.println(" lx");
+ }
+
+}
diff --git a/BH1750/examples/BH1750autoadjust/BH1750autoadjust.ino b/BH1750/examples/BH1750autoadjust/BH1750autoadjust.ino
new file mode 100644
index 0000000..8ac7e71
--- /dev/null
+++ b/BH1750/examples/BH1750autoadjust/BH1750autoadjust.ino
@@ -0,0 +1,98 @@
+/*
+
+ 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 seconds.
+
+ 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
+#include
+
+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
+ 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"));
+ }
+ }
+ 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);
+}
diff --git a/BH1750/examples/BH1750onetime/BH1750onetime.ino b/BH1750/examples/BH1750onetime/BH1750onetime.ino
new file mode 100644
index 0000000..c22ff9a
--- /dev/null
+++ b/BH1750/examples/BH1750onetime/BH1750onetime.ino
@@ -0,0 +1,44 @@
+/*
+
+ Example of BH1750 library usage.
+
+ This example initialises the BH1750 object using the high resolution
+ one-time mode and then makes a light level reading every second.
+
+ The BH1750 component starts up in default mode when it next powers up.
+ The BH1750 library automatically reconfigures the one-time mode in
+ preparation for the next measurement.
+
+*/
+
+#include
+#include
+
+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);
+
+ Serial.println(F("BH1750 One-Time Test"));
+
+}
+
+
+void loop() {
+
+ while (!lightMeter.measurementReady(true)) {
+ yield();
+ }
+ float lux = lightMeter.readLightLevel();
+ Serial.print("Light: ");
+ Serial.print(lux);
+ Serial.println(" lx");
+ lightMeter.configure(BH1750::ONE_TIME_HIGH_RES_MODE);
+}
diff --git a/BH1750/examples/BH1750test/BH1750test.ino b/BH1750/examples/BH1750test/BH1750test.ino
new file mode 100644
index 0000000..4ca5c10
--- /dev/null
+++ b/BH1750/examples/BH1750test/BH1750test.ino
@@ -0,0 +1,54 @@
+/*
+
+ Example of BH1750 library usage.
+
+ This example initialises the BH1750 object using the default high resolution
+ continuous mode and then makes a light level reading every second.
+
+ 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
+#include
+
+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);
+ // For Wemos / Lolin D1 Mini Pro and the Ambient Light shield use Wire.begin(D2, D1);
+
+ lightMeter.begin();
+
+ Serial.println(F("BH1750 Test begin"));
+
+}
+
+
+void loop() {
+
+ float lux = lightMeter.readLightLevel();
+ Serial.print("Light: ");
+ Serial.print(lux);
+ Serial.println(" lx");
+ delay(1000);
+
+}
diff --git a/BH1750/examples/BH1750two_i2c/BH1750two_i2c.ino b/BH1750/examples/BH1750two_i2c/BH1750two_i2c.ino
new file mode 100644
index 0000000..49bcd8e
--- /dev/null
+++ b/BH1750/examples/BH1750two_i2c/BH1750two_i2c.ino
@@ -0,0 +1,73 @@
+/*
+
+ 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() {
+ 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++;
+ }
+ 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/BH1750/keywords.txt b/BH1750/keywords.txt
new file mode 100644
index 0000000..b7c12da
--- /dev/null
+++ b/BH1750/keywords.txt
@@ -0,0 +1,34 @@
+#######################################
+# Syntax Coloring Map For BH1750
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+BH1750 KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+begin KEYWORD2
+configure KEYWORD2
+setMTreg KEYWORD2
+readLightLevel KEYWORD2
+measurementReady KEYWORD2
+#######################################
+# Instances (KEYWORD2)
+#######################################
+
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+BH1750_CONTINUOUS_HIGH_RES_MODE LITERAL1
+BH1750_CONTINUOUS_HIGH_RES_MODE_2 LITERAL1
+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
diff --git a/BH1750/library.json b/BH1750/library.json
new file mode 100644
index 0000000..d575750
--- /dev/null
+++ b/BH1750/library.json
@@ -0,0 +1,12 @@
+{
+ "name": "BH1750",
+ "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", "espressif32", "stm32"],
+ "version": "1.2.0"
+}
diff --git a/BH1750/library.properties b/BH1750/library.properties
new file mode 100644
index 0000000..142a0d4
--- /dev/null
+++ b/BH1750/library.properties
@@ -0,0 +1,10 @@
+name=BH1750
+version=1.2.0
+author=Christopher Laws
+maintainer=Christopher Laws
+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=avr,sam,esp8266,esp32,stm32
+includes=BH1750.h
diff --git a/BH1750/resources/gy30-module.jpg b/BH1750/resources/gy30-module.jpg
new file mode 100644
index 0000000..15cf099
Binary files /dev/null and b/BH1750/resources/gy30-module.jpg differ
diff --git a/BH1750/resources/wiring-diagram-gy30-module.png b/BH1750/resources/wiring-diagram-gy30-module.png
new file mode 100644
index 0000000..f8efe5c
Binary files /dev/null and b/BH1750/resources/wiring-diagram-gy30-module.png differ
diff --git a/BH1750/src/BH1750.cpp b/BH1750/src/BH1750.cpp
new file mode 100644
index 0000000..f7916e6
--- /dev/null
+++ b/BH1750/src/BH1750.cpp
@@ -0,0 +1,297 @@
+/*
+
+ This is a library for the BH1750FVI Digital Light Sensor breakout board.
+
+ The BH1750 board uses I2C for communication. Two pins are required to
+ interface to the device. Configuring the I2C bus is expected to be done
+ in user code. The BH1750 library doesn't do this automatically.
+
+ Written by Christopher Laws, March, 2013.
+
+*/
+
+#include "BH1750.h"
+
+// Define milliseconds delay for ESP8266 platform
+#if defined(ESP8266)
+
+ #include
+ #define _delay_ms(ms) delayMicroseconds((ms) * 1000)
+
+// Use _delay_ms from utils for AVR-based platforms
+#elif defined(__avr__)
+ #include
+
+// Use Wiring's delay for compability with another platforms
+#else
+ #define _delay_ms(ms) delay(ms)
+#endif
+
+
+// Legacy Wire.write() function fix
+#if (ARDUINO >= 100)
+ #define __wire_write(d) I2C->write(d)
+#else
+ #define __wire_write(d) I2C->send(d)
+#endif
+
+
+// Legacy Wire.read() function fix
+#if (ARDUINO >= 100)
+ #define __wire_read() I2C->read()
+#else
+ #define __wire_read() I2C->receive()
+#endif
+
+
+/**
+ * Constructor
+ * @params addr Sensor address (0x76 or 0x72, see datasheet)
+ *
+ * On most sensor boards, it was 0x76
+ */
+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, 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;
+ }
+
+ // Configure sensor in specified mode and set default MTreg
+ return (configure(mode) && setMTreg(BH1750_DEFAULT_MTREG));
+}
+
+
+/**
+ * Configure BH1750 with specified mode
+ * @param mode Measurement mode
+ */
+bool BH1750::configure(Mode mode) {
+
+ // default transmission result to a value out of normal range
+ byte ack = 5;
+
+ // Check measurement mode is valid
+ switch (mode) {
+
+ case BH1750::CONTINUOUS_HIGH_RES_MODE:
+ case BH1750::CONTINUOUS_HIGH_RES_MODE_2:
+ case BH1750::CONTINUOUS_LOW_RES_MODE:
+ case BH1750::ONE_TIME_HIGH_RES_MODE:
+ case BH1750::ONE_TIME_HIGH_RES_MODE_2:
+ case BH1750::ONE_TIME_LOW_RES_MODE:
+
+ // Send mode to sensor
+ I2C->beginTransmission(BH1750_I2CADDR);
+ __wire_write((uint8_t)mode);
+ ack = I2C->endTransmission();
+
+ // Wait a few moments to wake up
+ _delay_ms(10);
+ break;
+
+ default:
+ // Invalid measurement mode
+ Serial.println(F("[BH1750] ERROR: Invalid mode"));
+ break;
+
+ }
+
+ // Check result code
+ 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"));
+ 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;
+
+}
+
+/**
+ * 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]
+ I2C->beginTransmission(BH1750_I2CADDR);
+ __wire_write((0b01000 << 3) | (MTreg >> 5));
+ ack = I2C->endTransmission();
+ I2C->beginTransmission(BH1750_I2CADDR);
+ __wire_write((0b011 << 5 ) | (MTreg & 0b11111));
+ ack = ack | I2C->endTransmission();
+ I2C->beginTransmission(BH1750_I2CADDR);
+ __wire_write(BH1750_MODE);
+ ack = ack | I2C->endTransmission();
+
+ // Wait a few moments to wake up
+ _delay_ms(10);
+
+ // Check result code
+ switch (ack) {
+ case 0:
+ BH1750_MTreg = MTreg;
+ 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;
+}
+
+/**
+ * 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
+ * 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
+ */
+float BH1750::readLightLevel() {
+
+ if (BH1750_MODE == UNCONFIGURED) {
+ Serial.println(F("[BH1750] Device is not configured!"));
+ return -2.0;
+ }
+
+ // Measurement result will be stored here
+ float level = -1.0;
+
+ // 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)) {
+ unsigned int tmp = 0;
+ tmp = __wire_read();
+ tmp <<= 8;
+ tmp |= __wire_read();
+ level = tmp;
+ }
+ lastReadTimestamp = millis();
+
+ if (level != -1.0) {
+ // Print raw value if debug enabled
+ #ifdef BH1750_DEBUG
+ Serial.print(F("[BH1750] Raw value: "));
+ Serial.println(level);
+ #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
+ }
+ 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 float value: "));
+ Serial.println(level);
+ #endif
+ }
+
+ return level;
+
+}
diff --git a/BH1750/src/BH1750.h b/BH1750/src/BH1750.h
new file mode 100644
index 0000000..dd4575c
--- /dev/null
+++ b/BH1750/src/BH1750.h
@@ -0,0 +1,83 @@
+/*
+
+ This is a library for the BH1750FVI Digital Light Sensor breakout board.
+
+ The BH1750 board uses I2C for communication. Two pins are required to
+ interface to the device. Configuring the I2C bus is expected to be done
+ in user code. The BH1750 library doesn't do this automatically.
+
+ Datasheet: http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf
+
+ Written by Christopher Laws, March, 2013.
+
+*/
+
+#ifndef BH1750_h
+#define BH1750_h
+
+#if (ARDUINO >= 100)
+ #include
+#else
+ #include
+#endif
+
+#include "Wire.h"
+
+// Uncomment, to enable debug messages
+// #define BH1750_DEBUG
+
+// No active state
+#define BH1750_POWER_DOWN 0x00
+
+// Waiting for measurement command
+#define BH1750_POWER_ON 0x01
+
+// 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:
+
+ enum Mode
+ {
+ // same as Power Down
+ UNCONFIGURED = 0,
+ // Measurement at 1 lux resolution. Measurement time is approx 120ms.
+ CONTINUOUS_HIGH_RES_MODE = 0x10,
+ // Measurement at 0.5 lux resolution. Measurement time is approx 120ms.
+ CONTINUOUS_HIGH_RES_MODE_2 = 0x11,
+ // Measurement at 4 lux resolution. Measurement time is approx 16ms.
+ CONTINUOUS_LOW_RES_MODE = 0x13,
+ // Measurement at 1 lux resolution. Measurement time is approx 120ms.
+ ONE_TIME_HIGH_RES_MODE = 0x20,
+ // Measurement at 0.5 lux resolution. Measurement time is approx 120ms.
+ ONE_TIME_HIGH_RES_MODE_2 = 0x21,
+ // 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, byte addr = 0x23,
+ TwoWire* i2c = nullptr);
+ bool configure(Mode mode);
+ bool setMTreg(byte MTreg);
+ bool measurementReady(bool maxWait = false);
+ float readLightLevel();
+
+ private:
+ 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 the data sheet (p.2, Measurement Accuracy)
+ // for more information.
+ const float BH1750_CONV_FACTOR = 1.2;
+ Mode BH1750_MODE = UNCONFIGURED;
+ TwoWire* I2C;
+ unsigned long lastReadTimestamp;
+};
+
+#endif