Voltar

Scanner I2C com Arduino: Encontre Todos os Dispositivos no Barramento

Introdução

Você já conectou um novo sensor ou display I2C ao seu Arduino e se perguntou: “Qual endereço esse dispositivo usa?” Você não está sozinho! O protocolo I2C é uma forma poderosa de se comunicar com vários dispositivos usando apenas dois fios, mas cada dispositivo tem um endereço único — e às vezes esse endereço não é óbvio na folha de dados. É aí que entra um scanner I2C. É um sketch simples que testa todos os endereços possíveis e informa quais respondem.

Neste tutorial, vamos construir um scanner I2C usando um Arduino Uno e um display OLED SSD1306 (que também serve como um dispositivo conhecido no barramento). Vamos executar tudo dentro do simulador no navegador Velxio, então você não precisa de nenhum hardware para acompanhar. Ao final, você entenderá como o barramento I2C funciona, como conectar dispositivos e como escrever código para escaneá-los.

Vamos mergulhar!

Montagem do Circuito

Diagrama do circuito do scanner I2C no canvas do simulador Velxio

O circuito é refrescantemente simples. Precisamos apenas de dois componentes:

Detalhes da Conexão

Conecte o OLED ao Arduino usando quatro fios:

Pino do ArduinoPino do OLEDCor do Fio
A4 (SDA)DATAAzul
A5 (SCL)CLKLaranja
GNDGNDPreto
5VVINVermelho

Nota: No Arduino Uno, A4 e A5 são os pinos I2C dedicados. Outras placas podem usar pinos diferentes (ex.: SDA/SCL em um ESP32).

No simulador Velxio, você pode adicionar o OLED pelo seletor de componentes e conectá-lo clicando nos pinos. A barra de ferramentas do canvas ajuda a ampliar e navegar para facilitar as conexões.

Barra de ferramentas do canvas Velxio acima da viewport de simulação

Explicação do Código

Código-fonte do scanner I2C no editor Monaco do Velxio

Agora vamos ver o código. Abra o editor de código no Velxio (você verá o editor Monaco com realce de sintaxe). O sketch é escrito em Arduino C++ e usa a biblioteca Wire embutida.

Incluindo a Biblioteca

#include <Wire.h>

A biblioteca Wire lida com toda a comunicação I2C de baixo nível. Ela já vem incluída com a IDE Arduino, então nenhuma instalação extra é necessária.

Função Setup

void setup() {
  Wire.begin();
  Serial.begin(9600);

  Serial.println("===========================");
  Serial.println("  Scanner do Barramento I2C (TWI)");
  Serial.println("===========================");
  Serial.println("Escaneando...");
  Serial.println();

  int dispositivosEncontrados = 0;

  for (byte addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    byte erro = Wire.endTransmission();

    if (erro == 0) {
      Serial.print("  Dispositivo encontrado em 0x");
      if (addr < 16) Serial.print("0");
      Serial.print(addr, HEX);

      // Identifica endereços conhecidos
      switch (addr) {
        case 0x27: Serial.print("  (Backpack LCD PCF8574)"); break;
        case 0x3C: Serial.print("  (OLED SSD1306)"); break;
        case 0x48: Serial.print("  (Sensor de temperatura)"); break;
        case 0x50: Serial.print("  (EEPROM)"); break;
        case 0x68: Serial.print("  (RTC DS1307)"); break;
        case 0x76: Serial.print("  (Sensor BME280)"); break;
        case 0x77: Serial.print("  (BMP180/BMP280)"); break;
      }
      Serial.println();
      dispositivosEncontrados++;
    }
  }

  Serial.println();
  Serial.print("Escaneamento concluído. ");
  Serial.print(dispositivosEncontrados);
  Serial.println(" dispositivo(s) encontrado(s).");

  if (dispositivosEncontrados == 0) {
    Serial.println("Nenhum dispositivo I2C encontrado. Verifique as conexões.");
  }
}

Vamos detalhar:

  1. Wire.begin() – Inicializa o Arduino como mestre I2C.
  2. Serial.begin(9600) – Inicia a comunicação serial a 9600 baud para vermos os resultados no Monitor Serial.
  3. O loop itera pelos endereços de 1 a 126 (0x01 a 0x7E). O endereço 0 é reservado para chamada geral, e 127 é reservado para fins especiais.
  4. Wire.beginTransmission(addr) – Inicia uma transmissão para o endereço fornecido.
  5. Wire.endTransmission() – Finaliza a transmissão e retorna um código de erro. Se o erro for 0, significa que o dispositivo reconheceu (ACK) — encontramos um dispositivo!
  6. Imprimindo o endereço – Imprimimos em formato hexadecimal com zero à esquerda para legibilidade.
  7. Comando switch – Identifica dispositivos comuns por seus endereços conhecidos. Isso é opcional, mas útil.
  8. Contando dispositivos – Incrementamos dispositivosEncontrados para cada ACK.
  9. Relatório final – Imprime o número total de dispositivos encontrados.

Função Loop

void loop() {
  // Reescaneia a cada 10 segundos
  delay(10000);
  Serial.println("\nReescaneando...");
  setup();
}

A função loop() simplesmente espera 10 segundos e então chama setup() novamente para reescaneamento. Isso é útil se você adicionar ou remover dispositivos enquanto o sistema está em execução.

Conceitos-Chave para Estudantes

O que é I2C?

I2C (Inter-Integrated Circuit), também chamado de TWI (Two-Wire Interface), é um protocolo de comunicação serial síncrona. Ele usa duas linhas bidirecionais de dreno aberto: SDA (dados) e SCL (clock). Cada dispositivo no barramento tem um endereço único de 7 bits (embora existam endereços de 10 bits). O mestre (Arduino) inicia a comunicação e gera o sinal de clock.

Como o Scanner Funciona

O scanner envia uma condição de início seguida pelo byte de endereço (endereço de 7 bits + bit de leitura/escrita). Se um dispositivo com esse endereço existir, ele responde com um ACK (reconhecimento) puxando SDA para baixo durante o nono pulso de clock. Se nenhum dispositivo responder, um NACK (não reconhecimento) é recebido, e endTransmission() retorna um código de erro diferente de zero.

Por que Usar um Scanner?

Armadilhas Comuns e Dicas de Depuração

  1. Fiação errada – Verifique novamente se SDA e SCL estão conectados corretamente. Trocá-los não funcionará.
  2. Falta de resistores de pull-up – As linhas I2C precisam de resistores de pull-up (tipicamente 4,7kΩ) para VCC. Muitas placas de desenvolvimento os incluem, mas se você estiver montando do zero, não os esqueça.
  3. Conflitos de endereço – Se dois dispositivos compartilham o mesmo endereço, nenhum funcionará de forma confiável. Use o scanner para detectar conflitos.
  4. Incompatibilidade de taxa de transmissão – O scanner usa o padrão de 100 kHz (modo padrão). Alguns dispositivos podem precisar de velocidades mais lentas. Você pode alterar com Wire.setClock(400000) para modo rápido.
  5. Monitor Serial não mostrando saída – Certifique-se de que a taxa de transmissão no Monitor Serial corresponde a 9600.

No Velxio, você pode abrir o Monitor Serial pela barra de ferramentas do editor. Se não vir a saída, verifique se o código compilou com sucesso (procure por erros no console).

Barra de ferramentas do editor Velxio com controles de compilar e executar

Extensões Sugeridas

Depois que o scanner básico estiver funcionando, tente estas melhorias:

Para adicionar bibliotecas no Velxio, use o Gerenciador de Bibliotecas.

Modal do Gerenciador de Bibliotecas Velxio listando bibliotecas Arduino instaladas

Conclusão

Você acabou de construir um scanner I2C universal que funciona com qualquer placa compatível com Arduino. Esta ferramenta é inestimável para depurar e explorar novos módulos I2C. A melhor parte? Você pode executá-lo agora mesmo no seu navegador no Velxio, sem nenhum hardware.

Pronto para testar você mesmo? Abra o exemplo ao vivo e comece a escanear:

👉 Inicie o Scanner I2C no Velxio

Feliz programação!


Compartilhar em:
David Montero

Escrito por

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

Artigos relacionados


Artigo anterior
Relógio RTC I2C com DS1307 no Velxio
Próximo artigo
Controle Serial de LED com Arduino: Envie Comandos para Piscar