This mini-tutorial concerns using I2C (Inter-Integrated Circuit) on the BeagleBone Green Wireless board. The current BeagleBone Black Adafruit I2C library has a few compatibility issues with the BeagleBone Green Wireless (BBGW). There is far too little documentation on using the BBGW’s built in I2C library, mraa library, and I felt a post was needed.
When using an I2C library on the BeagleBone or Raspberry Pi there are a couple libraries to choose from. You can use the popular Adafruit library or the built in mraa library. With the BeagleBone or Raspberry Pi terminal (linux terminal) you can read the I2C bus without having to know the slave address of the device. To do this you use the “i2cdetect -y -r 0” command, where the number is the device numbered on the I2C bus. To find your device resend the command in the terminal with the number incremented, until you find the readout in the terminal with the register ID of that device displayed in hex.
For example the accelerometer with an ID of 42, that I’m looking for is bus numbered as “1” in my “i2cdetect -y -r 1” readout in the terminal.
As you can see register 0x0d is the device identification number register. We can see a 0x2a hex which translates to 42 decimal. So I know that the BeagleBone or Raspberry Pi interprets this device as bus “1” in the i2cdetect or i2cdump commands. This becomes important in the mraa library which uses this number to address the slave device. The adafruit library doesn’t need this number.
Using the libraries
When writing a python program on either the BeagleBone or Raspberry Pi we need to choose a library and import it once it’s installed. The BeagleBone Green Wireless has the mraa library built-in already so there’s no need to install it like the adafruit library. When using these libraries for i2c communication you need to setup the address, then use read and write commands. For the mraa i2c library we use the first call, which is i2c=mraa.I2c(2, True).
This means we are assigning the variable i2c to the device on the bus. The number 2 comes from the i2cdetect command mentioned before. Once we’ve assigned the variable “i2c” we can address it directly using the address(I2c self, uint8_t address) command. For example, if the device address in the data sheet is 0x1D we write the line i2c.address(0x1D) to initialize it. Next we write the pointer to address(0x01) to initialize the pointer on the device.
To configure the device we have to write data to registers on the device to set up the i2c device itself. We write to a register using the writeReg() function. Where the 2 parameters in the parenthesis are, writeReg(Register Address, Data) in uint_8 format. When reading from the device we use readReg(), where the 1 parameter in the parenthesis are readReg(Register Address) in unit_8 format. An example is provided below:
The Adafruit library requires the ‘python-smbus’ package installed on your device in order to use. The first call to setup the address of the device which is listed in the datasheet is i2c=Adafruit_I2C(device_address) where ‘device_address’ is the hex value of the device address. We then initialize the pointer on the device by setting register 0x01 to 0x00 using the i2c.write8(register, data) command. Which means we want to write 8 bits to a register. We can then set configuration registers of the device using the i2c.write8() command again with the register and data filled in. The way we read from most devices is reading 8 bits at a time from a register. We set a variable that we want to assign the data to. In this case it is ‘deviceID’. We use the i2c.readU8(register) command to read unsigned 8 bits from register 0x0d, which is the device ID register. An example is provided below:
from Adafruit_I2C import Adafruit_I2C
i2c = Adafruit_I2C(0x1D)
Difference in Libraries
The Adafruit Library requires the python-smbus’ package installed while the mraa library does not. The mraa library does require you to find the device number on the bus using ‘i2cdetect’ the command to set up the address before you start writing and reading registers. The libraries are similar in their syntax but are different in setup. The adafruit library also needs to be installed from a third party source and is not standard on the Beaglebone Green Wireless like mraa is. So you can start writing the code at first boot up.
mraa.I2c(mraa::I2c self, int bus, bool raw=False)
address(I2c self, uint8_t address) → mraa::Result
read(I2c self, uint8_t * data) → int
readByte(I2c self) → uint8_t
readBytesReg(I2c self, uint8_t reg, uint8_t * data)
readReg(I2c self, uint8_t reg) → uint8_t
readWordReg(I2c self, uint8_t reg) → uint16_t
write(I2c self, uint8_t const * data) → mraa::Result
writeByte(I2c self, uint8_t data) → mraa::Result
writeReg(I2c self, uint8_t reg, uint8_t data) → mraa::Result
writeWordReg(I2c self, uint8_t reg, uint16_t data) → mraa::Result
Methods defined here:
__init__(self, address, busnum=-1, debug=False)
readList(self, reg, length)
Read a list of bytes from the I2C device
Reads a signed 16-bit value from the I2C device
Reads a signed 16-bit value from the I2C device with rev byte order
Reads a signed byte from the I2C device
Reads an unsigned 16-bit value from the I2C device
Reads an unsigned 16-bit value from the I2C device with rev byte order
Read an unsigned byte from the I2C device
Reverses the byte order of an int (16-bit) or long (32-bit) value
write16(self, reg, value)
Writes a 16-bit value to the specified register/address pair
write8(self, reg, value)
Writes an 8-bit value to the specified register/address
writeList(self, reg, list)
Writes an array of bytes using I2C format
That’s it… good luck!