You are on page 1of 11

I2C Protocolo de ComunicaoI2C Protocolo

de Comunicao
At este momento vimos alguns protocolos de comunicao que o Arduino suporta, como
SPI, One-Wire, e mesmo a interface serial um protocolo de comunicao bem definido.
O I2C trabalha no modelo master-slave, com pelo menos um dispositivo atuando
como master, e os demais dispositivos atuando como slave. A funo do master
coordenar a comunicao, sendo que ele quem envia informaes a determinado slave
ou consulta informaes. No vi nenhum setup, ou tutorial, onde o dispositivo slave inicia a
comunicao, sempre o master quem faz esse papel. Podemos ter mais de um master
numa conexo I2C, e at 112 dispositivos slaves. Alguns materiais pela Internet, incluindo
o site do Arduino, falam que possvel termos 127 dispositivos num setup I2C, mas eu
acredito que esse nmero seja terico, e que 112 dispositivos um nmero mais realista.
Nesta pgina voc encontra um excelente material sobre I2C.

Conexo utilizando I2C


I2C um protocolo de barramento(ou bus), ou seja, com os mesmo fios conectamos todos
os dispositivos do nosso setup. Essa caracterstica, barramento, um dos grandes
atrativos do I2C, pois reduzimos em muito a necessidade de pinos de conexo no Arduino,
pois usaremos sempre os mesmo fios para a conexo, no importa se estamos utilizando
1 ou 127 dispositivos.

Um dispositivo conectado ao barramento, atuando como Master, e 3 dispositivos atuando como Slave,
tambm conectados ao barramento

O Arduino vem com pinos prprios para a conexo I2C, no caso do Uno e derivados os
pinos so sempre o 4 (SDA) e 5(SCL). No caso do Arduino Mega, os pinos utilizados so
o 20 (SDA) e 21 (SCL).
SDA significa Serial Data e SCL significa Serial Clock. SDA o pino que efetivamente
transfere os dados, e SCL serve para temporizao entre os dispositivos, de modo que a
comunicao pela SDApossa ter confiabilidade. Como podem observar, tanto o envio
quanto a recepo de dados realizada utilizando a linha SDA, ou seja, uma linha bidirecional de comunicao, ora estamos enviando dados por este pino, ora estamos
recebendo dados.

Pinos utilizados para a comunicao I2C

Existem uma variedade enorme de dispositivos que utilizam o protocolo I2C, como o
prprio Arduino, Raspberry, memrias externas (EEPROM), I/O expanders, RTC (Real
Time Clock), Visor (LCD, TFT, etc), sensores diversos(temperatura, acelermetro, etc).
Portanto, uma hora ou outra voc certamente vai se deparar com um dispositivo I2C, e
saber trabalhar com o protocolo vai ser muito til. Vrios dispositivos oferecem vrias
interfaces de conexo, ou seja, podemos conect-lo ao Arduino usando I2C, ou serial, ou
SPI, e, depois que aprender I2C, bem provvel que esta seja sua escolha.
Alm do SDA e SCL, os dispositivos utilizam o terra (GND) e o Vcc para alimentao.
Abaixo um exemplo de ligao mais real:

Arduino e outros dispositivos atuando como Slave de um Raspberry Master.

Reparem na imagem acima o uso de resistores pull-up para as linhas SDA e SCL. Estes
resistores normalmente so utilizados quando h mais de um slave no barramento, e o
valor do resistor dependente dos dispositivos. Normalmente dispositivos I2C possuem
um datasheet, e nele podemos encontrar o valor adequado dos resistores pull-up. Se
estiver utilizando apenas um dispositivo slave conectado ao Arduino, no se preocupe, o
Arduino j vem com resistores pull-up internos especializados para a comunicao I2C.
Ainda com relao a imagem acima, a ordem que conectamos os dispositivos no importa.
Podemos ligar os dispositivos como quizermos, respeitando a pinagem certa, que o
resultado final ser o mesmo.

A distncia normal de trabalho no barramento I2C de aproximadamente 1 metro.Alem


disso podemos ter problemas de impedncia, mas ai j no posso ajudar muito, se

lembrem que sou um Z Man em eletrnica


. Existem dispositivos que podem
estender esta distncia de trabalho at aproximadamente 50 metros, e talvez eu faa um
post sobre esses dispositivos futuramente.
Bem, j sabemos como conectar os dispositivos no barramento, sabemos que podemos
ter teoricamente 127 dispositivos, mas Como saber com qual dispositivos estou falando?

I2C Endereamento de dispositivos


Dispositivos I2C possuem um endereo que os identifica. Esse endereo composto
normalmente por 7 bits. Se lembram do limite terico de 127 dispositivos, pois ento, com

7 bits podemos ter 127 valores diferentes


. Aqui temos um pouco de confuso,
pois alem dos 7 bits que definem o endereamento, temos ainda um ultimo bit, totalizando
8 bits, que indicam se uma operao de leitura ou escrita (read/write). Normalmente os
dispositivos vem indicando o seu endereo no formato hexadecimal, considerando 7 bits.
Neste caso o Arduino, atuando como master, insere estes 7 bits no incio da transmisso,
ajusta adequadamente o oitavo bit, e tudo funciona muito bem.

Em alguns casos, o fabricante do dispositivo especifica o endereo do dispositivo


utilizando o oitavo bit. Nestes casos comum o datasheet especificar um endereo para
escrita e outra para leitura. Nesta situao temos que calcular o endereo correto (7 bits),
ou dar um shift em nosso sketch de modo a desconsiderar o oitavo bit.

Como podem ver no exemplo acima, o dispositivo X possui dois endereos( 0x92 e 0x93),
sendo que o valor que realmente nos interessa o 0x49, que obtido desconsiderando o
ultimo bit de qualquer um dos endereos anteriores.
Caso no fique claro pelo datasheet se o seu dispositivo usa 7 ou 8 bits no
endereamento, outra forma verificar se o endereo esta na faixa de endereos I2C
vlidos.

Como podem ver, a faixa disponvel vai de 0x08 a 0x77. No se esquea que em
hexadecimal, e fazendo as converses para decimal podemos concluir que o nmero de

dispositivos possveis na prtica 112


Bem, j sabemos como conectar os dispositivos e como nos direcionar a ele. Vamos
comear a brincadeira?

I2C Escritas e Leituras.


Todo o trabalho com dispositivos I2C se resume a uma operao de leitura ou uma
operao de escrita. Em nossos sketches, independente do dispositivo, estaremos lendo
alguma informao ou escrevendo alguma informao em um dispositivo especifico. Ser
comum encontrarmos dispositivos com alguma particularidade nas operaes de
escrita/leitura, mas em geral o datasheet do dispositivo fornece esses detalhes. Vamos ver
como funciona a escrita e a leitura de dispositivos I2c.
Uma observao importante para trabalharmos com I2C no Arduino; temos que dar um
include na biblioteca Wire. No incio de qualquer sketch inclua a linha #include <Wire.h> .
Aps incluirmos a biblioteca, necessrio inicializ-la dentro de setup() com Wire.begin().

I2C Escrita
A escrita em dispositivos I2C relativamente simples. O trecho de cdigo abaixo mostra
como funciona esse processo:

Wire.beginTransmission(endereo);
Wire.write(memria);
Wire.write(valor);
Wire.endTransmission();

Wire.beginTransmission(endereo); envia o endereo do dispositivo pela linha SDA,


sinalizando o dispositivo correspondente que haver uma comunicao. Todos os
dispositivos escutam essa informao, mas apenas o dispositivo que possui o endereo
informado estar apto a se comunicar.
Wire.write(memria); A maioria possui diversos registradores que podem ser gravados, e
precisamos informar em qual registrador queremos informao.
Wire.write(valor); envia o valor (sempre 1 byte) pela SDA para o dispositivo informado
anteriormente. O dispositivo possui um registrador (ou memria) aguardando pela
informao, e os outros dispositivos ignoram esta comunicao. O comum enviarmos
uma informao (um byte) em cada operao.

Wire.endTransmission(); Aps enviarmos a informao, devemos finalizar a operao


com essa linha, liberando o dispositivo e o barramento I2C para novas operaes.
No sei se notaram, mas utilizamos o mesmo comando tanto para
informar ONDE queremos gravar e O QUE queremos gravar. Essa uma fonte de
confuso inicialmente, mas relativamente simples. Tudo dependo do datasheet do
dispositivo, onde, no caso acima, teramos a instruo de que, numa operao de escrita,
o primeiro byte indica a posio de memria, e o segundo byte indica o valor a ser
gravado. Poderamos muito bem ter um dispositivo com apenas um registrador para
gravao, e portanto no seria necessrio informar em qual posio para o valor ser
gravado

I2C Leitura.
O processo de leitura envolve mais comandos. Normalmente o dispositivo possui diversos
registradores (ou posies de memria) para armazenar diferentes informaes, ento
temos que informar de qual registrador queremos ler informao. Ainda, lembrando que
cada registrador armazena um byte, podemos especificar o nmero de bytes que
queremos ler. Vamor ver um trecho de cdigo:

Wire.beginTransmission(endereo);
Wire.write(memoria);
Wire.endTransmission();
Wire.requestFrom(endereo, 1);
byte valor;
if (Wire.available()){
valor=Wire.read();
}
Wire.endTransmission();

As trs primeiras linhas foram explicadas anteriormente e, basicamente, posicionam o


registrador do dispositivo na posio que queremos fazer a leitura. Na sequncia temos:
Wire.requestFrom(endereo, 1); Este comando informa o dispositivo identificado por
endereo que queremos ler uma posio de memria(ou byte, ou registrador), a partir da
posio de memria especificada anteriormente. Esta informao posta imediatamente
na linha SDA, e o dispositivo ento responde informando tambm na SDA o valor contido
no registrador. Neste exemplo estamos pedindo apenas o valor de um registrador, mas
poderamos pedir tantos quanto forem necessrios. Neste caso o dispositivo iria informar
sequencialmente, a partir da posio informada pelo write anterior.
Wire.available(); Este comando verifica se h informao disponvel para leitura. O
hardware do Arduino armazena em buffer as informaes recebidas, e atualmente este
buffer tem o tamanho de 32 bytes. com isso podemos fazer tranquilamente a leitura de 32
bytes sequenciais.

Wire.read(); Esta bem simples, similar ao Serial.read. Basicamente este comando l um


byte de cada vez.

Chega por hoje n?


Bem pessoal, vou ficando por aqui. Espero ter ajudado um pouco. Creio que I2C uma
daqueles casos em que a melhor teoria a prtica, ento no prximo post vamos
continuar vendo I2C, desta vez aplicando o que vimos aqui no mdulo AT24C256.
Abs e at a prxima.

Referncias
Blog TronixStuff
Endereamento
PDF sobre o protocolo I2C
I2C a sigla de Inter-Integrated Circuit, e basicamente um protocolo de comunicao
entre dispositivos que falam I2C.
At este momento vimos alguns protocolos de comunicao que o Arduino suporta, como
SPI, One-Wire, e mesmo a interface serial um protocolo de comunicao bem definido.
O I2C trabalha no modelo master-slave, com pelo menos um dispositivo atuando
como master, e os demais dispositivos atuando como slave. A funo do master
coordenar a comunicao, sendo que ele quem envia informaes a determinado slave
ou consulta informaes. No vi nenhum setup, ou tutorial, onde o dispositivo slave inicia a
comunicao, sempre o master quem faz esse papel. Podemos ter mais de um master
numa conexo I2C, e at 112 dispositivos slaves. Alguns materiais pela Internet, incluindo
o site do Arduino, falam que possvel termos 127 dispositivos num setup I2C, mas eu
acredito que esse nmero seja terico, e que 112 dispositivos um nmero mais realista.
Nesta pgina voc encontra um excelente material sobre I2C.

Conexo utilizando I2C


I2C um protocolo de barramento(ou bus), ou seja, com os mesmo fios conectamos todos
os dispositivos do nosso setup. Essa caracterstica, barramento, um dos grandes
atrativos do I2C, pois reduzimos em muito a necessidade de pinos de conexo no Arduino,
pois usaremos sempre os mesmo fios para a conexo, no importa se estamos utilizando
1 ou 127 dispositivos.

Um dispositivo conectado ao barramento, atuando como Master, e 3 dispositivos atuando como Slave,
tambm conectados ao barramento

O Arduino vem com pinos prprios para a conexo I2C, no caso do Uno e derivados os
pinos so sempre o 4 (SDA) e 5(SCL). No caso do Arduino Mega, os pinos utilizados so
o 20 (SDA) e 21 (SCL).
SDA significa Serial Data e SCL significa Serial Clock. SDA o pino que efetivamente
transfere os dados, e SCL serve para temporizao entre os dispositivos, de modo que a
comunicao pela SDApossa ter confiabilidade. Como podem observar, tanto o envio
quanto a recepo de dados realizada utilizando a linha SDA, ou seja, uma linha bidirecional de comunicao, ora estamos enviando dados por este pino, ora estamos
recebendo dados.

Pinos utilizados para a comunicao I2C

Existem uma variedade enorme de dispositivos que utilizam o protocolo I2C, como o
prprio Arduino, Raspberry, memrias externas (EEPROM), I/O expanders, RTC (Real
Time Clock), Visor(LCD, TFT, etc), sensores diversos(temperatura, acelerometro, etc).
Portanto, um hora ou outra voc certamente vai se deparar com um dispositivo I2C, e
saber trabalhar com o protocolo vai ser muito til. Vrios dispositivos oferecem vrias
interfaces de conexo, ou seja, podemos conect-lo ao Arduino usando I2C, ou serial, ou
SPI, e, depois que aprender I2C, bem provvel que esta seja sua escolha.
Alem do SDA e SCL, os dispositivos utilizam o terra(GND) e o Vcc para alimentao.
Abaixo um exemplo de ligao mais real:

Arduino e outros dispositivos atuando como Slave de um Raspberry Master.

Reparem na imagem acima o uso de resistores pull-up para as linhas SDA e SCL. Estes
resistores normalmente so utilizados quando h mais de um slave no barramento, e o
valor do resistor dependente dos dispositivos. Normalmente dispositivos I2C possuem
um datasheet, e nele podemos encontrar o valor adequado dos resistores pull-up. Se
estiver utilizando apenas um dispositivo slave conectado ao Arduino, no se preocupe, o
Arduino j vem com resistores pull-up internos especializados para a comunicao I2C.
Ainda com relao a imagem acima, a ordem que conectamos os dispositivos no importa.
Podemos ligar os dispositivos como quizermos, respeitando a pinagem certa, que o
resultado final ser o mesmo.
A distncia normal de trabalho no barramento I2C de aproximadamente 1 metro.Alem
disso podemos ter problemas de impedncia, mas ai j no posso ajudar muito, se

lembrem que sou um Z Man em eletrnica


. Existem dispositivos que podem
estender esta distncia de trabalho at aproximadamente 50 metros, e talvez eu faa um
post sobre esses dispositivos futuramente.
Bem, j sabemos como conectar os dispositivos no barramento, sabemos que podemos
ter teoricamente 127 dispositivos, mas Como saber com qual dispositivos estou falando?

I2C Endereamento de dispositivos


Dispositivos I2C possuem um endereo que os identifica. Esse endereo composto
normalmente por 7 bits. Se lembram do limite terico de 127 dispositivos, pois ento, com

7 bits podemos ter 127 valores diferentes


. Aqui temos um pouco de confuso,
pois alem dos 7 bits que definem o endereamento, temos ainda um ultimo bit, totalizando
8 bits, que indicam se uma operao de leitura ou escrita (read/write). Normalmente os
dispositivos vem indicando o seu endereo no formato hexadecimal, considerando 7 bits.
Neste caso o Arduino, atuando como master, insere estes 7 bits no incio da transmisso,
ajusta adequadamente o oitavo bit, e tudo funciona muito bem.

Em alguns casos, o fabricante do dispositivo especifica o endereo do dispositivo


utilizando o oitavo bit. Nestes casos comum o datasheet especificar um endereo para
escrita e outra para leitura. Nesta situao temos que calcular o endereo correto (7 bits),
ou dar um shift em nosso sketch de modo a desconsiderar o oitavo bit.

Como podem ver no exemplo acima, o dispositivo X possui dois endereos( 0x92 e 0x93),
sendo que o valor que realmente nos interessa o 0x49, que obtido desconsiderando o
ultimo bit de qualquer um dos endereos anteriores.
Caso no fique claro pelo datasheet se o seu dispositivo usa 7 ou 8 bits no
endereamento, outra forma verificar se o endereo esta na faixa de endereos I2C
vlidos.

Como podem ver, a faixa disponvel vai de 0x08 a 0x77. No se esquea que em
hexadecimal, e fazendo as converses para decimal podemos concluir que o nmero de

dispositivos possveis na prtica 112

Bem, j sabemos como conectar os dispositivos e como nos direcionar a ele. Vamos
comear a brincadeira?

I2C Escritas e Leituras.


Todo o trabalho com dispositivos I2C se resume a uma operao de leitura ou uma
operao de escrita. Em nossos sketches, independente do dispositivo, estaremos lendo
alguma informao ou escrevendo alguma informao em um dispositivo especifico. Ser
comum encontrarmos dispositivos com alguma particularidade nas operaes de
escrita/leitura, mas em geral o datasheet do dispositivo fornece esses detalhes. Vamos ver
como funciona a escrita e a leitura de dispositivos I2c.
Uma observao importante para trabalharmos com I2C no Arduino; temos que dar um
include na biblioteca Wire. No incio de qualquer sketch inclua a linha #include <Wire.h> .
Aps incluirmos a biblioteca, necessrio inicializ-la dentro de setup() com Wire.begin().

I2C Escrita
A escrita em dispositivos I2C relativamente simples. O trecho de cdigo abaixo mostra
como funciona esse processo:

Wire.beginTransmission(endereo);
Wire.write(memria);
Wire.write(valor);
Wire.endTransmission();

Wire.beginTransmission(endereo); envia o endereo do dispositivo pela linha SDA,


sinalizando o dispositivo correspondente que haver uma comunicao. Todos os
dispositivos escutam essa informao, mas apenas o dispositivo que possui o endereo
informado estar apto a se comunicar.
Wire.write(memria); A maioria possui diversos registradores que podem ser gravados, e
precisamos informar em qual registrador queremos informao.
Wire.write(valor); envia o valor (sempre 1 byte) pela SDA para o dispositivo informado
anteriormente. O dispositivo possui um registrador (ou memria) aguardando pela
informao, e os outros dispositivos ignoram esta comunicao. O comum enviarmos
uma informao (um byte) em cada operao.
Wire.endTransmission(); Aps enviarmos a informao, devemos finalizar a operao
com essa linha, liberando o dispositivo e o barramento I2C para novas operaes.
No sei se notaram, mas utilizamos o mesmo comando tanto para
informar ONDE queremos gravar e O QUE queremos gravar. Essa uma fonte de
confuso inicialmente, mas relativamente simples. Tudo dependo do datasheet do
dispositivo, onde, no caso acima, teramos a instruo de que, numa operao de escrita,
o primeiro byte indica a posio de memria, e o segundo byte indica o valor a ser
gravado. Poderamos muito bem ter um dispositivo com apenas um registrador para
gravao, e portanto no seria necessrio informar em qual posio para o valor ser
gravado

I2C Leitura.
O processo de leitura envolve mais comandos. Normalmente o dispositivo possui diversos
registradores (ou posies de memria) para armazenar diferentes informaes, ento
temos que informar de qual registrador queremos ler informao. Ainda, lembrando que

cada registrador armazena um byte, podemos especificar o nmero de bytes que


queremos ler. Vamor ver um trecho de cdigo:

Wire.beginTransmission(endereo);
Wire.write(memoria);
Wire.endTransmission();
Wire.requestFrom(endereo, 1);
byte valor;
if (Wire.available()){
valor=Wire.read();
}
Wire.endTransmission();

As trs primeiras linhas foram explicadas anteriormente e, basicamente, posicionam o


registrador do dispositivo na posio que queremos fazer a leitura. Na sequncia temos:
Wire.requestFrom(endereo, 1); Este comando informa o dispositivo identificado por
endereo que queremos ler uma posio de memria(ou byte, ou registrador), a partir da
posio de memria especificada anteriormente. Esta informao posta imediatamente
na linha SDA, e o dispositivo ento responde informando tambm na SDA o valor contido
no registrador. Neste exemplo estamos pedindo apenas o valor de um registrador, mas
poderamos pedir tantos quanto forem necessrios. Neste caso o dispositivo iria informar
sequencialmente, a partir da posio informada pelo write anterior.
Wire.available(); Este comando verifica se h informao disponvel para leitura. O
hardware do Arduino armazena em buffer as informaes recebidas, e atualmente este
buffer tem o tamanho de 32 bytes. com isso podemos fazer tranquilamente a leitura de 32
bytes sequenciais.
Wire.read(); Esta bem simples, similar ao Serial.read. Basicamente este comando l um
byte de cada vez.

Chega por hoje n?


Bem pessoal, vou ficando por aqui. Espero ter ajudado um pouco. Creio que I2C uma
daqueles casos em que a melhor teoria a prtica, ento no prximo post vamos
continuar vendo I2C, desta vez aplicando o que vimos aqui no mdulo AT24C256.
Abs e at a prxima.