Who doesn’t know the Raspberry Pi by now? The board which brought Linux to millions…
As it turns out, Linux on small embedded boards usually has very good I2C support. All it takes essentially, is to load the proper kernel drivers – including one called “i2c-dev”. This provides access to I2C via a device called /dev/i2c-N
, with N a small integer to identify the I2C bus (there is often more than one).
On all Raspberry Pi’s except the earliest ones, the bus we’re interested in is /dev/i2c-1
.
Very conveniently, the two signal pins as well as +3.3V and GND are all located near each other, on the RPi’s pins 1/3/5/9. Here’s a little board sitting on top with an LPC810 on it:
And now we can read out the fake RTC slave shown previously, from the command line:
$ i2cdump -y -r 0x00-0x06 1 0x68 c
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 02 01 02 03 04 05 06 ???????
$ i2cdump -y -r 0x00-0x06 1 0x68 c
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 03 01 02 03 04 05 06 ???????
$ i2cdump -y -r 0x00-0x06 1 0x68 c
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 04 01 02 03 04 05 06 ???????
$
We’re reading out “registers” 0 through 6, and are indeed getting the expected values back.
Setting things up
To make the above work, you need to install the “i2c-tools” package and set up a few more details. This needs to be done once – all these changes will be remembered across reboots:
- enable I2C via the raspi-config “Advanced Options” menu:
sudo raspi-config
- install i2c-tools:
sudo apt-get install i2c-tools
- append a new line with “i2c-dev” to /etc/modules:
sudo nano /etc/modules
- add yourself to the “i2c” group:
sudo usermod -aG i2c pi
That final step is just for convenience: it allows user “pi” to launch the newly installed tools (i2cdetect, i2cdump, i2cget, i2cset) without having to use “sudo” all the time.
We can now run i2cdump as shown above (type “i2cdump –help” or “man i2cdump” for more info), or we can scan the I2C bus to see what devices are connected to it right now:
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
$
Nothing so far. The “UU” code means that I2C address 0x3b is unavailable for user-level access – it’s probably in use by the kernel itself.
After connecting the RTC plug or the fake LPC810 version, the output will change to:
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
$
Yeay, device 0x68 is alive and well!
Note that the I2C bus allows live connection, i.e. devices can be plugged and unplugged without powering down the Raspberry Pi. It’ll mess up some accesses, but I2C will recover.
If you’re looking for real-world uses of I2C: most PC’s are full of I2C-based chips, used for temperature sensors, fan control, and more. PS2-based keyboards and mice also use I2C.
[Back to article index]