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

You will also need to be sure your board is correctly importing in Adafruit_Blinka/src/busio.py. Inside of that file is a large import statement for I2C, SPI, and UART. You will want to add your board to all three if you plan on supporting all three.

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:

Download: file
# 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.
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
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
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 ten rainbow...
$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:

import time

import board
import busio
import adafruit_bme280

# Create library object using our Bus I2C port
i2c = busio.I2C(board.SCL, board.SDA)
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c)

# OR create library object using our Bus SPI port
# spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
# 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 Apr 01, 2020.

This page (Getting I2C Working) was last updated on Nov 24, 2020.