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 Password: # 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. loop i2c-bcm2708 i2c-dev
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
[pi2] kernel=vmlinuz-4.4.0-1-rpi2 initramfs initrd.img-4.4.0-1-rpi2 followkernel dtparam=i2c1=on dtparam=i2c_arm=on
Save the file, and reboot for the changes to take effect.
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 Password: # apt-get install i2c-tools : : : # adduser pi i2c Adding user `'pi to group `i2c' ... Adding user pi to group i2c Done. #
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 Done. #
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: i2c-tools The following NEW packages will be installed: python-smbus 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.
#!/usr/bin/python # # 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 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 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