Enabling the I2C bus on a Raspberry Pi

As I just re-discovered after reinstalling Raspbian, by default only the superuser can access the I2C bus. (This may not be the case if you are using one of the official pre-installed SD card images).

To allow an ordinary user to use the I2C bus you need to add them to the I2C group. This needs to be done after installing the I2C tools, otherwise the group doesn’t exist.

To configure the kernel to load the modules automatically at startup you need begin by modifying /etc/modules.

$ su
# vi /etc/modules 

# /etc/modules: kernel modules to load at boot time.
# This file contains the names of kernel modules that should be
# loaded at boot time, one per line. Lines beginning with "#" 
# are ignored. Parameters can be specified after the module
# name.


If you are running a recent version of Raspbian (3.18 kernel or higher) you will also need to update the ‘/boot/config.txt’ file adding the lines below to the end of the file.

# vi /boot/config.txt 

initramfs initrd.img-4.4.0-1-rpi2 followkernel


Save the file, and reboot for the changes to take effect.

# reboot 

To allow users to access I2C devices you need to install the I2C tools and make any users members of the I2C user group.

$ su
# apt-get install i2c-tools
# adduser pi i2c
Adding user `'pi to group `i2c' ...
Adding user pi to group i2c

If you want to be able access I2C devices from a server-side script using lighttpd then you also need to add the www-data user to the i2c group.

# adduser www-data i2c
Adding user `'www-data to group `i2c' ...
Adding user www-data to group i2c

Finally if you are using python you need to install the required python library.

# apt-get install python-smbus 
Reading package lists... Done
Building dependency tree 
Reading state information... Done
Recommended packages:
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 11.5 kB of archives.
After this operation, 94.2 kB of additional disk space will be used.

That is it - you should now be able use the I2C bus as an ordinary user.

The following example python script uses eight LEDs connected to port A of an MC23017 IO expander to display a binary count from 0 to 255.

# py-pi-led-counter.py
# Demonstrates how to write data to the GPIO pins of a MCP23017 I2C I/O
# port expander. 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
ADDRESS = 0x20 # I2C address of MC23017 I/O expander.

IODIRA = 0x00 # Port A data direction register.
IODIRB = 0x01 # Port B data direction register.
GPIOA = 0x12 # Port A data register.
GPIOB = 0x13 # Port B data register.
IODIRx = IODIRA # Active data direction register.
GPIOx = GPIOA # Active GPIO register.

DELAY = 0.01 # Delay between iterations.
LIMIT = 1 # Number of time to display count.
MAX = 255 # Upper limit of the counter.

import smbus 
import time

bus = smbus.SMBus (1) # Rev 2 boards use bus 1, rev 1 boards use bus 0.
bus.write_byte_data(ADDRESS, IODIRx, 0x00) # Set all pins as outputs.

for iteration in range(LIMIT):
  for count in range(0, MAX +1):
    bus.write_byte_data(ADDRESS, GPIOx, count)
    time.sleep (DELAY)

time.sleep (1) # Wait 1 second to display final value.
bus.write_byte_data(ADDRESS, GPIOx, 0x00) # Clear all outputs.
bus.write_byte_data(ADDRESS, IODIRx, 0xFF) # Reset all pins to input.

Raspberry Pi is a trademark of the Raspberry Pi Foundation

This entry was posted in Linux, Programming and tagged , , . Bookmark the permalink.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.