terça-feira, junho 16, 2015

Dispositivos de 3.3 e 5 Volts na mesma Rede I2C

Este problema surgiu para mim quando eu liguei um display ao Raspberry Pi. Agora estou querendo ligar um dispositivo de 3.3V a um Arduino (5V) e resolvi pesquisar um pouco mais sobre o assunto.

Lembrando, os dispositivos I2C não colocam tensão alta nos barramentos, eles podem apenas "puxá-los" para terra ou deixar o sinal solto. Resistores de pull-up são responsáveis por forçar um nível alto quando nenhum dispositivo está acionando o barramento.


Quando temos dispositivos de 3.3 e 5 Volts em uma mesma rede I2C temos dois problemas em potencial:
  • Se os resistores de pull-up estiverem ligados ao 5V, os dispositivos de 3.3 receberão uma tensão próxima a 5V na entrada quando ela estiver no nível alto. Na maioria dos casos isto vai "fritar" o dispositivo.
  • Se os resistores de pull-up estiverem ligados ao 3.3V, os dispositivos de 5 receberão uma tensão próxima a 3.3V na entrada quando ela estiver no nível alto. Esta tensão pode não ser reconhecida como nível alto pelo dispositivo de 5V. A norma do I2C fala que a tensão mínima para o nível alto seria de 70% da alimentação, o que corresponderia a 3.5V.
A Philips (que é quem criou o padrão I2C) tem uma nota de aplicação sobre o assunto. Esta nota de aplicação tem uma solução elegante, que consiste em ter barramentos de 3.3 e 5V interligados por um MOSFET. Estes MOSFETs precisam atender algumas características (listadas na nota de aplicação). A mais crítica é a tensão de acionamento que deve ser, no máximo, 2V (para suportar um dispositivo de 2.7V). Entretanto, encontrei vários circuitos na internet usando o 2N7000, cuja tensão típica é 2.1V e a máxima 3V, aparentemente isto funciona quase sempre para dispositivos de 3.3V.



A solução de simplesmente ligar os pull-ups a 3.3V, como eu fiz no display, também é bastante usada com sucesso (apesar de violar a norma). No caso do Arduino, existe uma complicação adicional, que são os pull-ups internos do ATmega. Estes pull-ups são ativados pela biblioteca Wire (que vem com a IDE do Arduino) e estão ligados a 5V. Neste caso, os resistores externos ligados ao 3.3V acabam atuando como uma espécie de pull-down. Como os resistores externos são menores que os internos, a tensão vai ficar próxima de 3.3V e, espera-se, dentro da margem de segurança.

O Arduino Playground tem um artigo com mais detalhes sobre isto e mais algumas opções.

Nenhum comentário: