Ir para o conteúdo

Comunicação I²C

A comunicação I²C está disponível em alguns modelos de Display Android. O clock da comunicação é 100kHz, e o dispositivo padrão é /dev/i2c-0.

Configuração do projeto

Para utilizar o protocolo I²C é necessário adicionar alguns arquivos e configurações ao seu projeto.

Dica

Baixe o projeto de demonstração de I²C na página de exemplos para ter um ponto de partida rápido!

  1. Adicione as classes I2CManager e PortNotOpenException ao seu package (geralmente no caminho app/src/main/[SEU_PACKAGE]/).
  2. Adicione a classe I2c ao package com.hyperlcd.iicdemo (geralmente no caminho app/src/main/com/hyperlcd/iicdemo/).
  3. Adicione o arquivo libi2craw.so à pasta app/src/main/jniLibs/armeabi-v7a/.
  4. Adicione o código abaixo à seção android do arquivo build.gradle (referente ao app: app/build.gradle).
    1
    2
    3
    4
    5
    6
     sourceSets {
         main {
             jni.srcDirs = []
             jniLibs.srcDirs = ['src/main/jniLibs', 'libs']
         }
     }
    

A estrutura final do projeto deve ser similar a esta:

Estrutura de arquivos do projeto no Android Studio

Arquivos:

IconDownload I2CManager.java

IconDownload PortNotOpenException.java

IconDownload I2c.java

IconDownload libi2craw.so

Exemplos de código

Instanciação e abertura da porta I²C:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public class MainActivity extends AppCompatActivity {
    // ...

    private I2CManager _i2cManager;

    // ...

    @Override
    public void onCreate(Bundle savedInstanceState) {

        // ...

        _i2cManager = new I2CManager();
        _i2cManager.open();

        // ...
    }    

    // ...
}

Métodos para enviar bytes (na classe MainActivity do exemplo acima):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void sendToI2C(byte slaveAddress, byte valueToSend) {
    try {
        _i2cManager.write(slaveAddress, valueToSend);
        Toast.makeText(this, "Sending value '" + valueToSend + "' to slave " + slaveAddress, Toast.LENGTH_SHORT).show();
    } catch (PortNotOpenException e) {
        Toast.makeText(this, "Cannot send, I²C is closed", Toast.LENGTH_SHORT).show();
        return;
    }
}

public void sendToI2C(byte slaveAddress, byte[] valuesToSend) {
    try {
        _i2cManager.write(slaveAddress, valuesToSend);
        Toast.makeText(this, "Sending value '" + valuesToSend + "' to slave " + slaveAddress, Toast.LENGTH_SHORT).show();
    } catch (PortNotOpenException e) {
        Toast.makeText(this, "Cannot send, I²C is closed", Toast.LENGTH_SHORT).show();
        return;
    }
}

// ... em algum lugar, chamando os métodos:
    sendToI2C((byte) 0x08, (byte) 0x10); // Envia 0x10 para o slave 0x08
    sendToI2C((byte) 0x09, new byte[]{0x0A, 0x0B}); // Envia 0x0A e 0x0B para o slave 0x09

Método para ler bytes (na classe MainActivity do exemplo acima):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public byte[] readFromI2C(byte slaveAddress, int expectedResponseLength) {
    byte[] inputDataBuffer = new byte[0];
    try {
        inputDataBuffer = _i2cManager.read(slaveAddress, expectedResponseLength);
        Toast.makeText(this, "Requesting " + expectedResponseLength + " bytes from slave " + _slaveAddress, Toast.LENGTH_SHORT).show();
    } catch (PortNotOpenException e) {
        Toast.makeText(this, "Cannot request, I²C is closed", Toast.LENGTH_SHORT).show();
        return inputDataBuffer;
    }

    return inputDataBuffer;
}

// ... em algum lugar, chamando o método:
    byte[] receivedValues = readFromI2C((byte) 0x08, 1); // Tenta ler 1 byte do slave 0x08

Fechamento da porta I²C:

1
2
3
4
5
// ...

_i2cManager.close();

// ...