Volver

Escáner I2C con Arduino: Encuentra todos los dispositivos en el bus

Introducción

¿Alguna vez has conectado un nuevo sensor o pantalla I2C a tu Arduino y te has preguntado: “¿Qué dirección usa este dispositivo?” ¡No estás solo! El protocolo I2C es una forma potente de comunicarse con múltiples dispositivos usando solo dos cables, pero cada dispositivo tiene una dirección única, y a veces esa dirección no es obvia en la hoja de datos. Ahí es donde entra un escáner I2C. Es un sketch simple que sondea todas las direcciones posibles e informa cuáles responden.

En este tutorial, construiremos un escáner I2C usando un Arduino Uno y una pantalla OLED SSD1306 (que también sirve como dispositivo conocido en el bus). Ejecutaremos todo dentro del simulador en navegador Velxio, por lo que no necesitas ningún hardware para seguir el proceso. Al final, entenderás cómo funciona el bus I2C, cómo cablear dispositivos y cómo escribir código que los escanee.

¡Vamos a ello!

Recorrido del Circuito

Diagrama del circuito del escáner I2C en el lienzo del simulador Velxio

El circuito es sorprendentemente simple. Solo necesitamos dos componentes:

Detalles del Cableado

Conecta la OLED al Arduino usando cuatro cables:

Pin ArduinoPin OLEDColor del Cable
A4 (SDA)DATAAzul
A5 (SCL)CLKNaranja
GNDGNDNegro
5VVINRojo

Nota: En el Arduino Uno, A4 y A5 son los pines I2C dedicados. Otras placas pueden usar pines diferentes (por ejemplo, SDA/SCL en un ESP32).

En el simulador Velxio, puedes añadir la OLED desde el selector de componentes y cablearla haciendo clic en los pines. La barra de herramientas del lienzo te ayuda a hacer zoom y desplazarte para facilitar las conexiones.

Barra de herramientas del lienzo de Velxio sobre la ventana de simulación

Explicación del Código

Código fuente del escáner I2C en el editor Monaco de Velxio

Ahora veamos el código. Abre el editor de código en Velxio (verás el editor Monaco con resaltado de sintaxis). El sketch está escrito en Arduino C++ y usa la librería integrada Wire.

Incluyendo la Librería

#include <Wire.h>

La librería Wire maneja toda la comunicación I2C de bajo nivel. Viene incluida con el IDE de Arduino, por lo que no es necesaria ninguna instalación adicional.

Función Setup

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

  Serial.println("===========================");
  Serial.println("  Escáner del Bus I2C (TWI)");
  Serial.println("===========================");
  Serial.println("Escaneando...");
  Serial.println();

  int devicesFound = 0;

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

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

      // Identificar direcciones conocidas
      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();
      devicesFound++;
    }
  }

  Serial.println();
  Serial.print("Escaneo completado. ");
  Serial.print(devicesFound);
  Serial.println(" dispositivo(s) encontrado(s).");

  if (devicesFound == 0) {
    Serial.println("No se encontraron dispositivos I2C. Verifica las conexiones.");
  }
}

Vamos a desglosarlo:

  1. Wire.begin() – Inicializa el Arduino como maestro I2C.
  2. Serial.begin(9600) – Inicia la comunicación serie a 9600 baudios para poder ver los resultados en el Monitor Serie.
  3. El bucle itera a través de las direcciones 1 a 126 (0x01 a 0x7E). La dirección 0 está reservada para llamada general y la 127 para propósitos especiales.
  4. Wire.beginTransmission(addr) – Inicia una transmisión a la dirección dada.
  5. Wire.endTransmission() – Finaliza la transmisión y devuelve un código de error. Si el error es 0, significa que el dispositivo respondió con ACK (reconocimiento) – ¡encontramos un dispositivo!
  6. Imprimir la dirección – La imprimimos en formato hexadecimal con un cero inicial para facilitar la lectura.
  7. Sentencia switch – Identifica dispositivos comunes por sus direcciones conocidas. Esto es opcional pero útil.
  8. Contar dispositivos – Incrementamos devicesFound por cada ACK.
  9. Informe final – Imprime el número total de dispositivos encontrados.

Función Loop

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

La función loop() simplemente espera 10 segundos y luego llama a setup() de nuevo para reescanear. Esto es útil si añades o quitas dispositivos mientras el sistema está en funcionamiento.

Conceptos Clave para Estudiantes

¿Qué es I2C?

I2C (Inter-Integrated Circuit), también llamado TWI (Two-Wire Interface), es un protocolo de comunicación serie síncrono. Utiliza dos líneas bidireccionales de drenaje abierto: SDA (datos) y SCL (reloj). Cada dispositivo en el bus tiene una dirección única de 7 bits (aunque existen direcciones de 10 bits). El maestro (Arduino) inicia la comunicación y genera la señal de reloj.

Cómo Funciona el Escáner

El escáner envía una condición de inicio seguida del byte de dirección (dirección de 7 bits + bit de lectura/escritura). Si existe un dispositivo con esa dirección, responde con un ACK (reconocimiento) poniendo SDA en bajo durante el noveno pulso de reloj. Si ningún dispositivo responde, se recibe un NACK (no reconocimiento) y endTransmission() devuelve un código de error distinto de cero.

¿Por Qué Usar un Escáner?

Errores Comunes y Consejos de Depuración

  1. Cableado incorrecto – Verifica que SDA y SCL estén conectados correctamente. Intercambiarlos no funcionará.
  2. Falta de resistencias de pull-up – Las líneas I2C necesitan resistencias de pull-up (típicamente 4.7kΩ) a VCC. Muchas placas de expansión las incluyen, pero si construyes desde cero, no las olvides.
  3. Conflictos de dirección – Si dos dispositivos comparten la misma dirección, ninguno funcionará de manera fiable. Usa el escáner para detectar conflictos.
  4. Velocidad de baudios incorrecta – El escáner usa 100 kHz por defecto (modo estándar). Algunos dispositivos pueden necesitar velocidades más lentas. Puedes cambiarlo con Wire.setClock(400000) para modo rápido.
  5. El Monitor Serie no muestra salida – Asegúrate de que la velocidad de baudios en el Monitor Serie coincida con 9600.

En Velxio, puedes abrir el Monitor Serie desde la barra de herramientas del editor. Si no ves salida, verifica que el código se haya compilado correctamente (busca errores en la consola).

Barra de herramientas del editor de Velxio con controles de compilación y ejecución

Extensiones Sugeridas

Una vez que tengas el escáner básico funcionando, prueba estas mejoras:

Para añadir librerías en Velxio, usa el Gestor de Librerías.

Ventana del Gestor de Librerías de Velxio mostrando librerías de Arduino instaladas

Conclusión

Acabas de construir un escáner I2C universal que funciona con cualquier placa compatible con Arduino. Esta herramienta es invaluable para depurar y explorar nuevos módulos I2C. ¿La mejor parte? Puedes ejecutarlo ahora mismo en tu navegador en Velxio sin ningún hardware.

¿Listo para probarlo tú mismo? Abre el ejemplo en vivo y comienza a escanear:

👉 Inicia el Escáner I2C en Velxio

¡Feliz hacking!


Compartir en:
David Montero

Escrito por

David Montero

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

GitHub velxio.dev

Artículos relacionados


Artículo anterior
Reloj RTC I2C con DS1307 en Velxio
Artículo siguiente
Control de LED por Serie con Arduino: Envía Comandos para Parpadear