Raspberry Pi Pico: BH1750 Ambient Light Sensor (MicroPython)

Learn to use the BH1750 ambient light sensor with the Raspberry Pi Pico programmed with MicroPython to get ambient light measurements. We’ll show you how to wire the sensor, install the required libraries, and get sensor measurements in LUX unit, the standardized unit for illuminance.

Raspberry Pi Pico BH1750 Ambient Light Sensor MicroPython

New to the Raspberry Pi Pico? Read the following guide: Getting Started with Raspberry Pi Pico (and Pico W).

Table of Contents:

Throughout this tutorial, we’ll cover the following subjects:

Prerequisites

Before proceeding with this tutorial, make sure you follow the next prerequisites.

MicroPython Firmware

To follow this tutorial you need MicroPython firmware installed in your Raspberry Pi Pico board. You also need an IDE to write and upload the code to your board.

micorpython logo

The recommended MicroPython IDE for the Raspberry Pi Pico is Thonny IDE. Follow the next tutorial to learn how to install Thonny IDE, flash MicroPython firmware, and upload code to the board.

Alternatively, if you like programming using VS Code, you can start with the following tutorial:

Parts Required

To follow this tutorial, you need the following parts:

Introducing the BH1750 Ambient Light Sensor

The BH1750 is a 16-bit ambient light sensor that communicates via I2C protocol. It outputs luminosity measurements in lux (SI-derived unit of illuminance). It can measure a minimum of 1 lux and a maximum of 65535 lux.

The sensor may come in different breakout board formats. See the picture below. Both are BH1750 sensors.

BH1750 two different breakout boards

BH1750 Features

Here’s a list of the BH1750 sensor features. For more information consult the BH1750 sensor datasheet.

  • I2C bus Interface
  • Illuminance to digital converter
  • Range: 1 – 65535 lux
  • Low current by power down function
  • 50Hz / 60Hz Light noise reject-function
  • It is possible to select 2 different I2 C slave addresses
  • Small measurement variation (+/- 20%)
  • The influence of infrared is very small
  • Supports continuous measurement mode
  • Supports one-time measurement mode

Measurement Modes

The sensor supports two different measurement modes: continuous measurement mode, and one-time measurement mode. Each mode supports three different resolution modes.

Low Resolution Mode4 lux precision16 ms measurement time
High Resolution Mode1 lux precision120 ms measurement time
High Resolution Mode 20.5 lux precision120 ms measurement time

In continuous measurement mode, the sensor continuously measures ambient light values. In one-time measurement mode, the sensor measures the ambient light value once, and then it goes to power down mode.

Applications

BH1750 Ambient Light Sensor

The BH1750 is an ambient light sensor so it can be used in a wide variety of projects. For example:

  • to detect if it is day or night;
  • to adjust or turn on/off LED’s brightness accordingly to ambient light;
  • to adjust LCDs and screen’s brightness;
  • to detect if an LED is lit;
  • …

Wiring the BH1750 to the Raspberry Pi Pico

The BH1750 sensor uses I2C communication protocol to interface with microcontrollers. Take a look at its pinout in the table below.

BH1750 Ambient Light Sensor Pinout

Here’s the BH1750 Pinout, it’s the same for both breakout boards:

VCCPowers the sensor (3.3V or 5V)
GNDGND
SCLSCL pin for I2C communication
SDA/DATSDA pin for I2C communication
ADDRSelects address

The ADDR pin is used to set the I2C sensor address. If the voltage on that pin is less than 0.7VCC (pin is left floating or connected to GND), the I2C address is 0x23. But, if the voltage is higher than 0.7xVCC (pin is connected to VCC), the address is 0x5C. In summary:

  • ADDR pin floating or connected to GND → address: 0x23
  • ADDR pin connected to VCC → address: 0x5C

We’ll wire the sensor to the Raspberry Pi Pico GPIO 4 (SDA) and GPIO 5 (SCL).

BH1750Raspberry Pi Pico
VCC3V3(OUT)
GNDGND
SCLGPIO 5
SDAGPIO 4
ADDR*Don’t connect

By not connecting the ADDR pin, we’re selecting 0x23 I2C address. However, it’s always better to run an I2C scanner to be sure:

Circuit Diagram

You can use the following diagram as a reference.

Raspberry Pi Pico and Pico W BH1750 Schematic Diagram

BH1750 MicroPython Library

To read from the BH1750 sensor, we’ll use an external library that isn’t part of the standard MicroPython library by default.

Open the following link and copy the library code to Thonny IDE:

Follow the next steps to upload the library to your Pico board:

1) Copy the library code to a new file. The bh1750.py library code can be found here.


# Micropython BH1750 ambient light sensor driver: https://github.com/PinkInk/upylib/tree/master/bh1750

from utime import sleep_ms

class BH1750():
    """Micropython BH1750 ambient light sensor driver."""

    PWR_OFF = 0x00
    PWR_ON = 0x01
    RESET = 0x07

    # modes
    CONT_LOWRES = 0x13
    CONT_HIRES_1 = 0x10
    CONT_HIRES_2 = 0x11
    ONCE_HIRES_1 = 0x20
    ONCE_HIRES_2 = 0x21
    ONCE_LOWRES = 0x23

    # default addr=0x23 if addr pin floating or pulled to ground
    # addr=0x5c if addr pin pulled high
    def __init__(self, bus, addr=0x23):
        self.bus = bus
        self.addr = addr
        self.off()
        self.reset()

    def off(self):
        """Turn sensor off."""
        self.set_mode(self.PWR_OFF)

    def on(self):
        """Turn sensor on."""
        self.set_mode(self.PWR_ON)

    def reset(self):
        """Reset sensor, turn on first if required."""
        self.on()
        self.set_mode(self.RESET)

    def set_mode(self, mode):
        """Set sensor mode."""
        self.mode = mode
        self.bus.writeto(self.addr, bytes([self.mode]))

    def luminance(self, mode):
        """Sample luminance (in lux), using specified sensor mode."""
        # continuous modes
        if mode & 0x10 and mode != self.mode:
            self.set_mode(mode)
        # one shot modes
        if mode & 0x20:
            self.set_mode(mode)
        # earlier measurements return previous reading
        sleep_ms(24 if mode in (0x13, 0x23) else 180)
        data = self.bus.readfrom(self.addr, 2)
        factor = 2.0 if mode in (0x11, 0x21) else 1.0
        return (data[0]<<8 | data[1]) / (1.2 * factor)

View raw code

BH1750 micropython library thonny ide

2) Go to File > Save as…

Thonny IDE ESP32 ESP8266 MicroPython Save file library to device save as

3) Select save to “Raspberry Pi Pico“:

Save Files to Raspberry Pi Pico Thonny IDE

4) Name your file as bh1750.py and press the OK button:

saving bh1750.py to raspberry pi

And that’s it. The library was uploaded to your board. To make sure that it was uploaded successfully, go to File > Save as… and select the Raspberry Pi Pico device. Your file should be listed there:

BH1750 file saved on the Raspberry Pi Pico board

After uploading the library to your board, you can use the library functionalities in your code by importing the library.

Raspberry Pi Pico – BH1750 Luminance (Lux) – Code

After uploading the library to the Raspberry Pi Pico, create a new file and paste the following code. It reads the luminance in lux units and prints the readings into the Shell every two seconds.

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-bh1750-micropython/

from machine import Pin, SoftI2C
from bh1750 import BH1750
import time

# Initialize I2C communication
i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=400000)

# Create BH1750 object
light_sensor = BH1750(bus=i2c, addr=0x23)

try:
    # Read lux every 2 seconds
    while True:
        lux = light_sensor.luminance(BH1750.CONT_HIRES_1)
        print("Luminance: {:.2f} lux".format(lux))
        time.sleep(2)

except Exception as e:
    # Handle any exceptions during sensor reading
    print("An error occurred:", e)

View raw code

How the Code Works

We need to import the Pin and SoftI2C classes from the machine module.

from machine import Pin, SoftI2C
from bh1750 import BH1750
import time

In this case, this library needs SoftI2C instead of I2C. In MicroPython, SoftI2C refers to software I2C and I2C refers to hardware I2C.

Hardware I2C relies on dedicated hardware modules that are optimized for I2C communication. Software-based I2C, on the other hand, uses software-defined GPIO pins to emulate I2C communication.

We initialize an I2C communication on GPIOs 5 and 4, the I2C pins that the sensor is connected to.

# Initialize I2C communication
i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=400000)

Then, create a BH1750 instance, called light_sensor on the I2C bus defined previously.

light_sensor = BH1750(bus=i2c, addr=0x23)

To get luminance values, we just need to use the luminance() method on the BH1750 object and pass a measurement mode as an argument.

lux = light_sensor.luminance(BH1750.CONT_HIRES_1)

The library provides a list of measurement modes you can use. See the table below.

ConstantDescription
CONT_LOWRESContinuous, low-resolution (4lx), sampling takes ~24ms, sensor remains on after reading.
CONT_HIRES_1Continuous, high-resolution (1lx), sampling takes ~180ms, sensor remains on after reading.
CONT_HIRES_2Continuous, very high resolution (.5lx), sampling takes ~180ms, sensor remains on after reading.
ONCE_HIRES_1One-shot, low resolution (4lx), sampling takes ~24ms, sensor powered down after reading
ONCE_HIRES_2One-shot, high resolution (1lx), sampling takes ~180ms, sensor powered down after reading
ONCE_LOWRESOne-shot, very high resolution (.5lx), sampling takes ~180ms, sensor powered down after reading

Finally, we print the readings in the shell:

print("Luminance: {:.2f} lux".format(lux))

Testing the Code

Run the previous code on your Raspberry Pi Pico board. You should get new luminance values in lux units every two seconds.

Micropython getting luminance values from BH1750 sensor with the Raspberry Pi Pico

Cover the sensor or point some light to see the values changing.

Raspberry Pi Pico with the BH1750 luminance sensor

Wrapping Up

In this guide, you learned how to use the BH1750 luminance sensor with the Raspberry Pi Pico to get measurements of ambient light in LUX units.

We have a similar guide for other boards:

We also have tutorials for other sensors with the Raspberry Pi Pico that you may like:

We hope you found this tutorial useful. Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

2 thoughts on “Raspberry Pi Pico: BH1750 Ambient Light Sensor (MicroPython)”

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.