BH1750. Ambient light sensor with I2C bus.

BH1750. Ambient light sensor with I2C bus.

BH1750. Ambient light sensor with I2C bus.

The BH1750 is an ambient lighting sensor with reasonably high resolution and sensitivity. It behaves in the face of visible light in a way comparable to that of the human eye and is not affected by infrared radiation nor does it depend on the color temperature of the type of lighting, that is, it works well with natural light and with different types of artificial lighting. It communicates digitally with the microcontroller, with the I2C bus, so it is resistant to interference if it is placed at a certain distance from the circuit that reads it. Its response time is quite low, less than 200 ms in the most unfavorable circumstances.

Table of Contents

    BH1750 Ambient light sensor

    From the electronic point of view, its implementation is very simple. Simply connect the power (between 2,4V and 3,6V) and the I2C bus. Optionally, the bus address can be changed to connect two devices (with ADDR at a low level it is 0B0100011 or 0x23 and with ADDR at a high level it is 0B1011100 or 0x5C) and the VDI line can be used for the reset function with the microcontroller.

    To connect the BH1750 to Arduino, in addition to being powered by the 3,3 V output, it is most correct to use a level converter in addition to the pull-up resistors for I2C bus. Although the component will support a direct connection to the bus I2C bus It is not advisable to size a circuit without considering converting the level.

    BH1750 ambient lighting sensor. Application circuit

    Due to its popularity, which is due to being very cheap in relation to its precision, there are several modules, such as the well-known GY-30, which can be seen in the photograph at the beginning. To connect them more comfortably when prototyping with a microcontroller, they usually include level converters for the I2C bus and voltage regulators to power them with a higher voltage (up to 5V) instead of the 3,3V output of Arduino.

    The BH1750 has two reading modes, continuous and individual, which correspond to two states, active and low power or sleep. While if the continuous reading mode is used, the BH1750 remains active after sampling, after performing an individual measurement it automatically enters the sleep and low power mode. The first reading in continuous mode takes a maximum of 180 ms and subsequent ones between 16 ms and 120 ms depending on the resolution.

    The sensor is capable of measuring at intervals (resolution) of 4 lux, 1 lux and 0,5 lux. The BH1750 recommends in its data sheet to use the resolution of 1 lux, which allows you to distinguish illuminations below 10 lux (which corresponds to twilight) and which is more immune to noise that could affect the measurement.

    The resolutions of 1 lux and 4 lux use the 16 bits of data to represent the integer part so a maximum measurement of 65535 lux can be achieved (sunny day without direct light). The 0,5 lux mode uses the least significant bit for the decimal part (measures from 0,5 lux to 0,5 lux) so with the remaining 15 bits it is possible to represent a maximum value of 32767 lux (exterior without direct light)

    Theoretical solar illumination versus the average capacity of the BH1750
    Theoretical solar illumination of the place and day of writing the article (legal time, not solar) versus the average capacity of the BH1750 at 1 lux

    Normally, the optical window according to which ambient light is measured corresponds to the entire visible spectrum and the aim is to achieve a sensitivity distribution in it comparable to that of humans. If the optical window is reduced (light is measured in a lower wavelength range) the sensitivity of the BH1750 can be increased (up to 0,11 lux) with a mode of cancellation of the adjustment of the influence of the optical window by increasing the time reading in proportion. Since in this special (oversized) mode separate readings are taken, the context must allow this without particularly altering the measurement conditions (for example, the sensor must remain very stable, it must not move to an area with different lighting conditions)

    BH1750 Operation Codes

    STATUS
    5>

    • 0B00000000 (0x00) Low power or idle mode.

    • 0B00000001 (0x01) Switched on.

    • 0B00000111 (0x07) Reset. Clears the BH1750 data logs.

    Decision
    5>

    • 0B00010011 (0x13) Continuous measurement at 4 lux resolution (between 16 ms and reading time)

    • 0B00010000 (0x10) Continuous measurement at 1 lux resolution (120 ms reading time)

    • 0B00010001 (0x11) Continuous measurement at 0,5 lux resolution (120 ms reading time)

    • 0B00100011 (0x23) A measurement at 4 lux resolution (16 ms reading time)

    • 0B00100000 (0x20) A measurement at 1 lux resolution (120 ms reading time)

    • 0B00100001 (0x21) A measurement at 0,5 lux resolution (120 ms reading time)

    Adjustment for change in optical window
    5>

    • 0B011MT [0,1,2,3,4] Low bit of the MTREG (Measurement Time REGister) register.

    • 0B01000MT [5,6,7] MTREG register high bit.

    Read the BH1750 from Arduino

    To measure ambient lighting with the BH1750 from Arduino the library is used Wire that manages communications with the I2C bus. The process is the usual one in this type of communications, first they are activated (once in the program) with Wire.begin(), communication with the BH1750 starts with Wire.beginTransmission() and your address I2C (0x5C or 0x23 depending on whether ADDR is high or low respectively), it is configured by sending the corresponding code with Wire.write() and the bus is released with Wire.endTransmission()

    If one of the continuous reading modes is used, Wire.beginTransmission() is used to get the data with the address I2C corresponding to access the BH1750, you are prompted for two bytes (resolution is 16 bits) with Wire.requestFrom() that are read, using Wire.read(), and are loaded into an unsigned integer, rotating the first byte by 8 bits. The bus is subsequently released with Wire.endTransmission(). The final result is obtained by dividing the returned value by the precision factor (1,2 if the optical window is not changed)

    If the individual readings mode is used, the BH1750 enters sleep mode. To return to active mode, a configuration (the same reading mode or a new one) or the power-on code (0x01) can be sent. The shutdown code (1750x0) can be used to force the BH00 into sleep mode.

    It is important to respect the sensor reading time, which depends on the resolution. If the wait is not critical, it can be unified into a value for all cases that can be slightly larger than the expected maximum to ensure that the read completes.

    To make writing code for the BH1750 more comfortable in Arduino, the most relevant operation codes are found in the following header document.

    The following example code shows the most common reading mode in the light sensor I2C BH1750. The resolution is 1 lux and the reading mode is continuous. The example shows, using the serial console Arduino, each result obtained from the measured value.

    As I said above, both the 1 lux and 4 lux resolution modes use the 16 bits of data to express the measurement as an integer. On the other hand, in the 0,5 lux mode, the last bit represents a decimal part, that is, the value that contributes to the total measurement is shifted by a power of two to the right. In 1 lux or 4 lux mode the last bit (LSB) is worth 20, the penultimate 21, the next 22…in 0,5 lux mode the last bit (LSB) is worth 2-1, the penultimate 20, the next 21...

    According to this data structure, and considering that two readings must be performed I2C of a byte, to obtain the 16-bit value you have to load the most significant bits of the byte, the first ones to be read, and rotate them 8 bits to the left in 1 lux resolution mode and in 4 lux resolution mode and only 7 bits in the 0,5 lux. To unify the way of reading in the 0,5 lux mode you can load the most significant byte into an unsigned integer, rotate 8 bits to the left, load the least significant byte and rotate the entire unsigned integer 1 bit to the left. right, preserving the value of the decimal part that indicates the LSB (least significant bit) to apply it later.

    Logically, for 1 lux or 4 lux modes it is necessary to use unsigned integers (unsigned int) what for Arduino do not reserve the MSB (most significant bit) for the sign and be able to operate directly with the true value of the measurement, not with a negative number. In Arduino Due not necessary since integers use 32 bits, but the same program will also work if used as well unsigned int.

    The following code shows how the 0,5 lux mode would be used

    Download the documents for the examples of measuring ambient light with the BH1750 sensor and Arduino.

    Post Comment

    You May Have Missed