Tutorial · Iniciante · 30 min

Como funciona o barramento I2C: endereços e resistores de pull-up

Dois fios e um barramento compartilhado: veja a função dos resistores de pull-up, por que placas empilhadas quebram tudo e como corrigir colisões de endereço.

Introdução

Toda página de sensor deste site manda conectar SDA e SCL, e nenhuma delas diz o que esses dois fios estão fazendo. Na maioria dos casos você não precisa saber — conecta, a biblioteca funciona e o sensor faz a leitura.

Depois você adiciona uma segunda placa e a primeira para de responder. Ou a biblioteca retorna zeros sem erro. Ou dois dispositivos querem o mesmo endereço e nada na documentação diz o que fazer.

Tudo isso decorre do mesmo pequeno conjunto de fatos sobre I²C, e são menos fatos do que os sintomas sugerem.

Dois fios, muitos dispositivos

O I²C conecta todos os dispositivos ao mesmo par de fios compartilhado:

  • SDA — a linha de dados.
  • SCL — o sinal de relógio, sempre controlado pelo controlador.

Em um Arduino Uno, essas linhas são A4 e A5 (e os pinos duplicados ao lado de AREF — os mesmos dois pinos, não pinos extras). Cada dispositivo se conecta aos mesmos dois fios, em paralelo. Não existe fio de seleção de chip nem topologia em anel: adicionar um dispositivo significa soldá-lo ao mesmo par.

É por isso que ele escala tão bem para robôs. Um MPU-6050, um VL53L0X e um PCA9685 compartilham os dois fios e são diferenciados por endereço, não pela ligação.

Ninguém leva a linha ao nível alto

Este é o fato do qual tudo o mais decorre.

Um dispositivo I²C só pode puxar uma linha para baixo. Ele não pode levá-la ao nível alto — a saída é dreno aberto (open-drain), o que significa que ela é apenas uma chave para a massa. Deixada sozinha, a linha flutuaria em uma tensão indeterminada.

Os resistores de pull-up são o que leva a linha ao nível alto. Eles não são uma medida de robustez nem um acessório opcional: são metade do circuito e, sem eles, o barramento não tem estado ocioso e nada funciona.

O dreno aberto tem uma vantagem real, e é por isso que ele é usado assim: se dois dispositivos falarem ao mesmo tempo, um puxando para baixo e o outro liberando, o resultado é baixo. Nada entra em conflito, nada fica em curto, e o dispositivo que perdeu pode detectá-lo. Em um barramento onde qualquer dispositivo pode falar, isso importa.

A faixa aceitável para um resistor de pull-up

Há limites dos dois lados, e eles podem ser calculados.

Muito baixo e nenhum dispositivo consegue puxar a linha para baixo. A especificação exige que um dispositivo absorva pelo menos 3 mA enquanto mantém a linha abaixo de 0,4 V, portanto:

R_min = (Vcc − V_OL) / I_sink = (5 − 0.4) / 0.003 = 1533 Ω

Muito alto e o flanco de subida fica lento demais. A linha sobe como uma curva RC contra a capacitância do barramento, e o sinal de relógio não espera:

t_rise ≈ 0.85 × R × C        ≤ 1000 ns at 100 kHz, ≤ 300 ns at 400 kHz
Gráfico em escala logarítmica da resistência de pull-up permitida contra a capacitância total do barramento. Duas curvas decrescentes marcam o limite de tempo de subida para 100 quilohertz e 400 quilohertz, e uma linha vermelha horizontal em 1533 ohms marca o piso abaixo do qual nenhum dispositivo consegue absorver corrente suficiente para puxar a linha para baixo. Quatro linhas horizontais tracejadas marcam a resistência efetiva de uma, duas, três e quatro placas adaptadoras empilhadas em 4700, 2350, 1567 e 1175 ohms; a linha de quatro placas fica abaixo do piso.
A faixa utilizável fica entre o limite mínimo de corrente de absorção e o limite de tempo de subida. Observe onde 400 kHz fica em um barramento muito carregado: acima de cerca de 250 pF, seu limite cai abaixo do piso, portanto o modo rápido ali não é alcançável nem com resistores comuns. Baixar SVG

Agora vem a parte que pega as pessoas. Quase todas as placas adaptadoras já incluem seus próprios resistores de pull-up, geralmente de 4,7 kΩ. Ligue várias ao mesmo barramento e esses resistores ficam em paralelo:

Placas no barramento Resistência efetiva de pull-up Resultado
1 4700 Ω Bom
2 2350 Ω Bom
3 1567 Ω Marginal — 34 Ω acima do piso
4 1175 Ω Abaixo do piso

Portanto, a falha tem uma forma específica: um sensor funciona, dois funcionam, três funcionam em um bom dia e a quarta placa faz o barramento inteiro parar. Nada está quebrado. Os dispositivos simplesmente não conseguem puxar a linha para baixo o suficiente para que ela seja lida como nível baixo.

A solução é remover os resistores de pull-up de todas as placas, exceto uma — normalmente são dois pequenos resistores de superfície marcados 472, e a documentação da placa diz quais. Desoldá-los parece errado na primeira vez, mas é a resposta correta.

Examine o barramento antes de depurar qualquer outra coisa

Antes de mexer em uma biblioteca, pergunte ao barramento o que existe nele. Este código tenta todos os endereços e informa quais respondem:

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(115200);
  while (!Serial) {}

  Serial.println(F("Scanning I2C..."));
  uint8_t found = 0;
  for (uint8_t addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    if (Wire.endTransmission() == 0) {
      Serial.print(F("  device at 0x"));
      Serial.println(addr, HEX);
      found++;
    }
  }
  Serial.println(found ? F("done") : F("nothing answered — check wiring and pull-ups"));
}

void loop() {}

O resultado diz qual problema você tem:

  • Nada responde → ligação, alimentação ou resistores de pull-up ausentes. Não é a biblioteca.
  • O dispositivo responde em um endereço inesperado → um pino de configuração de endereço está definido de modo diferente do que você supôs.
  • O dispositivo responde, mas a biblioteca retorna zeros → o barramento está bom e o problema está acima dele.

Essa última linha vale mais que todo o código. Ela separa claramente “o fio está errado” de “o código está errado”, o que representa a maior parte do tempo de depuração.

Endereços, e a confusão do 0xD0

Um endereço I²C tem 7 bits. Dezesseis valores são reservados, restando 112 utilizáveis.

Aqui está a armadilha. No barramento, o endereço é enviado como sete bits seguidos por um bit de leitura/escrita, então parece um valor de 8 bits. As folhas de dados frequentemente citam essa forma de 8 bits. A biblioteca Wire do Arduino quer a forma de 7 bits.

Uma folha de dados do MPU-6050 diz que o endereço é 0xD0 para escrita e 0xD1 para leitura. A biblioteca Wire quer 0x68:

0xD0 = 1101 0000
0x68 = 0110 1000        the same bits, shifted right by one

Se um dispositivo não responder no endereço indicado na folha de dados, tente esse valor deslocado uma posição para a direita antes de concluir que a placa está morta. É o erro de I²C mais comum que existe.

Quando dois dispositivos querem o mesmo endereço

Os endereços são definidos pelo fabricante, então colisões são rotina. Três soluções, em ordem de preferência:

1. Um pino de configuração de endereço. A solução mais barata, quando a peça tem um. Um MPU-6050 fica em 0x68, ou em 0x69 com seu pino AD0 conectado ao nível alto — então dois deles coexistem com um fio. Um PCA9685 tem seis jumpers de solda que fornecem 64 endereços, e é por isso que você pode encadear até 62 placas em um barramento.

2. Mantenha os outros em reset enquanto reconfigura o endereço de um. Algumas peças têm endereço fixo, mas podem ser reprogramadas durante a execução. Um VL53L0X sempre é 0x29 de fábrica, e este é o método padrão para operar vários: mantenha o pino XSHUT de cada sensor em baixo, ative um sensor de cada vez, envie o comando para um novo endereço e repita. O novo endereço fica na RAM, portanto a sequência é executada novamente a cada inicialização.

3. Um multiplexador. Um TCA9548A é um dispositivo em 0x70 com oito barramentos comutados atrás dele. Selecione um canal, fale com o dispositivo nele e selecione o próximo. É a solução para oito sensores idênticos sem pino de configuração de endereço e sem reconfiguração — ao custo de uma peça e de o barramento trabalhar um de cada vez.

Velocidade, comprimento e o que realmente quebra

O I²C foi projetado para funcionar entre chips em uma mesma placa. Um robô o estende por um chassi, e é aí que os limites começam a incomodar.

  • A capacitância é o limite real, não o comprimento. A especificação permite 400 pF no total. Um cabo de fitas acrescenta cerca de 50–100 pF por metro, e cada dispositivo acrescenta cerca de 10 pF. Trechos longos falham ao deixar o flanco de subida lento demais — o que a figura acima mostra como a queda do limite.
  • Desacelere antes de desistir. Wire.setClock(50000) reduz à metade a taxa padrão e oferece margem real em um barramento marginal. Um robô consultando um sensor a 100 Hz não precisa de 400 kHz.
  • Mantenha SDA e SCL separadas. Executar um par adjacente em um cabo de fitas acopla os flancos do sinal de relógio aos dados. Um fio de massa entre elas ajuda.
  • Extensão do tempo de SCL (clock stretching). Um dispositivo que precisa de tempo pode manter SCL em baixo, e o controlador deve esperar. O hardware I²C lida com isso; algumas implementações por manipulação de bits não, e o sintoma é um dispositivo que funciona sozinho e corrompe os dados quando o barramento está ocupado.
  • Um barramento travado. Se um dispositivo foi reiniciado no meio de uma transferência, ele pode ficar segurando SDA em baixo para sempre, e toda varredura retorna nada. Pulsar SCL nove vezes deixa que ele termine o byte que acreditava estar enviando e libere a linha — é o que a rotina de recuperação de uma boa biblioteca está fazendo.

Misturando 3,3 V e 5 V

Um ESP32 e um Raspberry Pi operam o I²C a 3,3 V; um Uno opera a 5 V. Como o barramento é open-drain, a tensão dos resistores de pull-up decide o nível alto para todo o barramento. Se os resistores de pull-up forem conectados a 5 V com uma peça que só aceita 3,3 V, você estará colocando 5 V em um pino especificado para 3,6 V.

Duas coisas salvam você quase sempre, e vale saber em qual delas você está confiando:

  • Muitas placas adaptadoras “compatíveis com 5 V” são um chip de 3,3 V com um regulador e tradução de nível já na placa. Verifique antes de assumir — a presença de um regulador de tensão, por si só, não significa que os pinos de sinal estejam protegidos.
  • Quando não há tradução, um tradutor de nível bidirecional com MOSFET é a resposta padrão. Um divisor de tensão não é: ele quebra o comportamento open-drain na direção que importa.

Quando algo dá errado

Sintoma Causa provável
A varredura não encontra nada Resistores de pull-up ausentes, SDA/SCL trocados ou ausência de massa comum
Funciona com três placas e morre com quatro Resistores de pull-up paralelos abaixo do limite mínimo de corrente de absorção
Dispositivo ausente no endereço da folha de dados Endereço de 8 bits citado; desloque uma posição para a direita
Dois sensores idênticos, só um responde Colisão de endereço — pino de configuração de endereço, XSHUT ou multiplexador
Lê bem em um trecho curto e falha em um cabo longo Capacitância do barramento; reduza a frequência de SCL ou encurte o trecho
Corrupção intermitente enquanto os motores funcionam Ruído da fonte — veja potência e quedas de tensão
A varredura retorna nada de repente depois de uma falha Um dispositivo preso segurando SDA em baixo; aplique nove pulsos em SCL
Funciona sozinho e corrompe quando o barramento está ocupado Extensão do tempo de SCL que o controlador não respeita

O hábito útil é executar a varredura primeiro, sempre, antes de abrir o código-fonte de uma biblioteca. Leva trinta segundos e divide o problema ao meio — e metade de toda a depuração de I²C é não saber se a falha está no barramento ou no código.

Explore o grafo

Faz parte destas montagens

Projetos e caminhos de aprendizagem que incluem este tutorial.

Leitura complementar

Referências