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 8M Mini has several I2C (Inter Integrated Circuits) interfaces to communicate with other I2C devices using this protocol. See the ConnectCore 8M Mini 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.
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 |
---|---|
|
Creates and returns an |
|
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
.
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 |
---|---|
|
Retrieves the I2C interface number |
|
Retrieves whether interface is open or not |
|
Opens the I2C interface |
|
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
.
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 |
---|---|
|
Reads the given amount of bytes from the given slave device address |
|
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
.
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 |
---|---|
|
Writes the given byte in the given slave device address |
|
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
.
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 |
---|---|
|
Simultaneously writes the given byte array in the given slave device address and reads the given amount of bytes |
|
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
.
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.