I2C Examples - Raspberry Pi Pico

The following short Python programs will demonstrate essential operation of the Raspberry Pi Pico board. These assume one or more I2C (or I2C) devices are externally attached. The I2C bus is a two-wire bidirectional serial bus for short-distance low-bandwidth communication between a microcontroller and peripherals.

Each sample can be run by copying the program into code.py on the CIRCUITPY drive offered by the board. The text can be pasted directly from this page, or each file can be downloaded from the CircuitPython sample code folder on this site.

Related Pages

I2C Bus Scan

The following utility script uses the built-in scanning feature to detect devices on the I2C bus. It uses only built-in firmware modules.

Direct download: bus_scan.py.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# bus_scan.py 

# Raspberry Pi Pico - I2C Bus Scan
# Search for devices on an I2C bus.

#---- electrical connections ---------------------------------------------------
# The Pico has two hardware I2C ports which can each be mapped to a number of
# possible pin pairs.  This example uses pins 6 and 7 for I2C0 SDA
# and SCL.  For alternate choices please see the official pinout diagram.

# Pico                  description
# pin 7/GP5/I2C0 SCL    I2C clock from port 0
# pin 6/GP4/I2C0 SDA    I2C data from port 0
# pin 38/GND            common ground

#-------------------------------------------------------------------------------
# related CircuitPython module documentation:

# busio             https://circuitpython.readthedocs.io/en/latest/shared-bindings/busio/index.html
# time              https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/index.html
# board             https://circuitpython.readthedocs.io/en/latest/shared-bindings/board/index.html

#-------------------------------------------------------------------------------
# load standard Python modules
import time

# load the CircuitPython hardware definition module for pin definitions
import board

# load the CircuitPython I2C support
import busio

#---------------------------------------------------------------
# The device is connected to I2C0 on pins 6 and 7.
i2c = busio.I2C(scl=board.GP5, sda=board.GP4)

#---------------------------------------------------------------
# Scan for devices.
if i2c.try_lock():
    print("Starting I2C scan.")
    devices = i2c.scan()
    i2c.unlock()
    
    print("Found %d I2C device(s)." % (len(devices)))
    for dev in devices:
        print("  I2C address:  %d (0x%x)" % (dev, dev))

else:
    print("Unable to lock I2C interface.")

Library Installation

The Pico firmware includes core modules for using the onboard I/O, but a number of optional packages are available to support specific hardware. The easiest way to install these is to download a bundle of precompiled libraries and copy individual packages or modules as needed to the CIRCUITPY filesystem.

The bundle version must match the installed version of CircuitPython. Current bundles are available at https://circuitpython.org/libraries. The bundle is zip file containing a large number of .mpy library files and sample code. You’ll be unpacking this on your desktop or laptop and installing just a subset of files.

For example, the seven-segment demo uses the adafruit_ht16k33 package, which is a folder containing several individual modules. To install it, unpack the library zip and locate the lib/adafruit_ht16k33 folder. This should be copied to the lib folder on the CIRCUITPY device. This folder is on the default search path for import.

To check the result, when installed correctly the Pico CIRCUITPY filesystem should include the following: lib/adafruit_ht16k33/segments.mpy

Seven-Segment LED Display

This demo shows numbers on a four-digit LED display connected via the Pico I2C bus. Please note it uses an optional library which must be installed separately.

The display is an Adafruit product: 0.56” 4-Digit 7-Segment Display w/I2C Backpack. Adafruit has a useful tutorial which describes this and several related products.

Direct download: seven_segment_demo.py.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# seven_segment_demo.py

# Raspberry Pi Pico - Seven Segment I2C Display demo

# Display a number on a four-digit seven-segment display using an I2C interface.

# This uses a particular product from Adafruit:
#   Adafruit 0.56" 4-Digit 7-Segment Display w/I2C Backpack
#   shop:     https://www.adafruit.com/products/881 (blue version)
#   tutorial: https://learn.adafruit.com/adafruit-led-backpack/0-dot-56-seven-segment-backpack

# IDeATe stocks a small quantity of these devices in Lending for long-term loan.
# The description can be found in the Physical Computing lab database under part
# numbers 2342, 2343, 2345, 2347, and 2349, corresponding to different digit
# colors.

# The board is based on a HT16K33 I2C LED driver chip.  The default address
# (with no jumpers installed) is 0x70.

#---- Adafruit library ----------------------------------------------------
# This sample uses an Adafruit library which is not included in the firmware,
# but which must be copied to the board.  All of these optional libraries are
# distributed in a bundle which must match the CircuitPython firmware version.

# To install, unzip the bundle zip and locate the lib/adafruit_ht16k33 folder.
# This contains several precompiled .mpy files; the folder should be copied to the
# lib folder on the CIRCUITPY device. 
# 
# E.g., the installed files should include the following:
#   CIRCUITPY/lib/adafruit_ht16k33/segments.mpy

#---- electrical connections ---------------------------------------------------
# The Pico has two hardware I2C ports which can each be mapped to a number of
# possible pin pairs.  This example uses pins 6 and 7 for I2C0 SDA
# and SCL.  For alternate choices please see the official pinout diagram.

# Pico                  display         description
# pin 7/GP5/I2C0 SCL    SCL             I2C clock from port 0
# pin 6/GP4/I2C0 SDA    SDA             I2C data from port 0
# pin 36/3.3VOUT        VCC             3.3V to power display
# pin 38/GND            GND             common ground

################################################################
# related CircuitPython module documentation:

# busio             https://circuitpython.readthedocs.io/en/latest/shared-bindings/busio/index.html
# time              https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/index.html
# board             https://circuitpython.readthedocs.io/en/latest/shared-bindings/board/index.html
# adafruit_ht16k33  https://circuitpython.readthedocs.io/projects/ht16k33/en/latest/api.html

# Adafruit_CircuitPython_HT16K33 source: https://github.com/adafruit/Adafruit_CircuitPython_HT16K33

################################################################################
# load standard Python modules
import time

# load the CircuitPython hardware definition module for pin definitions
import board

# load the CircuitPython I2C support
import busio

# load the Adafruit HT16K33 library
import adafruit_ht16k33.segments

#---------------------------------------------------------------
# The device is connected to I2C0 on pins 6 and 7.
i2c = busio.I2C(scl=board.GP5, sda=board.GP4)
display = adafruit_ht16k33.segments.Seg7x4(i2c)

#---------------------------------------------------------------
# Run the main loop to generate a counting display.

while True:
    for count in range(10000):
        display.print("%04d" % count)
        print("%04d" % count)
        time.sleep(1)
        

LCD 20x4 Character Display

This demo shows text and numbers on a LCD 20x4 display connected via the Pico I2C bus. Please note it uses an optional library which must be installed separately.

Direct download: lcd_display_demo.py.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# lcd_display_demo.py

# Raspberry Pi Pico - LCD I2C 20x4 Character Display demo

# Display text on a 20x4 character display using an I2C interface.
# IDeATe stocks a small quantity of these devices in the Hunt A10 Physical
# Computing Lab as part 0627.

# This is a generic display part which uses a PCF8574 "Remote 8-Bit I/O Expander
# for I2C Bus" to drive the LCD display parallel port.  The default I2C address
# is 0x27 as determined by a bus scan.

#---- LCD library ---------------------------------------------------------
# This sample uses a third-party library which is not included in the firmware,
# but which must be copied to the board.
#
# PCF8574 LCD library: https://github.com/dhalbert/CircuitPython_LCD
#
# To install, clone the repo or download it, then copy the lcd/ folder
# to the lib/ folder on the CIRCUITPY device.

#---- electrical connections ---------------------------------------------------
# The Pico has two hardware I2C ports which can each be mapped to a number of
# possible pin pairs.  This example uses pins 6 and 7 for I2C0 SDA
# and SCL.  For alternate choices please see the official pinout diagram.

# Pico                  display         description
# pin 7/GP5/I2C0 SCL    SCL             I2C clock from port 0
# pin 6/GP4/I2C0 SDA    SDA             I2C data from port 0
# pin 36/3.3VOUT        VCC             3.3V to power display
# pin 38/GND            GND             common ground

# On the display, install a jumper on the two-pin header labeled LED in order to
# power the backlight, otherwise the display is almost unreadable.

################################################################
# related CircuitPython module documentation:

# board  https://circuitpython.readthedocs.io/en/latest/shared-bindings/board/index.html
# busio  https://circuitpython.readthedocs.io/en/latest/shared-bindings/busio/index.html
# time   https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/index.html

################################################################################
# load standard Python modules
import time

# load the CircuitPython hardware definition module for pin definitions
import board

# load the CircuitPython I2C support
import busio

# load the LCD library
import lcd.lcd
import lcd.i2c_pcf8574_interface

#---------------------------------------------------------------
# The device is connected to I2C0 on pins 6 and 7.
i2c = busio.I2C(scl=board.GP5, sda=board.GP4)

iface = lcd.i2c_pcf8574_interface.I2CPCF8574Interface(i2c, 0x27)
display = lcd.lcd.LCD(iface, num_rows=4, num_cols=20)
display.set_backlight(True)
display.set_display_enabled(True)

display.print("Hello, world.")

#---------------------------------------------------------------
# Run the main loop to generate a counting display.

while True:
    for count in range(10000):
        display.set_cursor_pos(1, 4)
        display.print("%04d" % count)
        print("%04d" % count)
        time.sleep(1)