Tutorial · Principiante · 30 min de lectura

Cómo funciona el bus I2C: direcciones y resistencias pull-up

Dos cables y un bus compartido: para qué sirven las resistencias pull-up, por qué apilar placas breakout bloquea el bus y cómo resolver conflictos de dirección.

Introducción

Todas las páginas de sensores de este sitio te dicen que conectes SDA y SCL, y ninguna te dice qué están haciendo esos dos cables. La mayoría de las veces no necesitas saberlo — lo cableas, la biblioteca funciona y el sensor lee.

Después añades una segunda placa y la primera deja de responder. O la biblioteca devuelve ceros sin ningún error. O dos dispositivos resulta que quieren la misma dirección y nada en la documentación dice qué hacer al respecto.

Todo eso son los mismos pocos hechos sobre I²C, y hay menos de los que sugieren los síntomas.

Dos cables, muchos dispositivos

I²C coloca todos los dispositivos sobre un mismo par de cables compartidos:

  • SDA — la línea de datos.
  • SCL — el reloj, lo maneja siempre el controlador.

En un Arduino Uno esas son A4 y A5 (y los pines duplicados junto a AREF — los mismos dos pines, no unos extra). Cada dispositivo se conecta a los mismos dos, en paralelo. No hay cable de selección de chip ni anillo: añadir un dispositivo significa soldarlo al mismo par.

Por eso escala tan bien para robots. Un MPU-6050, un VL53L0X y un PCA9685 comparten los dos cables y se distinguen por dirección, no por cableado.

Nadie lleva la línea a nivel alto

Este es el hecho del que se deriva todo lo demás.

Un dispositivo I²C solo puede llevar una línea a nivel bajo. No puede manejarla a nivel alto — la salida es drenador abierto, lo que significa que es un interruptor a masa y nada más. Sin nadie que la maneje, la línea flotaría a un voltaje indeterminado.

Las resistencias pull-up son lo que lleva la línea a nivel alto. No son una medida de robustez ni un extra opcional: son la mitad del circuito, y sin ellas el bus no tiene estado en reposo y nada funciona.

El drenador abierto tiene una ventaja real, y por eso se hace así: si dos dispositivos hablan a la vez, uno llevando la línea a nivel bajo y otro soltándola, el resultado es un nivel bajo. Nada compite, nada se cortocircuita, y el dispositivo que perdió puede detectarlo. En un bus donde cualquier dispositivo puede hablar, eso importa.

La ventana en la que tiene que vivir un pull-up

Hay límites por los dos lados, y son calculables.

Demasiado bajo y ningún dispositivo puede llevar la línea hacia abajo. La especificación exige que un dispositivo absorba al menos 3 mA mientras mantiene la línea por debajo de 0,4 V, así que:

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

Demasiado alto y el flanco de subida es demasiado lento. La línea sube según una curva RC contra la capacitancia del bus, y el reloj no espera:

t_rise ≈ 0.85 × R × C        ≤ 1000 ns at 100 kHz, ≤ 300 ns at 400 kHz
Gráfico en escala logarítmica de la resistencia pull-up admisible frente a la capacitancia total del bus. Dos curvas descendentes marcan el techo de tiempo de subida para 100 kilohertz y 400 kilohertz, y una línea roja horizontal en 1533 ohmios marca el suelo por debajo del cual ningún dispositivo puede absorber corriente suficiente para llevar la línea a nivel bajo. Cuatro líneas discontinuas horizontales marcan la resistencia efectiva de una, dos, tres y cuatro placas breakout apiladas a 4700, 2350, 1567 y 1175 ohmios; la línea de cuatro placas cae por debajo del suelo.
La banda utilizable está entre el suelo de corriente de absorción y el techo de tiempo de subida. Fíjate en dónde queda 400 kHz en un bus muy cargado: a partir de unos 250 pF su techo baja del suelo, así que ahí el modo rápido no es alcanzable ni con resistencias simples. Descargar SVG

Ahora la parte que pillan por sorpresa. Casi todas las placas breakout de hobby ya traen sus propias resistencias pull-up, normalmente de 4,7 kΩ. Si cableas varias al mismo bus, esas resistencias quedan en paralelo:

Placas en el bus Pull-up efectivo Veredicto
1 4700 Ω Bien
2 2350 Ω Bien
3 1567 Ω Al límite — 34 Ω por encima del suelo
4 1175 Ω Por debajo del suelo

Así que el fallo tiene una forma concreta: un sensor funciona, dos funcionan, tres funcionan en un buen día, y la cuarta placa detiene el bus entero. No hay nada roto. Simplemente los dispositivos ya no pueden llevar la línea bastante abajo para que se lea como un nivel bajo.

La solución es quitar las resistencias pull-up de todas las placas menos una — suelen ser dos resistencias en montaje superficial marcadas 472, y la documentación de la placa indica cuáles. Desoldarlas parece errado la primera vez y es la respuesta correcta.

Escanea el bus antes de depurar nada más

Antes de tocar una biblioteca, pregúntale al bus qué hay en él. Este sketch prueba todas las direcciones e informa de cuáles contestan:

#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() {}

El resultado te dice qué problema tienes:

  • No contesta nada → cableado, alimentación o pull-up ausentes. No es la biblioteca.
  • El dispositivo contesta en una dirección inesperada → un pin de selección de dirección está configurado de forma distinta a lo que asumiste.
  • El dispositivo contesta, pero la biblioteca devuelve ceros → el bus está bien y el problema está por encima de él.

Esa última línea vale por todo el sketch. Separa limpiamente «el cable está mal» de «el código está mal», que de otro modo es la mayor parte del tiempo de depuración.

Direcciones, y la confusión del 0xD0

Una dirección I²C es de 7 bits. Dieciséis valores están reservados, quedan 112 usables.

Aquí está la trampa. En el cable, la dirección se envía como siete bits seguidos de un bit de lectura/escritura, así que parece un valor de 8 bits. Las hojas de datos citan con frecuencia esa forma de 8 bits. La biblioteca Wire de Arduino quiere la forma de 7 bits.

La hoja de datos de un MPU-6050 dice que su dirección es 0xD0 para escritura y 0xD1 para lectura. La biblioteca Wire quiere 0x68:

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

Si un dispositivo no contesta en la dirección impresa en su hoja de datos, prueba ese valor desplazado un bit a la derecha antes de concluir que la placa está muerta. Es el error de I²C más habitual que existe.

Cuando dos dispositivos quieren la misma dirección

Las direcciones las fija el fabricante, así que las colisiones son rutinarias. Tres soluciones, por orden de cuánto te van a gustar:

1. Un pin de selección de dirección. La solución más barata, cuando la pieza lo tiene. Un MPU-6050 está en 0x68, o en 0x69 con su pin AD0 llevado a nivel alto — así que dos de ellos conviven con un solo cable. Un PCA9685 tiene seis puentes de soldadura que dan 64 direcciones, y por eso puedes encadenar hasta 62 placas en un bus.

2. Mantener los demás en reset mientras reasignas uno. Algunas piezas tienen dirección fija pero se pueden reprogramar en tiempo de ejecución. Un VL53L0X es siempre 0x29 de fábrica, y esta es la forma estándar de hacer funcionar varios: mantén el pin XSHUT de cada sensor a nivel bajo, levanta uno, dile que pase a una dirección nueva y repite. La nueva dirección vive en RAM, así que la secuencia se repite en cada arranque.

3. Un multiplexor. Un TCA9548A es un dispositivo en 0x70 con ocho buses conmutados detrás. Selecciona un canal, habla con el dispositivo que hay en él, selecciona el siguiente. Es la respuesta para ocho sensores idénticos sin pin de selección y sin reasignación de direcciones — al coste de una pieza, y de que el bus funciona de uno en uno.

Velocidad, longitud y lo que realmente se rompe

I²C se diseñó para correr entre chips de una misma placa. Un robot lo estira a lo largo de un chasis, y ahí es donde los límites empiezan a morder.

  • La capacitancia es el límite real, no la longitud. La especificación permite 400 pF en total. Un cable plano añade aproximadamente 50–100 pF por metro, y cada dispositivo añade unos 10 pF. Los tendidos largos fallan por hacer el flanco de subida demasiado lento — que es lo que la figura de arriba muestra como techo cayendo.
  • Baja la velocidad antes de rendirte. Wire.setClock(50000) reduce a la mitad la velocidad estándar y compra margen real en un bus al límite. Un robot que consulta un sensor a 100 Hz no necesita 400 kHz.
  • Mantén SDA y SCL separadas. Carryarlas como un par adyacente en un cable plano acopla los flancos del reloj hacia los datos. Un hilo de masa entre ellas ayuda.
  • Clock stretching. Un dispositivo que necesite tiempo puede mantener SCL a nivel bajo, y el controlador debe esperar. El hardware I²C real lo contempla; algunas implementaciones por software no, y el síntoma es un dispositivo que funciona solo y corrompe los datos cuando el bus está ocupado.
  • Un bus bloqueado. Si un dispositivo se reinició a mitad de una transferencia puede quedarse sujetando SDA a nivel bajo para siempre, y cualquier escaneo devuelve nada. Pulsar SCL nueve veces le deja terminar el byte que creía estar enviando y soltar la línea — que es lo que hace la rutina de recuperación de una buena biblioteca.

Mezclar 3,3 V y 5 V

Un ESP32 y una Raspberry Pi ejecutan su I²C a 3,3 V; un Uno lo ejecuta a 5 V. Como el bus es de drenador abierto, la tensión del pull-up decide el nivel alto para todos los que están en él. Haz el pull-up a 5 V con una pieza de solo 3,3 V conectada y estás metiendo 5 V en un pin que solo admite 3,6 V.

Dos cosas te salvan casi siempre, y conviene saber en cuál te estás apoyando:

  • Muchos breakouts «compatibles con 5 V» son un chip de 3,3 V con un regulador y desplazamiento de niveles ya en la placa. Compruébalo antes de asumir — la sola presencia de un regulador de tensión no significa que los pines de señal estén protegidos.
  • Donde no sea así, un desplazador de niveles bidireccional con MOSFET es la respuesta estándar. Un divisor de tensión no lo es: rompe el comportamiento de drenador abierto justo en la dirección que importa.

Cuando va mal

Síntoma Normalmente
El escáner no encuentra absolutamente nada Pull-up ausentes, SDA/SCL intercambiados o sin masa común
Funcionaba con tres placas, muere con cuatro Pull-up en paralelo por debajo del suelo de corriente de absorción
Dispositivo ausente en la dirección de su hoja de datos Dirección citada en 8 bits; desplaza un bit a la derecha
Dos sensores idénticos, solo uno contesta Colisión de direcciones — pin de selección, XSHUT o un multiplexor
Lee bien en corto, falla con un cable largo Capacitancia del bus; baja la velocidad del reloj o acorta el tendedido
Corrupción intermitente mientras giran los motores Ruido de alimentación — mira alimentación y caídas de tensión
El escáner de repente devuelve nada tras un fallo Un dispositivo bloqueado sujetando SDA a nivel bajo; pulsa SCL nueve veces
Funciona solo, corrompe cuando el bus está ocupado Clock stretching que el controlador no respeta

El hábito útil es ejecutar el escáner primero, siempre, antes de abrir el código fuente de una biblioteca. Lleva treinta segundos y parte el problema por la mitad — y la mitad de toda la depuración de I²C es no saber de qué lado del cable está el fallo.

Explora el grafo

Forma parte de estos montajes

Proyectos y rutas de aprendizaje que incluyen este tutorial.

Lecturas adicionales

Referencias