The first step, of course, is to set up an SD card suitable for the Raspberry Pi. I used the official Debian image from the Raspberry Pi Foundation.
Unfortunately, this official image has no support for I²C! You need to enter Chris's Digital Realm for that. Follow the instructions on Chris Boot's site to upgrade your Raspberry Pi firmware and install his Raspberry Pi kernel, which has drivers for I²C. Now if you run
lsmod
you should see a lot of good stuff, such as the i2c_bcm2708 module.Once you are running the new kernel, you will need to run
sudo modprobe i2c_dev
. You should also add i2c_dev
to the /etc/modules.conf
file so that it loads automatically the next time you boot up the Raspberry Pi. Now you should see two I2C devices:pi@raspberrypi:~/$ ls -l /dev/i2c* crw------- 1 root root 89, 0 Dec 31 1969 /dev/i2c-0 crw------- 1 root root 89, 1 Dec 31 1969 /dev/i2c-1
You will need to connect your device to the Raspberry Pi. I used Pololu Female-Female Premium Jumper Wires to make the following connections between the Raspberry Pi's GPIO header and my device:
- Raspberry Pi GND to device GND
- Raspberry Pi SCL to device SCL
- Raspberry Pi SDA to device SDA
- Raspberry Pi 3V3 Power to device's power input. This line can only provide a few tens of milliamps so you should look up how much current your device draws and make sure you can power it at 3.3 V. The Raspberry Pi's 5V power line is also available.
#include <unistd.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <linux/i2c-dev.h> #include <sys/ioctl.h> #include <fcntl.h> #define MAG_ADDRESS (0x3C >> 1) #define LSM303_WHO_AM_I_M (0x0F) int main() { char buf[10]; const char * devName = "/dev/i2c-0"; // Open up the I2C bus int file = open(devName, O_RDWR); if (file == -1) { perror(devName); exit(1); } // Specify the address of the slave device. if (ioctl(file, I2C_SLAVE, MAG_ADDRESS) < 0) { perror("Failed to acquire bus access and/or talk to slave"); exit(1); } // Write a byte to the slave. buf[0] = LSM303_WHO_AM_I_M; if (write(file, buf, 1) != 1) { perror("Failed to write to the i2c bus"); exit(1); } // Read a byte from the slave. if (read(file,buf,1) != 1) { perror("Failed to read from the i2c bus"); exit(1); } printf("result: 0x%02X\n", buf[0]); return 0; }When I ran this code, it printed 0x3C which means that it successfully talked to the device! There might be a simpler way to read the register; see the Linux Kernel I2C Documentation.
In conclusion, it was not too hard to get I²C working on the Raspberry Pi. The biggest hurdle is that the official Debian image/kernel has no support for it. This is kind of surprising because the Raspberry Pi team purposefully brought the I²C lines out to their GPIO header and the product has been selling for several months now.