Beaglebone Black I2C Tutorial

I2C is a popular communications protocol and is used by a lot of sensors and devices. This is why most microcontrollers, including Arduino, PICs, and STM32 have I2C support. In this tutorial, we will look at how to use the I2C protocol on the BBB and create a simple Beaglebone Black I2C application.
Beaglebone Black I2C Bus
There are three I2C buses on the Beaglebone Black according to the AM335X Technical Reference Manual and their memory addresses are:
- i2c-0: 0x44E0_B000
- i2c-1: 0x4802_A000
- i2c-2: 0x4819_C000
The i2c-0 bus is not accessible on the header pins while the i2c-1 bus is utilized for reading EEPROMS on cape add-on boards and may interfere with that function when used for other digital I/O operations.
The i2c-2 bus is the one that is free for use so we'll be using that in this tutorial.
Linux I2C Tools
Thankfully, Linux has built-in i2c tools that make our lives easier (unlike with BBB PWM). To check which of the three buses are enabled we can use i2cdetect:
root@arm:~# i2cdetect -l i2c-0 i2c OMAP I2C adapter I2C adapter i2c-2 i2c OMAP I2C adapter I2C adapter
Mine's showing two i2c devices. But again we can't use i2c-0 so we'll go with i2c-2.
To detect the devices connected to i2c-2:
root@arm:~# i2cdetect -r 2 WARNING! This program can confuse your I2C bus, cause data loss and worse! I will probe file /dev/i2c-2 using read byte commands. I will probe address range 0x03-0x77. Continue? [Y/n] y 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- root@arm:~#
Those addresses with UU are reserved addresses. Noticed there is a 68. That's because I connected a device with an I2C address of 68 to my Beaglebone Black.
Writing and Reading from the I2C Bus
Now, to write to the I2C bus, we can use:
i2cset -y 2 0x68 0xf4 0x34
The first hex number is the I2C device address followed by the specific data address and the byte to be written. You can read more about the i2cset at https://linux.die.net/man/8/i2cset.
To read the registers from the device connected to the I2C bus, the i2cdump command can be used:
root@arm:~# i2cdump -y 2 0x68 w 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f 00: 01ff ff01 2dff af2d 0faf 050f 9005 fb90 08: 0bfb 050b 4405 2844 7028 6e70 946e c694 10: 00c6 0000 0000 0000 0000 0000 0000 0000 18: 0000 0000 0000 0000 0000 0000 0000 0000 20: 0000 0000 0000 0000 0000 0000 0000 0000 28: 0000 0000 0000 0000 0000 0000 0000 0000 30: 0000 0000 0000 0000 0000 0000 0000 0000 38: 0000 0100 cd01 54cd 25e8 9825 04cc 4804 40: f454 70f4 ff50 d4ff 01de ca01 00be 8800 48: 0078 0000 0000 0000 0000 0000 0000 0000 50: 0000 0000 0000 0000 0000 0000 0000 0000 58: 0000 0000 0000 0000 0000 0000 0000 0000 60: 0000 0000 0000 0000 0000 0000 0000 0000 68: 0000 0000 0000 0000 0000 3000 2031 1307 70: 0000 0000 0000 0000 0000 0068 0000 0000 78: 0000 0000 0000 0000 0000 0000 0000 ff00 80: 01ff ff01 2dff af2d 0faf 050f 9005 fb90 88: 0bfb 050b 4405 2844 7028 6e70 946e c694 90: 00c6 0000 0000 0000 0000 0000 0000 0000 98: 0000 0000 0000 0000 0000 0000 0000 0000 a0: 0000 0000 0000 0000 0000 0000 0000 0000 a8: 0000 0000 0000 0000 0000 0000 0000 0000 b0: 0000 0000 0000 0000 0000 0000 0000 0000 b8: 0000 0100 cd01 00ce 2400 6824 04bc 9c04 c0: f4e8 70f4 ff50 bcff 01ae 7201 0072 8500 c8: 0084 0000 0000 0000 0000 0000 0000 0000 d0: 0000 0000 0000 0000 0000 0000 0000 0000 d8: 0000 0000 0000 0000 0000 0000 0000 0000 e0: 0000 0000 0000 0000 0000 0000 0000 0000 e8: 0000 0000 0000 0000 0000 3600 2137 a020 f0: 0000 0000 0000 0000 0000 0068 0000 0000 f8: 0000 0000 0000 0000 0000 0000 0000 ff00
Read more about i2cdump here: https://linux.die.net/man/8/i2cdump
Finally, we can acquire the data from a specific register on the I2C device using i2cget:
root@arm:~# i2cget -y 2 0x68 0x87 0xff
Here's more information for i2cget: https://linux.die.net/man/8/i2cget.
In the next part of this tutorial, we'll be reading data from the MPU6050 gyroscope + accelerometer and displaying it on the Beaglebone Black terminal. Follow this blog for updates!