Next we'll work on getting I2C working. To get I2C working, you will first need to make sure your I2C is enabled. The exact method to enable it can vary from manufacturer to manufacturer. You can check if it's already enabled by typing the following command:

ls /dev/i2c*

If it is enabled, there should be at least one i2C port listed.

Add your board to busio.py

When you added your board to PlatformDetect, if your board is being detected by the any_embedded_linux() function, you should be good to go. If not, you will want to go back and add it in Adafruit_Python_PlatformDetect. See the Adding Detection Code page in our Adding a Single Board Computer to PlatformDetect for Blinka guide for more details on how to add this.

Adding to the Chip File

Near the bottom of the Chip File, you will want an i2cPorts tuple variable that contains all of the I2C ports. It should end up looking something like the following:

# ordered as i2cId, sclId, sdaId
i2cPorts = (
    (0, I2C0_SCL, I2C0_SDA),
    (1, I2C1_SCL, I2C1_SDA)
)

The values in each of the tuple items are as follows:

  • The I2C bus number. For instance, a value of 1 corresponds to /dev/i2c-1.
  • The SCL or Serial Clock pin. This should be an alias for readability.
  • The SDA or Serial Data pin. This should also be an alias for readability.

Adding to the Board File

The only thing you will need to add to the board file are any aliases for the Pins.

Clock Stretching

Occasionally certain Single Board Computers such as the Raspberry Pi need some settings changed to enable Clock Stretching. You will need to check with the board manufacturer to be certain, but you can read more about it in our Raspberry Pi Clock Stretching guide.

Parts Used

To test, we'll need an I2C controlled board such as the BME280, which is a temperature sensor along with a couple other parts to connect it to the board.

Some boards operate at a lower voltage than 3.3v and may need to be wired through an I2C-safe Level Shifter as well.
Adafruit BME280 I2C or SPI Temperature Humidity Pressure Sensor
Bosch has stepped up their game with their new BME280 sensor, an environmental sensor with temperature, barometric pressure and humidity! This sensor is great for all sorts...
$14.95
In Stock
Angled shot of Half-Size Breadboard with Mounting Holes.
This cute 3.2″ × 2.1″ (82 × 53mm) solderless half-size breadboard has four bus lines and 30 rows of pins, our favorite size of solderless breadboard for...
$5.00
In Stock
Angled shot of Premium Female/Male 'Extension' Jumper Wires - 40 x 6 (150mm)
Handy for making wire harnesses or jumpering between headers on PCB's. These premium jumper wires are 6" (150mm) long and come in a 'strip' of 40 (4 pieces of each of...
$3.95
In Stock

Wiring

  • Connect the SBC 3.3V power pin to Vin
  • Connect the SBC GND pin to GND
  • Connect the SBC SDA (Pin #3) pin to the BME280 SDI
  • Connect the SBC SCL (Pin #5) pin to to the BME280 SCK

Check the Connection

After wiring it up, double-check your connections and run the following command to check bus 1:

sudo i2cdetect -y 1

If it gives you an error, you may need to add an -r parameter such as:

sudo i2cdetect -r -y 1

You should see a device. If not, you may want to try changing the I2C bus number until you get something. The BME280 has an I2C address of 0x77. It should look like the following:

Run the Test Script

Testing is really the most involved part about enabling I2C. First make sure the BME280 library is installed. If you chose a different sensor, make sure that library is installed:

sudo pip3 install adafruit-circuitpython-bme280

Next save the simpletest code to your board as bme280_simpletest.py:

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import time
import board
from adafruit_bme280 import basic as adafruit_bme280

# Create sensor object, using the board's default I2C bus.
i2c = board.I2C()  # uses board.SCL and board.SDA
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c)

# OR create sensor object, using the board's default SPI bus.
# spi = board.SPI()
# bme_cs = digitalio.DigitalInOut(board.D10)
# bme280 = adafruit_bme280.Adafruit_BME280_SPI(spi, bme_cs)

# change this to match the location's pressure (hPa) at sea level
bme280.sea_level_pressure = 1013.25

while True:
    print("\nTemperature: %0.1f C" % bme280.temperature)
    print("Humidity: %0.1f %%" % bme280.relative_humidity)
    print("Pressure: %0.1f hPa" % bme280.pressure)
    print("Altitude = %0.2f meters" % bme280.altitude)
    time.sleep(2)

Now go ahead and run that code using the following command:

sudo python3 bme280_simpletest.py

You should see it outputting a temperature and some other data every 2 seconds or so:

You will want to perform the same test procedure on each I2C port that you want to test. Be sure to change both your wiring and the corresponding pins in the test script if necessary.

Troubleshooting Tips

  • Make Sure I2C is enabled on your board
  • Make sure i2cdetect is seeing the sensor
  • Check your Wiring
  • Check Permissions
  • The board may just not support I2C.

This guide was first published on Apr 01, 2020. It was last updated on Mar 13, 2020.

This page (Getting I2C Working) was last updated on Oct 03, 2023.

Text editor powered by tinymce.