Beaglebone Black I2C Tutorial

beaglebone black i2c

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.

beaglebone black i2c pinouts

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!

Leave a Reply

Your email address will not be published. Required fields are marked *