← Índice del curso

Comunicación entre Dispositivos · Tema 19 · I²C

Problemas reales en I²C

En un banco de pruebas, con un sensor y cuatro cables cortos, I²C funciona a la primera. En un proyecto real aparecen los problemas: cables más largos de lo previsto, un sensor que se toma su tiempo para contestar, dos módulos con la misma dirección y, sobre todo, ese bus que un buen día queda mudo después de reiniciar la placa. Vamos a ver las cinco situaciones más frecuentes (capacidad, estiramiento del reloj, direcciones repetidas, multiplexores y bus bloqueado), por qué ocurren y cómo se resuelven.

01 · Del banco de pruebas a la realidad

Cuando el bus real no es el del libro

I²C es un bus tolerante pero no mágico. Sus virtudes (pocos hilos, direcciones, colector abierto) se pagan con límites que en un montaje chico no se notan y en uno real sí. Casi todas las fallas de un bus I²C que ya funcionó alguna vez caen en una de estas cinco familias:

Los cinco problemas del tema, con su síntoma típico.
ProblemaCausa de fondoSíntoma típico
Capacidad excesivaDemasiado cable o demasiados dispositivos para la pull-up elegidaFunciona a 100 kHz y falla a 400; falla al agregar un módulo
Estiramiento del relojUn esclavo mantiene SCL en bajo para ganar tiempoLecturas lentas, errores o cuelgues con un maestro que no lo espera
Direcciones repetidasDos dispositivos con la misma direcciónEl barrido muestra una sola dirección; los datos salen mezclados
Falta de direcciones libresMuchos dispositivos iguales o con direcciones en conflictoNo hay forma de configurar direcciones distintas
Bus bloqueadoUn esclavo quedó a mitad de un byte reteniendo SDATodo deja de responder; SDA queda en bajo en reposo

Los cinco tienen salida. Algunos se resuelven en el diseño (cuentas de capacidad, elección de componentes y de direcciones), otros con un componente adicional (un multiplexor) y el último con una rutina de software que conviene tener siempre en el arranque.

02 · El límite que se olvida

Capacidad y longitud

En el tema 16 vimos que el tiempo de subida es tr = 0,8473 · R · Cb y que la especificación limita Cb a 400 pF (550 pF en el modo rápido plus). Lo que se pasa por alto es de dónde sale ese Cb: es la suma de todo lo que está pegado a la línea, y cada elemento aporta lo suyo:

Aporte típico de cada elemento a la capacidad de una línea (órdenes de magnitud).
ElementoCapacidad aproximada
Pin de un dispositivo I²C5 a 10 pF cada uno
Pista de circuito impresodel orden de 1 pF por centímetro
Conectorunos pocos pF
Cable de cinta o cable multipolar50 a 100 pF por metro
Par trenzadounos 50 pF por metro

Con estos números se hace el presupuesto: Cb = Cfija + n · Cdispositivo + L · Ccable. Por ejemplo, con 5 dispositivos de 8 pF, 10 pF de pistas y conectores, y 0,5 m de cable de cinta de 100 pF/m, queda 10 + 40 + 50 = 100 pF. Del otro lado está lo que admite la pull-up: Cmáx = tr,máx / (0,8473 · R). En modo rápido (300 ns) con 2,2 kΩ son 161 pF; con 4,7 kΩ, solo 75 pF. De ahí sale la longitud máxima del cable:

Lmáx = (Cmáx − Cfija − n · Cdispositivo) / Ccable

Con 5 dispositivos, 10 pF fijos y cable de 80 pF/m: en modo estándar con 4,7 kΩ (Cmáx = 251 pF) caben unos 2,5 m; en modo rápido con 2,2 kΩ (161 pF), 1,4 m; en modo rápido con 1 kΩ (354 pF), unos 3,8 m; y en modo rápido con los 4,7 kΩ «de costumbre» (75 pF), apenas 0,3 m. El cable largo no es un problema de «distancia» sino de capacidad, y se compra bajando la resistencia hasta el límite que permite la corriente de los dispositivos (Rmín).

Cuando la cuenta no cierra, las salidas son:

  • Acortar el bus y ubicar los dispositivos lo más juntos posible. Es lo más barato.
  • Bajar la pull-up dentro del rango válido (recordá el piso de Rmín).
  • Bajar el modo de velocidad. Con más tiempo permitido (1000 ns en el estándar), la misma capacidad pasa a ser aceptable.
  • Partir el bus con un multiplexor (sección 05): cada canal es un tramo con su propia capacidad, y solo se carga el tramo activo.
  • Usar un buffer o un extensor de bus (como el P82B715), que aísla la capacidad de cada lado y permite cables de decenas de metros, o un extensor diferencial (como el PCA9615) para distancias mayores y entornos ruidosos.
  • Separar SDA de SCL en un cable de cinta, con un conductor de masa entre ambas (SCL – masa – SDA): se evita que los flancos rápidos de SCL se acoplen a SDA y provoquen datos erróneos o falsos START y STOP.

Una cuestión relacionada es la conexión en caliente y los dispositivos sin alimentación. Un chip apagado cuyas entradas tienen diodos de protección hacia su VDD puede sujetar las líneas del bus cerca de masa; una placa apagada, conectada por I²C a una encendida, puede dejar el bus inutilizable. Los dispositivos «a prueba de eso» existen, pero conviene que todo lo que comparte el bus se alimente a la vez, o aislarlo con un buffer o un multiplexor.

03 · El esclavo pide tiempo

El estiramiento del reloj

Estiramiento del reloj El maestro suelta SCL esperando que suba, pero el esclavo la mantiene en bajo un tiempo más. SCL sube recién cuando el esclavo la suelta, y solo entonces el maestro continúa con el pulso siguiente. SCL que quiere el maestroSCL real en el cable el esclavo retiene SCL en bajo el maestro ya soltó SCL SCL sube recién acá el maestro continúa

Normalmente el maestro maneja SCL, pero la especificación permite una excepción: un esclavo que necesita más tiempo (porque está terminando una conversión, atendiendo una interrupción o preparando el dato) puede mantener SCL en bajo después de que el maestro la soltó. Es el estiramiento del reloj (clock stretching). Es posible gracias al colector abierto de SCL (tema 16): el maestro suelta la línea, pero si el esclavo sigue bajándola, la línea sigue en bajo.

La regla para el maestro es simple y obligatoria: después de soltar SCL, tiene que verificar que realmente subió antes de seguir con el flanco siguiente. Si no lo hace, avanza con un reloj que el esclavo todavía no liberó, y los bits se leen o se envían a destiempo. Qué pasa en la práctica depende del maestro:

  • Periféricos de hardware. La mayoría esperan SCL sin que el programa haga nada (el TWI de los AVR, los controladores del ESP32 y del STM32). El ESP32 tiene un tiempo máximo configurable; con Wire.setTimeOut(ms) se limita cuánto espera.
  • Maestros por software. Hay que escribir la espera: después de soltar(SCL), un bucle que lee el pin hasta verlo en alto, con un límite de tiempo (la función soltarSclYEsperar de la sección 07). Un maestro simple que solo hace una pausa fija pierde datos con los esclavos que estiran.
  • Maestros con un defecto conocido. El periférico I²C de la Raspberry Pi (el BCM2835 y sus derivados) tiene un error en el manejo del estiramiento: con sensores que lo usan intensamente (se conocen casos como el BNO055) hay lecturas corruptas. La solución habitual es usar I²C por software (bit-banging) o bajar la velocidad.

El estiramiento tiene dos consecuencias para el diseño:

  • Baja la velocidad efectiva del bus. Si cada byte se retiene 50 µs, en un mensaje de 6 bytes a 400 kHz (135 µs ideales) se pierden 300 µs: la transferencia dura 435 µs y el reloj efectivo cae a unos 124 kHz. Un bus «a 400 kHz» con un esclavo que estira mucho puede rendir menos que uno a 100.
  • Un esclavo trabado deja el bus colgado. Si un esclavo retiene SCL y nunca la suelta, el maestro que espera sin límite se cuelga también. Por eso toda espera de SCL tiene un tiempo máximo, y al agotarse el programa debe reaccionar (reiniciar el esclavo, recuperar el bus).

Los esclavos que estiran se pueden reconocer en la hoja de datos (buscar «clock stretching») o, si no, porque una captura con analizador lógico muestra SCL con fases bajas más largas que las del maestro, precisamente en los límites de byte.

04 · Dos con el mismo nombre

Direcciones repetidas

Cuando dos dispositivos tienen la misma dirección, el maestro les habla a ambos a la vez. Las consecuencias son consistentes con lo que vimos del colector abierto:

  • En una escritura, los dos reciben los mismos bytes y los dos confirman: si lo que se les escribe es una configuración, ambos quedan configurados igual, y si el maestro quería hablar con uno solo, el otro se entera.
  • En una lectura, los dos responden al mismo tiempo, y como la línea es un Y cableado, el maestro ve el AND bit a bit de ambas respuestas. Con 0xB6 (1011 0110) y 0x4D (0100 1101) llega 0x04 (0000 0100); basta que uno ponga un 0 para que el bit llegue en 0. No hay error de protocolo: todo está confirmado y los datos son basura plausible.
  • El barrido muestra una sola dirección, de modo que el conflicto pasa inadvertido hasta que los datos no tienen sentido.

La forma de evitarlo es no tener dos dispositivos con la misma dirección en el mismo tramo de bus. Hay varias maneras, de la más simple a la más pesada:

Maneras de resolver direcciones repetidas.
SoluciónCómo funcionaCuándo conviene
Cambiar la dirección con un pinMuchos chips tienen pines o puentes (ADDR, SDO, AD0, A0 a A2) que eligen entre dos o más direccionesDos o tres dispositivos iguales; es lo más simple (revisar antes de comprar)
Usar otra variante del componenteAlgunas familias tienen versiones con rangos distintos (PCF8574 en 0x20 a 0x27, PCF8574A en 0x38 a 0x3F)Cuando faltan combinaciones de pines
Cambiar la dirección por softwareAlgunos chips permiten programar su dirección tras el arranque (el VL53L0X, que arranca con un pin XSHUT: se lo despierta de a uno y se le asigna una dirección nueva a cada uno)Varios sensores iguales que lo soportan
Un segundo busMuchos microcontroladores tienen dos controladores I²C (el ESP32: Wire y Wire1 con pines distintos)Pocos conflictos y pines disponibles
Un multiplexor I²CUn integrado (TCA9548A) que conecta un canal a la vez; los dispositivos repetidos se ponen en canales distintosMuchos dispositivos idénticos, o tramos con distinta tensión
Alimentar de a unoLos dispositivos se encienden por turnos con un interruptor de potenciaÚltimo recurso; complica la secuencia

La regla de diseño: listar las direcciones de todos los dispositivos antes de armar el circuito (con sus alternativas por pines) y detectar los choques sobre el papel. Cambiar un diseño después de soldado es mucho más caro.

05 · Muchos tramos, un solo maestro

Multiplexores de bus

Multiplexor I²C TCA9548A El maestro se conecta a un multiplexor con ocho canales. Cada canal es un tramo de bus independiente con sus propias pull-ups. Dos sensores con la misma dirección 0x76 se conectan a canales distintos, y el maestro conecta un solo canal por vez. MaestroSDA · SCL TCA9548Adirección 0x708 canales canal 0canal 1canal 2canal 3 BME2800x76BME2800x76SSD13060x3CBH17500x23 con su propia pull-up misma dirección que el canal 0 tramo de 3,3 V o de 5 V cada canal es un bus aparte El maestro escribe un byte al multiplexor: cada bit activa un canal. Con un solo canal conectado no hay conflicto.

Un multiplexor I²C como el TCA9548A (o su pariente PCA9548A) tiene un lado conectado al maestro y ocho canales independientes. Es un conjunto de interruptores controlado por el propio bus: el multiplexor tiene una dirección I²C (de 0x70 a 0x77, según tres pines) y un registro de control de un byte donde cada bit conecta o desconecta un canal. Se maneja con un mensaje de escritura de un solo dato:

S 0xE0(W) A máscara A P  (multiplexor en 0x70; el bit n de la máscara conecta el canal n)

Por ejemplo, 0x01 conecta el canal 0, 0x04 conecta el canal 2, 0x00 los desconecta a todos, y 0x03 conecta los canales 0 y 1 a la vez. Leer el multiplexor devuelve la máscara actual. Después de elegir un canal, el resto de la comunicación es la de siempre: los mensajes al dispositivo que está en ese canal pasan «transparentes» por el multiplexor, sin cambiar ninguna dirección.

Qué resuelve:

  • Direcciones repetidas. Dos sensores 0x76 en canales distintos no se ven entre sí: se conecta el canal 0, se lee el primero; se conecta el canal 1, se lee el segundo. Con ocho canales y hasta ocho multiplexores (0x70 a 0x77) se llega a 64 dispositivos idénticos.
  • Capacidad. Cada canal es un tramo con sus propias pull-ups y su propia capacidad; solo la del canal activo se suma a la del maestro. Es una manera de pasar de un bus de 600 pF (inválido) a varios de 100 pF.
  • Tensiones distintas. Los canales son interruptores pasivos, y cada tramo puede tener su pull-up a su tensión (1,8 V, 3,3 V o 5 V) siempre que el integrado soporte todas. Hace de desplazador de nivel (tema 16).
  • Aislamiento de fallas. Un dispositivo que cuelga su canal no afecta a los demás mientras ese canal esté desconectado. El multiplexor tiene una entrada de reinicio (RESET, activa en bajo) que desconecta todos los canales y permite recuperar el bus principal.

Y los puntos a tener en cuenta:

  • Cada cambio de canal es un mensaje más: dos bytes (18 pulsos), unos 45 µs a 400 kHz y 180 µs a 100 kHz. En un ciclo de lectura de muchos sensores se suma.
  • El multiplexor mismo ocupa una dirección (0x70 a 0x77), que no puede coincidir con la de ningún dispositivo.
  • Un barrido desde el maestro no ve los canales apagados. Para descubrir qué hay conectado hay que barrer cada canal por separado (sección 07).
  • Conectar dos canales a la vez los junta eléctricamente: se suman las capacidades y, si hay una dirección repetida, el conflicto vuelve. Lo habitual es un solo canal por vez.
  • Al reiniciar el multiplexor (por RESET o por falta de energía) todos los canales quedan desconectados y hay que volver a elegir el canal. Un programa que lo asumió activo lee «nadie» de golpe.

06 · El peor día

El bus bloqueado

El síntoma es inconfundible: el programa funcionaba, se reinició la placa (por un corte de energía, por el perro guardián o por cargar un programa nuevo) y ahora ningún dispositivo responde. El barrido informa 112 respuestas o ninguna, endTransmission() devuelve errores o el programa queda colgado en una llamada de Wire. Midiendo con el bus en reposo, SDA está en bajo.

La causa es la siguiente. Un esclavo que estaba enviando un byte al maestro (una lectura en curso) no sabe que el maestro se reinició. Sigue esperando los pulsos de reloj que faltan para terminar el byte. Si el bit que le tocaba enviar era un 0, mantiene SDA en bajo, y el maestro, al arrancar, ve la línea ocupada: no puede generar un START porque necesita que SDA esté en alto. Lo mismo ocurre con ruidos que interrumpen un mensaje, o con un maestro que se cae a mitad de una transferencia.

Recuperación de un bus bloqueado SDA está retenida en bajo por un esclavo que quedó a mitad de un byte. El maestro genera pulsos de SCL uno a uno. Tras el quinto pulso el esclavo suelta SDA, que sube. Entonces el maestro baja SDA con SCL en bajo, sube SCL y después SDA, generando una condición de STOP que deja el bus libre. SCLSDA 12345 SDA retenida en bajo por el esclavo el esclavo suelta STOP bus libre

La solución está en la especificación y se llama recuperación del bus (bus clear): el maestro, que controla SCL, genera pulsos de reloj hasta que el esclavo termine su byte y suelte SDA. Como un byte tiene 8 bits más la confirmación, nueve pulsos son siempre suficientes. El procedimiento es:

  1. Soltar SDA y SCL y mirar SCL. Si SCL está en bajo, los pulsos no sirven: algo la retiene (un esclavo trabado con estiramiento, un cortocircuito); la única salida es reiniciar el esclavo o cortarle la alimentación.
  2. Mientras SDA esté en bajo, hasta un máximo de 9 veces: bajar SCL, soltarla (esperando que suba, por el estiramiento) y volver a mirar SDA.
  3. Cuando SDA sube, el esclavo soltó la línea. Si después de 9 pulsos sigue en bajo, hay un cortocircuito o un dispositivo averiado: pulsos de reloj no resuelven eso.
  4. Generar una condición de STOP (bajar SDA con SCL baja, subir SCL y subir SDA) para que todos los esclavos den por terminado el mensaje.
  5. Reinicializar el controlador I²C (Wire.begin()) y retomar.

Cuántos pulsos hacen falta depende de en qué bit estaba el esclavo: los bits restantes del byte que valgan 0 mantienen SDA baja hasta que el esclavo pasa el último. Un esclavo que había enviado 0x00 y estaba en el bit 3 necesita 5 pulsos; uno que estaba en el primer bit de un 0x00 necesita 8. Si el bit actual ya es un 1, SDA estaba en alto y no hay bloqueo.

Algunas medidas preventivas:

  • Recuperar el bus siempre al arrancar. Es una rutina corta (sección 07) que no cuesta nada y evita el caso más típico: reiniciar la placa con el sensor encendido.
  • Poner un tiempo máximo a todo. En AVR, Wire.setWireTimeout(3000, true) evita que una línea retenida cuelgue el programa para siempre (con el segundo argumento en true, el controlador se reinicia al agotarse el tiempo); en ESP32, Wire.setTimeOut(ms). Sin tiempos máximos, un bus bloqueado puede dejar la placa colgada.
  • Un pin de reinicio o de alimentación por dispositivo, o un multiplexor con RESET, para poder reiniciar un esclavo que no responde.
  • Proteger la alimentación (condensadores de desacople y un regulador con margen): una caída de tensión momentánea es una causa frecuente de esclavos que quedan en estados raros.
  • Contar los errores y, tras unos cuantos seguidos, ejecutar la recuperación en lugar de reintentar indefinidamente.

07 · Con el microcontrolador

Con el microcontrolador

El primer programa implementa la recuperación del bus a mano, con las funciones de colector abierto del tema 16 (bajar y soltar). Incluye la espera de SCL que necesita un maestro frente a un esclavo que estira el reloj, y devuelve un código que dice qué pasó. Se llama antes de Wire.begin().

#include <Wire.h>

const byte PIN_SDA = 21;
const byte PIN_SCL = 22;
const unsigned int MEDIO_US = 5;

inline void bajar(byte pin)  { pinMode(pin, OUTPUT); digitalWrite(pin, LOW); }
inline void soltar(byte pin) { pinMode(pin, INPUT); }          // la pull-up externa sube la línea
inline void medio()          { delayMicroseconds(MEDIO_US); }

// Suelta SCL y espera a verla en alto: un esclavo puede estirar el reloj. false si se pasa del límite.
bool soltarSclYEsperar(unsigned long limiteUs) {
    soltar(PIN_SCL);
    unsigned long t0 = micros();
    while (!digitalRead(PIN_SCL)) {
        if (micros() - t0 > limiteUs) return false;
    }
    return true;
}

// 0 = bus libre, 1 = SCL retenida (los pulsos no sirven), 2 = SDA sigue retenida tras 9 pulsos
byte recuperarBus() {
    soltar(PIN_SDA); soltar(PIN_SCL); medio();
    if (!digitalRead(PIN_SCL)) return 1;
    for (byte i = 0; i < 9 && !digitalRead(PIN_SDA); i++) {   // hasta 9 pulsos, mientras SDA esté en bajo
        bajar(PIN_SCL); medio();
        if (!soltarSclYEsperar(1000)) return 1;
        medio();
    }
    if (!digitalRead(PIN_SDA)) return 2;
    // STOP: SDA baja con SCL baja, SCL sube y recién entonces sube SDA
    bajar(PIN_SCL); medio();
    bajar(PIN_SDA); medio();
    if (!soltarSclYEsperar(1000)) return 1;
    medio();
    soltar(PIN_SDA); medio();
    return 0;
}

void setup() {
    Serial.begin(115200);
    switch (recuperarBus()) {
        case 0: Serial.println("Bus libre"); break;
        case 1: Serial.println("SCL retenida: reiniciar o desalimentar el esclavo"); break;
        case 2: Serial.println("SDA sigue en bajo tras 9 pulsos: cortocircuito o dispositivo averiado"); break;
    }
    Wire.begin(PIN_SDA, PIN_SCL);
    Wire.setTimeOut(100);               // ESP32: límite de espera en ms (en AVR: Wire.setWireTimeout(3000, true))
}

void loop() {}

El segundo programa maneja un multiplexor TCA9548A en 0x70: elige un canal, lee el registro de identificación de un BME280 (0xD0, valor 0x60) en dos canales distintos que usan la misma dirección 0x76, y hace un barrido por canal para descubrir qué hay detrás de cada uno.

#include <Wire.h>

const byte MUX = 0x70;

bool seleccionarMascara(byte mascara) {                 // el bit n conecta el canal n
    Wire.beginTransmission(MUX);
    Wire.write(mascara);
    return Wire.endTransmission() == 0;
}
bool seleccionarCanal(byte canal) { return seleccionarMascara((uint8_t)(1 << canal)); }
bool desconectarTodos()           { return seleccionarMascara(0); }

bool probar(byte dir) {                                 // S dir+W [A/N] P
    Wire.beginTransmission(dir);
    return Wire.endTransmission() == 0;
}

int leerId(byte dir) {                                  // registro de identificación 0xD0 (BME280: 0x60)
    Wire.beginTransmission(dir);
    Wire.write((uint8_t)0xD0);
    if (Wire.endTransmission(false) != 0) return -1;
    if (Wire.requestFrom(dir, (uint8_t)1) != 1) return -1;
    return Wire.read();
}

void barridoPorCanal() {
    for (byte canal = 0; canal < 8; canal++) {
        if (!seleccionarCanal(canal)) { Serial.println("El multiplexor no contesta"); return; }
        for (byte dir = 0x08; dir <= 0x77; dir++) {
            if (dir == MUX) continue;                   // la dirección del propio multiplexor
            if (probar(dir)) {
                Serial.print("canal "); Serial.print(canal);
                Serial.print(": 0x"); Serial.println(dir, HEX);
            }
        }
    }
    desconectarTodos();
}

void setup() {
    Serial.begin(115200);
    Wire.begin();
    for (byte canal = 0; canal < 2; canal++) {          // dos BME280 con la misma dirección 0x76
        seleccionarCanal(canal);
        int id = leerId(0x76);
        Serial.print("canal "); Serial.print(canal);
        Serial.print(": ID = 0x"); Serial.println(id, HEX);   // 0x60 en ambos
    }
    barridoPorCanal();
}

void loop() {}

Dos observaciones. En barridoPorCanal se salta la dirección del multiplexor, porque contesta en cualquier canal. Y las dos lecturas de identificación dan el mismo valor en cada canal porque son el mismo modelo: el multiplexor no «renombra» los dispositivos, solo decide con cuál habla el maestro en cada momento; para saber cuál es cuál hay que llevar la cuenta del canal.

08 · Analogía con programación

Los problemas del bus en Python

Cada problema del tema se puede reducir a unas pocas líneas de modelo. El programa siguiente calcula el presupuesto de capacidad y la longitud de cable máxima, el efecto del estiramiento sobre la velocidad real, el resultado de leer dos dispositivos con la misma dirección (el AND de los bytes), la recuperación de un bus bloqueado con el conteo de pulsos y el barrido de un multiplexor con cuatro canales.

Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.

import math

K = math.log(0.7 / 0.3)
hexa = lambda b: f"{b:#04x}"


def cmax_pf(tr_ns, r):
    return tr_ns / (K * r * 1e-3)


def largo_max(tr_ns, r, n, c_disp=8, c_fija=10, c_m=80):
    return (cmax_pf(tr_ns, r) - n * c_disp - c_fija) / c_m


def velocidad_efectiva(f_hz, n_bytes, estirar_us):
    pulsos = 9 * n_bytes
    ideal = pulsos / f_hz * 1e6
    real = ideal + n_bytes * estirar_us
    return ideal, real, pulsos / (real * 1e-6)


class EsclavoEnviando:
    """Esclavo en medio de un byte: mantiene SDA según el bit actual (0 = retiene)."""
    def __init__(self, valor, bit):
        self.bits = [(valor >> (7 - i)) & 1 for i in range(8)]
        self.i = bit

    def sda(self):
        return self.bits[self.i] if self.i < 8 else 1     # tras el octavo bit suelta SDA para la confirmación

    def pulso(self):
        self.i += 1


def recuperar(esclavo, maximo=9):
    pulsos = 0
    while esclavo.sda() == 0 and pulsos < maximo:
        esclavo.pulso()
        pulsos += 1
    return esclavo.sda() == 1, pulsos


class Mux:
    def __init__(self, canales):
        self.canales = canales                            # una lista de conjuntos de direcciones por canal
        self.mascara = 0

    def barrido(self):
        direcciones = [0x70]                              # el propio multiplexor siempre contesta
        for i, canal in enumerate(self.canales):
            if self.mascara >> i & 1:
                direcciones += sorted(canal)
        return sorted(direcciones)


print("Capacidad máxima y largo de cable (5 dispositivos de 8 pF, 10 pF fijos, cable de 80 pF/m):")
for nombre, tr, r in (("estándar, 4,7 kΩ", 1000, 4700), ("rápido, 2,2 kΩ", 300, 2200), ("rápido, 1 kΩ", 300, 1000), ("rápido, 4,7 kΩ", 300, 4700)):
    print(f"  {nombre:17}: {cmax_pf(tr, r):4.0f} pF -> {largo_max(tr, r, 5):.2f} m")

ideal, real, efectiva = velocidad_efectiva(400e3, 6, 50)
print(f"\nEstiramiento: 6 bytes a 400 kHz con 50 µs por byte: {ideal:.0f} µs ideales, {real:.0f} µs reales, {efectiva / 1e3:.0f} kHz efectivos")

print("\nDos dispositivos con la misma dirección responden a la vez (Y cableado):")
for a, b in ((0xB6, 0x4D), (0xA5, 0x5A)):
    print(f"  {hexa(a)} & {hexa(b)} = {hexa(a & b)}")

print("\nRecuperación del bus (valor que enviaba el esclavo, bit actual, pulsos permitidos):")
for valor, bit, maximo in ((0x00, 3, 9), (0x80, 1, 9), (0xA5, 3, 9), (0xFF, 4, 9), (0x00, 0, 9), (0x00, 0, 4)):
    libre, pulsos = recuperar(EsclavoEnviando(valor, bit), maximo)
    print(f"  {hexa(valor)}, bit {bit}, máximo {maximo}: {pulsos} pulsos -> {'libre' if libre else 'SIGUE BLOQUEADO'}")

print("\nMultiplexor con 4 canales (0: BME280, 1: BME280, 2: SSD1306, 3: BH1750):")
mux = Mux([{0x76}, {0x76}, {0x3C}, {0x23}])
for mascara in (0b0000, 0b0001, 0b0011, 0b0100, 0b1111):
    mux.mascara = mascara
    vistas = mux.barrido()
    repetidas = sorted({d for d in vistas if vistas.count(d) > 1})
    print(f"  máscara {mascara:04b}: {[hexa(d) for d in vistas]}" + (f"  CONFLICTO en {[hexa(d) for d in repetidas]}" if repetidas else ""))

Resultado: con 5 dispositivos, 10 pF fijos y cable de 80 pF/m, el modo estándar con 4,7 kΩ admite 251 pF y 2,51 m; el rápido con 2,2 kΩ, 161 pF y 1,39 m; el rápido con 1 kΩ, 354 pF y 3,80 m; y el rápido con 4,7 kΩ, solo 75 pF y 0,32 m. Con un esclavo que estira 50 µs por byte, un mensaje de 6 bytes a 400 kHz pasa de 135 µs a 435 µs y el reloj efectivo cae a 124 kHz. Dos dispositivos con la misma dirección entregan el AND de sus bytes: 0xb6 & 0x4d = 0x04 y 0xa5 & 0x5a = 0x00. En la recuperación, un esclavo con 0x00 en el bit 3 necesita 5 pulsos, uno con 0x80 en el bit 1 necesita 7, uno con 0xA5 en el bit 3 necesita solo 2 (los bits 3 y 4 son 0, el 5 es 1), uno con 0xFF no estaba bloqueando (0 pulsos) y el peor caso, 0x00 desde el primer bit, necesita 8; con un límite de 4 pulsos el mismo caso sigue bloqueado. El multiplexor desconectado muestra solo 0x70; con el canal 0 aparece 0x76; con los canales 0 y 1 la dirección 0x76 aparece dos veces (conflicto); con el canal 2, la 0x3c; y con los cuatro, 0x23 0x3c 0x70 0x76 0x76 con el conflicto del 0x76.

Observá que ninguna de estas fallas produce un error explícito: el AND de dos dispositivos sale con ACK, el estiramiento solo se nota en el tiempo y el bus bloqueado en el síntoma de «todo mudo». Se detectan con verificaciones y con medidas, no esperando una excepción.

09 · Exploración interactiva

Laboratorio: capacidad, reloj, bloqueo y multiplexor

El laboratorio tiene cuatro herramientas. La primera es un presupuesto de capacidad: elegís el modo, la pull-up, la cantidad de dispositivos y el cable, y ves si el bus cumple y cuánto cable queda. La segunda muestra el efecto del estiramiento del reloj sobre el tiempo y la velocidad real, con un maestro que espera y uno que no. La tercera es un simulador de bus bloqueado: elegís el byte y el bit donde quedó el esclavo y probás la recuperación con distinta cantidad de pulsos. La cuarta es un multiplexor TCA9548A con cuatro canales.

1. Presupuesto de capacidad

Capacidad total del bus—
Capacidad que admite la pull-up—
Tiempo de subida · límite del modo—
Largo de cable máximo—
Veredicto—

Elegí los parámetros del bus.

2. Estiramiento del reloj

Duración ideal—
Duración real—
Reloj efectivo—
Veredicto—

Elegí el mensaje y cuánto estira el esclavo.

3. Bus bloqueado y recuperación

SDA antes—
Pulsos generados—
Después—
Veredicto—

Elegí qué retiene el bus y presioná «Recuperar el bus».

4. Multiplexor TCA9548A con cuatro canales

Detrás del multiplexor: canal 0, BME280 (0x76); canal 1, otro BME280 (0x76); canal 2, SSD1306 (0x3C); canal 3, BH1750 (0x23).

Mensaje al multiplexor—
Barrido desde el maestro—
Direcciones repetidas—
Veredicto—

Elegí qué canales conectar.

En la herramienta 1, la capacidad se calcula con 10 pF de pistas y conectores más 8 pF por dispositivo, y la resistencia mínima con 3 mA de corriente de bajada (20 mA en el rápido plus). En la 2, el estiramiento se suma una vez por byte. En la 3, el esclavo suelta SDA tras su octavo bit para la confirmación, y la rutina corta cuando SDA sube. En la 4, el barrido muestra siempre al multiplexor (0x70).

Recorrido guiado

  1. Con los valores iniciales (modo rápido, 2,2 kΩ, 5 dispositivos, 0,5 m de cinta), el bus tiene 100 pF y admite 161 pF. El tiempo de subida es de 186 ns (límite 300 ns): «Cumple». El largo máximo de cable es de unos 1,1 m.
  2. Estirá el cable a 2 m: 250 pF, la subida es de 466 ns y falla. Cambiá la pull-up a 1 kΩ: admite 354 pF, la subida es de 212 ns y vuelve a cumplir (con una corriente de 2,9 mA, justa para los 3 mA del dispositivo).
  3. Pasá la pull-up a 4,7 kΩ con el modo rápido: admite solo 75 pF; con los 5 dispositivos ya no hay lugar ni para un metro de cable. En el modo estándar el mismo 4,7 kΩ admite 251 pF.
  4. En la herramienta 2, con los valores iniciales (400 kHz, 6 bytes, 50 µs por byte), la transferencia ideal dura 135 µs, la real 435 µs, y el reloj efectivo cae a 124 kHz. Probá con 200 µs por byte: 1,33 ms y 40 kHz. A 100 kHz el mismo estiramiento pesa menos en proporción.
  5. Cambiá el maestro a «sigue sin mirar SCL» con un estiramiento mayor que cero: «Datos corruptos». El maestro lee los bits antes de que el esclavo termine de preparar los suyos. Con 0 µs no hay diferencia.
  6. En la herramienta 3, con el esclavo en 0xA5, bit 3, presioná «Recuperar el bus»: SDA está en bajo, hacen falta 2 pulsos (los bits 3 y 4 son 0, el 5 es 1) y el bus queda libre tras generar el STOP.
  7. Probá 00 en el bit 0: 8 pulsos, el peor caso, todavía dentro de los 9. Con la rutina limitada a 4 pulsos el mismo caso queda bloqueado. Con FF, SDA estaba en alto: no había bloqueo y no hace falta ningún pulso.
  8. Cambiá a «Un esclavo retiene SCL»: los pulsos no tienen efecto porque SCL no se puede mover; la solución es reiniciar o desalimentar el esclavo. Con «SDA en cortocircuito», tras los 9 pulsos SDA sigue en bajo: es un problema de hardware.
  9. En la herramienta 4, con la máscara 0x01, el barrido muestra 0x70 y 0x76. Con 0x03, la dirección 0x76 aparece dos veces: «Conflicto». Con 0x04 aparece solo la 0x3C. Con 0x00, solo el multiplexor.
Desafío: cuántos multiplexores para 20 sensores iguales

Con TCA9548A de 8 canales, 20 sensores con la misma dirección necesitan 20 canales: 3 multiplexores (24 canales) con direcciones 0x70, 0x71 y 0x72. Los tres cuelgan del mismo bus del maestro, que escribe la máscara al multiplexor que corresponda; hay que desconectar el canal activo del multiplexor anterior (máscara 0) antes de usar otro, porque si no dos sensores iguales quedarían conectados a la vez. Cada cambio cuesta 2 bytes (18 pulsos, 45 µs a 400 kHz).

10 · Un procedimiento

Diagnóstico de un bus que falla

Cuando un bus deja de funcionar, la tentación es cambiar código. Casi siempre es mejor mirar el bus. Un recorrido de ocho pasos, de lo más barato a lo más caro, localiza la mayoría de las fallas:

  1. Mirar SDA y SCL en reposo. Las dos deben estar en alto (el programa del tema 16 lo hace). Si alguna está en bajo, el bus está retenido: hay un bloqueo, un cortocircuito o un esclavo sin alimentación que sujeta la línea.
  2. Verificar las alimentaciones de todos los dispositivos y de las pull-ups, y que la masa sea común.
  3. Desconectar todo y reconectar de a uno. El dispositivo con el que el bus se rompe es el culpable (o el cable hacia él).
  4. Barrer el bus y comparar con las direcciones esperadas (tema 18).
  5. Ejecutar la recuperación del bus (sección 06). Si un reinicio previo lo bloqueó, se libera.
  6. Reducir la velocidad a 100 kHz. Si así funciona y a 400 kHz no, el problema es de capacidad o de pull-up.
  7. Capturar con un analizador lógico u osciloscopio y comparar con lo esperado: flancos de subida, nivel bajo, fases de SCL estiradas, falsos START, ACK ausentes (tema 17).
  8. Revisar el software: que haya tiempos máximos, que se comprueben los códigos de error y que la recuperación del bus se ejecute al arrancar.
Síntomas, causas probables y acciones.
SíntomaCausa probableAcción
SDA en bajo en reposo tras reiniciar la placaEsclavo a mitad de un byteRecuperar el bus con hasta 9 pulsos y un STOP
SCL en bajo en reposoEsclavo que estira el reloj y se colgó, o cortocircuitoReiniciar o desalimentar el esclavo; revisar el cableado
Falla al agregar un módulo o un cableCapacidad total sobre el límiteMedir y recalcular; bajar la pull-up o el modo; acortar
Los datos de dos sensores iguales salen mezcladosMisma dirección: AND de ambas respuestasCambiar dirección por pin o usar un multiplexor
Lecturas lentas o con errores aleatorios en un sensor determinadoEstiramiento del reloj mal soportado por el maestroRevisar la hoja de datos; usar I²C por software o bajar la velocidad
Todo funciona hasta conectar una placa apagadaDispositivo sin alimentación que sujeta las líneas por sus diodos de protecciónAlimentar todo a la vez o aislar con un buffer/multiplexor
Lecturas erróneas con cables largos o junto a motoresRuido y acoplamiento entre SDA y SCLSeparar con masa, blindar, usar par trenzado o un extensor diferencial
El programa se cuelga en una llamada de WireFalta de tiempo máximo con una línea retenidaConfigurar timeouts y ejecutar la recuperación

11 · Comprensión

Confusiones frecuentes

«Un cable largo no es problema si bajo la velocidad»

Ayuda, pero el límite está en el tiempo de subida (R · C), no solo en la frecuencia. Con el modo estándar se admite más capacidad (1000 ns en lugar de 300). Para cables realmente largos se necesita bajar la pull-up, aislar con un buffer o usar un extensor diferencial.

«El estiramiento del reloj es un error del esclavo»

Es una función prevista en la especificación. Lo que sí es un error es un maestro que no la respeta, o un esclavo que la usa y nunca suelta SCL.

«Con dos dispositivos con la misma dirección, el maestro lee el primero»

No hay «primero»: ambos responden a la vez y el maestro ve el AND de sus respuestas. No hay error de protocolo, y los datos son basura plausible.

«El multiplexor cambia las direcciones de los dispositivos»

No. Solo conecta o desconecta tramos. Los dispositivos conservan su dirección, y el maestro tiene que saber qué canal está activo para saber con cuál habla.

«Reiniciar el microcontrolador deja el bus como nuevo»

Reinicia al maestro, no a los esclavos. Un esclavo a mitad de un byte sigue esperando sus pulsos, y es la causa más frecuente de un bus bloqueado tras un reinicio.

«Nueve pulsos de reloj siempre recuperan el bus»

Solo si el esclavo retiene SDA a mitad de un byte. Si retiene SCL, los pulsos no se pueden generar, y si hay un cortocircuito, SDA sigue en bajo. En esos casos se necesita reiniciar el dispositivo o arreglar el hardware.

«Más pull-ups hacen el bus más robusto»

Cada pull-up adicional baja la resistencia total. Más allá del mínimo, los dispositivos no pueden llevar la línea a 0,4 V y el bus pierde nivel bajo. Hay un rango, no un «más es mejor».

«El barrido ve todos los dispositivos conectados»

Solo los que están en el tramo conectado. Detrás de un multiplexor con el canal apagado, o con direcciones repetidas, el barrido no ve o ve de menos.

12 · Práctica guiada

Predecí antes de comprobar

1. Presupuesto de capacidad

Un bus en modo rápido, con 8 dispositivos de 8 pF, 10 pF fijos y 1,5 m de cable de 80 pF/m, tiene una pull-up de 2,2 kΩ. ¿Cumple? Si no, ¿qué resistencia usarías?

Ver solución

Cb = 10 + 8 · 8 + 1,5 · 80 = 194 pF. La pull-up de 2,2 kΩ admite 161 pF: no cumple (subida de unos 362 ns). La resistencia máxima para 194 pF es 300 ns / (0,8473 · 194 pF) ≈ 1825 Ω, y la mínima, unos 967 Ω a 3,3 V. Sirve una de 1,2 kΩ o 1,5 kΩ.

2. El costo del estiramiento

Leés 14 bytes a 400 kHz de un esclavo que retiene SCL 100 µs en cada byte. ¿Cuánto tarda y cuál es el reloj efectivo?

Ver solución

Ideal: 14 · 9 = 126 pulsos = 315 µs. Estiramiento: 14 · 100 µs = 1400 µs. Total: 1715 µs. Reloj efectivo: 126 / 1715 µs ≈ 73 kHz, bastante menos que los 400 kHz configurados.

3. Pulsos de recuperación

Un esclavo enviaba el byte 0x0F (0000 1111) y el maestro se reinició cuando iba por el bit 1. ¿Cuántos pulsos hacen falta para liberar SDA?

Ver solución

Los bits 1, 2 y 3 valen 0 y el bit 4 vale 1. SDA está en bajo en el bit 1 y se libera al llegar al bit 4: 3 pulsos. Después se genera el STOP.

4. Dos sensores iguales

Dos dispositivos en la misma dirección responden con 0xC3 y 0x3C. ¿Qué lee el maestro y qué indica el ACK?

Ver solución

0xC3 & 0x3C = 1100 0011 & 0011 1100 = 0x00. El maestro lee ceros. El ACK es normal (los dos confirmaron y se superponen): no hay ninguna señal de error en el protocolo, solo datos sin sentido.

5. Doce sensores

Tenés 12 sensores idénticos. ¿Cuántos multiplexores TCA9548A hacen falta y cuánto se agrega al ciclo por cambios de canal, a 400 kHz, con un cambio por sensor?

Ver solución

12 canales: 2 multiplexores (16 canales), en 0x70 y 0x71. Cada cambio es un mensaje de 2 bytes = 18 pulsos; 12 cambios son 216 pulsos = 540 µs por ciclo a 400 kHz (a 100 kHz, 2,16 ms). Si se cambia de un multiplexor a otro, hay que desconectar primero el canal del anterior.

6. Un bus que no se recupera

Tras reiniciar, SDA está en bajo. La rutina de recuperación genera 9 pulsos y SDA sigue en bajo. ¿Qué concluís y qué hacés?

Ver solución

No es un esclavo a mitad de un byte (eso se resuelve con 9 pulsos): hay un cortocircuito a masa, un dispositivo averiado o uno sin alimentación que sujeta la línea. Se desconectan los dispositivos de a uno, se mide la resistencia de SDA a masa y se revisan las alimentaciones. Si SCL estuviera en bajo, los pulsos ni siquiera se podrían generar.

7. Cuelgues en Wire

Un programa se cuelga cada tanto en Wire.endTransmission() y solo se arregla cortando la alimentación del sensor. ¿Qué pasa y qué le agregarías?

Ver solución

Casi seguro el sensor retiene SCL (o SDA) y el maestro espera sin límite. Se agregan: un tiempo máximo a Wire (setTimeOut o setWireTimeout), la rutina de recuperación del bus tras un error y, si el sensor tiene un pin de reinicio o una alimentación conmutable, un reinicio del dispositivo cuando la recuperación no alcanza.

13 · Síntesis

Ideas para recordar

  • La capacidad del bus es la suma de todo lo conectado (pines, pistas, cable). La pull-up máxima sale de Rmáx = tr,máx / (0,8473 · Cb) y, de ahí, la longitud máxima de cable. Se arregla acortando, bajando la pull-up, bajando el modo, partiendo el bus o usando un buffer o un extensor diferencial.
  • Un esclavo puede estirar el reloj reteniendo SCL en bajo. El maestro tiene que esperar a ver SCL en alto antes de seguir y con un tiempo máximo. El estiramiento baja la velocidad efectiva del bus.
  • Dos dispositivos con la misma dirección responden a la vez, y el maestro ve el AND de sus datos, con ACK normal. El barrido muestra una sola dirección. Se evita con pines de dirección, otra variante, un segundo bus o un multiplexor.
  • Un multiplexor TCA9548A (0x70 a 0x77) conecta canales con un byte de máscara; cada canal es un tramo aparte (con su capacidad, sus pull-ups y, si se quiere, su tensión). Los dispositivos conservan su dirección y se usa un canal por vez.
  • Un bus bloqueado (SDA en bajo en reposo) suele deberse a un esclavo a mitad de un byte tras un reinicio del maestro. Se recupera con hasta 9 pulsos de SCL y un STOP. Si SCL está en bajo, o si SDA sigue en bajo tras 9 pulsos, el problema es otro: reiniciar el esclavo o revisar el hardware.
  • La recuperación del bus se ejecuta siempre al arrancar, y toda llamada al bus lleva un tiempo máximo.
  • Estas fallas no suelen producir errores explícitos: se detectan midiendo (reposo, flancos, tiempos) y con verificaciones (identificación, barrido, comparación con lo esperado).
  • Diagnóstico en orden: reposo, alimentaciones, dispositivos de a uno, barrido, recuperación, velocidad, captura y software.

¿Listo para el siguiente tema?

Antes de avanzar, calculá cuánto cable admite un bus en modo rápido con 6 dispositivos de 8 pF, 10 pF fijos, cable de 80 pF/m y pull-up de 1,5 kΩ; explicá por qué reiniciar el microcontrolador puede dejar el bus bloqueado y cuántos pulsos de reloj bastan para liberarlo; y decidí cómo conectarías cuatro sensores BME280 idénticos. (Para la primera: Cmáx = 300 ns / (0,8473 · 1500 Ω) ≈ 236 pF, y Lmáx = (236 − 10 − 48) / 80 ≈ 2,2 m.) Si podés justificar las tres respuestas, tenés los problemas reales de I²C bajo control.

En el próximo tema cerramos el bloque con un taller de I²C: un sensor, un reloj, una pantalla y una memoria compartiendo los mismos dos hilos.