The Inter-Integrated Circuit, I2C or two-wire interface, is a multi-master synchronous serial data link standard, invented by Phillips. I2C uses only two bidirectional open-drain lines:

  • SCL: serial clock (output from master)

  • SDA: serial data line (bidirectional).

The I2C bus can operate with a single master device and with up to 256 devices, as long as they all have different device addresses. The API provides functions to change the target.

The ConnectCore 8X has several I2C (Inter Integrated Circuits) interfaces to communicate with other I2C devices using this protocol. See the ConnectCore 8X Hardware Reference Manual for information about the available I2C interfaces.

Digi adds to Android an API to manage these I2C interfaces. You can configure the slave address, write, and read among other things. In the Digi APIx javadoc, you can find a complete list of the available methods in this API.

Unless noted, all I2C API methods require the com.digi.android.permission.I2C permission.

If your application does not have the com.digi.android.permission.I2C permission, it will not have access to any I2C service feature.

First of all, a new I2CManager object must be instantiated by passing the Android Application Context.

Instantiating the I2CManager
import android.app.Activity;
import android.os.Bundle;

import com.digi.android.i2c.I2CManager;

public class I2CSampleActivity extends Activity {

    I2CManager i2cManager;

    [...]

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Instantiate the I2C manager object.
        i2cManager= new I2CManager(this);

        [...]
    }

    [...]
}

Instantiate an I2C Interface

The I2CManager allows you to create an I2C object representing a physical module’s I2C interface. With this object you can write to the interface and read from it. If you don’t know how many interfaces are available in the device you can list them.

Method Description

createI2C(int)

Creates and returns an I2C object with the given interface number

listInterfaces()

Lists all available I2C interface numbers in the device

The createI2C(int) method may fail if the provided index is 0 or lower than 0 throwing an IllegalArgumentException.

Getting I2C interfaces
import com.digi.android.i2c.I2C;
import com.digi.android.i2c.I2CManager;

[...]

I2CManager i2cManager = ...;

// Create an I2C object for each available I2C interface.
int[] nInterfaces = i2cManager.listInterfaces();
I2C[] interfaces = new I2C[nInterfaces.length];

for (int i = 0; i < nInterfaces.length; i++)
    interfaces[i] = i2cManager.createI2C(nInterfaces[i]);

[...]

Manage the I2C interface

The next step is to open the I2C interface. To do so, you just need to call the open() method. Prior to open the interface you can get its interface number and check its current status (open or closed). When you are done with the interface, you must close it. All this management can be performed using the following methods.

Method Description

getInterfaceNumber()

Retrieves the I2C interface number

isInterfaceOpen()

Retrieves whether interface is open or not

open()

Opens the I2C interface

close()

Attempts to close the I2C interface

The open() method may fail if the interface number to open does not exists throwing a NoSuchInterfaceException or if there is an IO issue accessing the interface throwing an IOException.

The close() method may fail if there is an issue accessing the interface throwing an IOException.

Getting I2C interfaces
import com.digi.android.i2c.I2C;
import com.digi.android.i2c.I2CManager;

[...]

I2CManager i2cManager = ...;

I2C i2cInterface = ...;

// Print interface number.
System.out.println("Created I2C interface " + i2cInterface.getInterfaceNumber());

[...]

// Check if the interface is open, if not, open it.
if (!i2cInterface.isInterfaceOpen())
    i2cInterface.open();

[...]

// Close the I2C interface.
i2cInterface.close();

Communicate with the I2C interface

Once the I2C interface has been successfully opened, you can perform the following actions:

Read data

One of the most common things you can do with an I2C interface is to read one or more bytes from a specific device slave address. In all the read methods, the first parameter corresponds to this slave address.

Method Description

read(int, int)

Reads the given amount of bytes from the given slave device address

readByte(int)

Reads one byte from the given slave device address

All the previous methods may fail for the following reasons:

  • The provided slave address is lower than 0 throwing an IllegalArgumentException.

  • The interface is closed or an error occurs while accessing the interface throwing an IOException.

In addition, the readByte(int, int) method may fail if the number of bytes to read is 0 or lower than 0 throwing an IllegalArgumentException.

Reading data from the I2C interface
import com.digi.android.i2c.I2C;
import com.digi.android.i2c.I2CManager;

[...]

I2CManager i2cManager = ...;

I2C i2cInterface = ...;

[...]

byte[] readData = new byte[8];

// Read 8 bytes (byte by byte) from address 0.
for (int i = 0; i < readData.length; i++)
    readData[i] = i2cInterface.readByte(0);

// Read 8 bytes from address 0.
readData = i2cInterface.read(0, 8);

[...]
When you are done with the I2C interface you need to close it by calling the close() method.

Write data

The I2C API allows you also to write data in the slave address of the I2C device. In this case you can write data byte by byte or write an array of bytes.

Method Description

write(int, byte)

Writes the given byte in the given slave device address

write(int, byte[])

Writes the given byte array in the given slave device address

All the previous methods may fail for the following reasons:

  • The provided slave address is lower than 0 throwing an IllegalArgumentException.

  • The interface is closed or an error occurs while accessing the interface throwing an IOException.

In addition, the write(int, byte[]) method may fail if the data to write is null, throwing a NullPointerException.

Writing data to the I2C interface
import com.digi.android.i2c.I2C;
import com.digi.android.i2c.I2CManager;
[...]

I2CManager i2cManager = ...;

I2C i2cInterface = ...;

byte[] data = "abcdefgh";

[...]

// Write bytes contained in data (byte by byte).
for (int i = 0; i < data.length; i++)
    i2cInterface.write(0, data[i]);

// Write bytes contained in data.
i2cInterface.write(0, data);

[...]
When you are done with the I2C interface you need to close it by calling the close() method.

Transfer data

Finally, the I2C interface gives you the possibility to read and write data simultaneously in one operation. Like in previous methods, the first parameter corresponds to the slave address of the I2C device.

Method Description

transfer(int, byte[], int)

Simultaneously writes the given byte array in the given slave device address and reads the given amount of bytes

transfer(int, byte, int)

Simultaneously writes the given byte in the given slave device address and reads the given amount of bytes

All these methods may fail for the following reasons:

  • The provided slave address is lower than 0 or if the number of bytes to transfer is lower than 1 throwing an IllegalArgumentException.

  • The interface is closed or an error occurs while accessing the interface throwing an IOException.

In addition, the transfer(int, byte[], int) method may fail if the data to transfer is null throwing a NullPointerException.

Transferring data to the I2C interface
import com.digi.android.i2c.I2C;
import com.digi.android.i2c.I2CManager;
[...]

I2CManager i2cManager = ...;

I2C i2cInterface = ...;

byte[] data = "abcdefgh";
byte[] readData;

[...]

// Write bytes contained in data and read the same number of bytes (8) in the slave address 0.
readData = i2cInterface.transfer(0, data, data.length);

// Write one byte ('a') and read 8 bytes in the slave address 0.
readData = i2cInterface.transfer(0, (byte)'a', 8);

[...]
When you are done with the I2C interface you need to close it by calling the close() method.

I2C example

The I2C Sample Application demonstrates the usage of the I2C API. In this example you can access and control an external I2C EEPROM memory. Application can perform read, write and erase actions displaying results in an hexadecimal list view.

You can import the example using Digi’s Android Studio plugin. For more information, see Import a Digi sample application. To look at the application source code, go to the GitHub repository.