Olá pessoal.
Recentemente tive que realizar uma integração entre o TC65i e um microcontrolador ATMEGA48/88/168. Encontrei várias dificuldades tanto no TC65i e tanto no ATMEGA. Logo, decidi contribuir com 2 posts que relacionam a comunicação via I2C entre o TC65i(master) com o ATMEGA(slave).
Não esqueçam, visitem a
Gridtech para projetos diversos nas tecnologias:
- Linux embedded ARM/x86
- GPRS: TC65 e Telite
- Zigbee
- Softwares web de FrontEnd para controle de diversos módulos de comunicação e concentradores de dados.
PARTE I - Codificação TC65i para utilizar a I2C como Master.
NOTA: Antes de qualquer condificação no TC65i, notei que não é possível utilizar eventos de listener nas portas de entrada em conjunto com a I2C ou SPI do modem. Quando é utilizado o listener das entradas digitais uma exceção fatal no modem ocorre. Até o momento não consegui informações sobre o erro da Cinterion. Portanto caso necessite utilizar leituras dos IOs do modem, faça um thread que fica checando a mudança de estados das entradas em cada 100ms por exemplo.
CÓDIGO TC65I - MASTER
A classe abaixo é a camada Control da I2C onde podemos encontrar os métodos já definidos de abertura/fechamento da I2C e da Leitura/Escrita na I2C. Para acessar esta classe fica como sugestão uma Thread contendo o método abaixo para acesso mais simplificado da classe:
...
private byte[] executeComandoI2C(byte[] comando) {
if (!I2CComm.getInstance().IS_CONNECTED) {
I2CComm.getInstance().openI2C();
}
if (I2CComm.getInstance().IS_CONNECTED) {
retry = recarregaRetry;
while (retry-- != 0) {
if (I2CComm.getInstance().writeData(0xAE, comando) == 0) {
long l = System.currentTimeMillis() + 200;
while (l <= System.currentTimeMillis()) {
semaphore(50);
}
byte[] dados = I2CComm.getInstance().readData(0xAF, 8);
if (dados != null) {
if (dados.length == 8 && dados[0] == 0x02 && dados[7] == 0x03) {
//System.out.println("RXI2C = " + Util.byteToHexString(dados));
//I2CComm.getInstance().closeI2C();
return dados;
} else {
System.out.println("ERRO: DADOS INVALIDOS -> RXI2C = " + Util.byteToHexString(dados));
}
}
}
}
//I2CComm.getInstance().closeI2C();
System.out.println("ERRO: uC nao respondeu ao comando I2C");
}
return null;
}
...
Não estou abordando neste Post o conceito da API java para comunicação da I2C no modem TC65i. Para isso consulte o javadoc da classe "I2cBusConnection" da Cinterion.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package gw.io.i2c;
import com.siemens.icm.io.I2cBusConnection;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
/**
*
* @author possebon
*/
public class I2CComm {
private static I2CComm instance = null;
public static I2CComm getInstance() {
if (instance == null) {
instance = new I2CComm();
}
return instance;
}
private I2cBusConnection cc = null;
private InputStream inStream = null;
private OutputStream outStream = null;
public boolean IS_CONNECTED = false;
private String baudrate = "400";
private String writeDelay = "800";
private String readDelay = "800";
private StringBuffer sb = new StringBuffer();
private char[] hexArr = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
public I2CComm() {
}
public I2CComm(String baudrate, String writeDelay, String readDelay) {
this.baudrate = baudrate;
this.writeDelay = writeDelay;
this.readDelay = readDelay;
}
public synchronized boolean openI2C() {
try {
// cc = (I2cBusConnection) Connector.open("i2c:" + "0" + ";baudrate=" + "100" + ";writeDelay=400" + ";readDelay=400");//+ ";writeDelay=1000" + ";readDelay=1000");
cc = (I2cBusConnection) Connector.open(
"i2c:" + "0"
+ ";baudrate=" + baudrate
+ ";writeDelay=" + writeDelay
+ ";readDelay=" + readDelay);
inStream = cc.openInputStream();
outStream = cc.openOutputStream();
IS_CONNECTED = true;
System.out.println("Conexao I2C aberta");
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Erro ao abrir comunicação pela I2C");
IS_CONNECTED = false;
}
return IS_CONNECTED;
}
public synchronized boolean closeI2C() {
if (inStream != null) {
try {
inStream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
inStream = null;
}
if (outStream != null) {
try {
outStream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
outStream = null;
}
if (cc != null) {
try {
cc.close();
} catch (Exception ex) {
ex.printStackTrace();
}
cc = null;
}
IS_CONNECTED = false;
System.out.println("Conexao I2C fechada");
return IS_CONNECTED;
}
public int writeData(int address, byte[] data) {
if (!IS_CONNECTED) {
openI2C();
}
String s = toHex(data);
// System.out.println(s);
try {
outStream.write(("<0" + toHex(address) + s + ">").getBytes());
outStream.flush();
long l = System.currentTimeMillis() + 2000;
while (System.currentTimeMillis() <= l) {
if (inStream.available() > 0) {
byte[] b = new byte[inStream.available()];
inStream.read(b);
// System.out.println(">>"+new String(b));
char flag = (char) b[2];
// System.out.println(">>"+flag);
if (flag == '+') {
return 0;
} else {
return -1;
}
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
return -1;
}
public byte[] readData(int address, int num) {
byte[] buff = new byte[num];
try {
byte[] numb = new byte[2];
numb[0] = (byte) (num >> 8);
numb[1] = (byte) (num & 255);
outStream.write(("<0" + toHex(address) + toHex(numb) + ">").getBytes());
outStream.flush();
long l = System.currentTimeMillis() + 2000;
while (System.currentTimeMillis() <= l) {
if (inStream.available() > 0) {
byte[] b = new byte[inStream.available()];
inStream.read(b);
//System.out.println(">>"+new String(b));
char flag = (char) b[2];
//System.out.println(">>"+flag);
if (flag == '+') {
String s = new String(b, 3, b.length - 3 - 1);
// System.out.println(s);
b = fromHex(b, 3, b.length - 3 - 1);
return (b);
} else {
return null;
}
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
return "error".getBytes();
}
private String toHex(byte[] b) {
int h = 0, l = 0;
sb.setLength(0);
int len = b.length;
for (int i = 0; i < len; i++) {
l = 15 & b[i];
h = 15 & (b[i] >> 4);
sb.append(hexArr[h]);
sb.append(hexArr[l]);
}
return sb.toString();
}
private byte[] fromHex(byte[] s, int offset, int length) {
byte[] b = new byte[length >> 1]; //rychle deleni 2
int tmp = 0;
length = offset + length;
for (int i = offset, j = 0; i < length; i += 2, j++) {
if (s[i] <= '9') {
tmp = s[i] - '0';
} else {
tmp = (s[i] - 'A') + 10;
}
tmp = tmp << 4;
if (s[i + 1] <= '9') {
tmp += s[i + 1] - '0';
} else {
tmp += (s[i + 1] - 'A') + 10;
}
b[j] = (byte) tmp;
}
return b;
}
private String toHex(int i) {
int h = 0, l = 0;
sb.setLength(0);
l = 15 & i;
h = 15 & (i >> 4);
sb.append(hexArr[h]);
sb.append(hexArr[l]);
return sb.toString();
}
}