← Índice del curso

Comunicación entre Dispositivos · Tema 48 · Depuración, selección y proyectos

Depurar comunicaciones

Tarde o temprano, un enlace no funciona, y el programa no dice por qué: el receptor no recibe nada, o recibe basura, o funciona diez minutos y se cuelga, o anda en la mesa y falla en el campo. Con un microcontrolador, la depuración con Serial.print alcanza para la lógica del programa, pero no para lo que pasa entre los dispositivos: allí hay cables, tensiones, tiempos y bits que el código no ve. Este tema es el método y las herramientas para verlos. Primero, cómo pensar: de abajo hacia arriba, una hipótesis por vez, partiendo el sistema por la mitad. Después, los instrumentos: el multímetro para la alimentación y los niveles, el osciloscopio para la forma de las señales, el analizador lógico para los bits y su decodificación (UART, I²C, SPI), y los sniffers para escuchar un bus sin intervenir. Se aprende a decodificar una UART a mano, a elegir la frecuencia de muestreo y el ancho de banda, a calcular las resistencias de elevación de un bus I²C, y se arma una tabla de síntomas y causas con los errores que de verdad ocurren. El tema incluye un espía para ESP32 que escucha el enlace del taller anterior y diagnostica cada trama, un decodificador en Python y cinco herramientas interactivas.

01 · Objetivo

Ver antes de suponer

La regla de oro de la depuración de comunicaciones es esta: nadie puede razonar con certeza sobre un enlace que no está viendo. El código dice qué se quiso enviar; el cable, qué se envió. Y el código del otro extremo dice qué se espera recibir, no qué llegó. Suponer («el cable debe estar bien», «la velocidad es la misma», «el sensor tiene la dirección 0x76») es la manera más cara de perder una tarde. Medir cuesta unos minutos, y cada medición descarta una familia entera de causas.

Las fallas de comunicación tienen una propiedad desagradable: los síntomas se parecen mucho entre sí. «No recibo nada» puede ser un cable cortado, la masa sin unir, una velocidad distinta, un pin mal configurado, un nivel de tensión incompatible, un receptor que no escucha o un emisor que no transmite. La depuración consiste en distinguirlas con el mínimo de mediciones, y para eso hay un método y un puñado de instrumentos.

02 · Pensar antes de medir

Un método: de abajo hacia arriba

Las capas de un enlace y el instrumento de cada una Siete niveles, de abajo hacia arriba. Alimentación y masa, que se miden con el multímetro. Nivel eléctrico, con el multímetro y el osciloscopio. Bits y tiempos, con el osciloscopio y el analizador lógico. Bytes, con el decodificador del analizador. Tramas, con el sniffer y el analizador de tramas. Protocolo, con los contadores y el registro del programa. Aplicación, con el registro y el depurador. Una flecha indica que se empieza por abajo. Qué se verificaCon qué se mira 7 · Aplicación: ¿el dato tiene sentido?6 · Protocolo: confirmaciones, tiempos, estados5 · Trama: inicio, largo, CRC, secuencia4 · Bytes: ¿los valores son los enviados?3 · Bits y tiempos: velocidad, formato, flancos2 · Nivel eléctrico: tensiones y forma1 · Alimentación y masa registro del programa, depuradorcontadores del programa, registro con marcas de tiemposniffer, analizador de tramasdecodificador del analizador lógicoanalizador lógico, osciloscopioosciloscopio, multímetromultímetro se empieza por abajo

El enlace es una pila de capas, y una falla en una capa baja se manifiesta como un síntoma en una alta: una masa sin unir produce bytes errados, que producen tramas con CRC incorrecto, que producen reintentos, que producen una lectura «que no llega». Si se empieza a revisar el protocolo y la falla está en la masa, se pierde el tiempo. Por eso el recorrido es de abajo hacia arriba, y cada capa se da por buena solo después de comprobarla:

  1. Alimentación y masa. ¿Los dos dispositivos tienen la tensión correcta? ¿Están unidas las masas? Con el multímetro: tensión de cada placa y continuidad entre las masas. Sin referencia común, las tensiones de las señales no significan nada.
  2. Nivel eléctrico. ¿La línea está en el nivel de reposo que corresponde (alto en una UART de 3,3 V, alto con resistencias en I²C, una diferencia mínima en RS-485)? ¿Cambia al transmitir? ¿Llega a los niveles lógicos (más de 2 V para un alto de 3,3 V, menos de 0,8 V para un bajo)?
  3. Bits y tiempos. ¿Hay actividad en la línea cuando el emisor transmite? ¿Cuánto dura el bit más corto? De ahí se deduce la velocidad real y se compara con la configurada.
  4. Bytes. ¿El decodificador, configurado con la velocidad y el formato esperados, muestra los bytes que se enviaron? Si no, el problema es de velocidad, formato, polaridad o ruido.
  5. Trama. ¿Los bytes forman tramas válidas (inicio, largo, CRC)? ¿En qué lugar se rompen?
  6. Protocolo. ¿Se confirma lo que se recibe? ¿Los tiempos de espera son adecuados? ¿Los contadores de los dos extremos cuadran (tema 47)?
  7. Aplicación. Recién acá se examina el significado de los datos: orden de bytes, escala, rangos (tema 46).

Cuatro hábitos acompañan al método y valen tanto como los instrumentos:

  • Una sola cosa a la vez. Si se cambian la velocidad, el cable y el programa a la vez y el enlace anda, no se sabe cuál de los tres era. Se cambia una variable, se prueba, se anota.
  • Partir por la mitad. Un sistema con A → cable → B se divide: ¿A transmite bien? (se mira la salida de A con un instrumento, sin B). ¿B recibe bien? (se le entrega una señal conocida desde una computadora). Un bucle de prueba (loopback: unir TX con RX del mismo dispositivo) verifica el pin, la configuración y el programa sin cable ni segundo dispositivo.
  • Reemplazar por algo que funcione. Una computadora con un adaptador USB–serie y un programa de terminal es un interlocutor de referencia: si el dispositivo conversa con ella y no con su par, la falla está en el par o en el cable.
  • Escribir lo que se ve. La captura, la medición, la hipótesis descartada. Las fallas intermitentes se resuelven con datos acumulados, no con la memoria.

03 · La caja de herramientas

Los instrumentos y para qué sirve cada uno

Instrumentos de depuración de comunicaciones.
InstrumentoRespondeNo ve
Multímetro¿Hay tensión? ¿Cuánto? ¿Hay continuidad en el cable y en la masa? ¿El reposo de la línea está en el nivel correcto?Nada que cambie rápido: un byte de 1 ms aparece como un valor promedio sin sentido
OsciloscopioLa forma real de la señal: niveles, flancos, ruido, rebotes, reflexiones, glitches. Mide tiempos y tensiones con precisiónPocos canales (2 o 4). No decodifica sin una función específica. Captura poco tiempo a la vez
Analizador lógicoLos ceros y unos de muchas líneas a la vez durante un tiempo largo, con decodificadores de UART, I²C, SPI, CAN y otros, y con disparo por condiciónLa forma analógica: un flanco lento, un nivel de 1,5 V o un rebote corto pueden pasar por un 0 o un 1 sin aviso
Adaptador USB–serie o USB–RS-485 en escuchaLos bytes que circulan por un enlace, en una computadora, con marca de tiempo (con la precisión de USB, de unos milisegundos)Los tiempos finos entre bytes y los niveles
Analizador de protocolo de red (Wireshark, tcpdump, el cliente MQTT en modo suscripción)Paquetes de Ethernet, Wi-Fi, TCP/IP, MQTT, BLE (con hardware adecuado)Lo que viaja cifrado, y la capa física
El propio programaContadores, estados, tiempos internos, valores de los campos. Un pin de depuración que cambia en eventos clave permite medir latenciasLo que el programa no sabe de sí mismo: una pausa del cable, una masa floja. Y perturba lo que mide (un Serial.print demora el ciclo)

Los instrumentos se complementan: el osciloscopio responde si la señal es eléctricamente sana; el analizador lógico, qué dicen los bits a lo largo de muchos mensajes; el sniffer, qué conversación hay; y los contadores del programa, qué piensa cada extremo. Un orden de uso muy práctico: el multímetro primero (dos minutos y descarta lo más tonto), después el analizador lógico (barato, versátil, decodifica), y el osciloscopio cuando el analizador dice «los bits llegan» pero el comportamiento sugiere un problema eléctrico (ruido, flancos lentos, reflexiones).

Con el multímetro, las comprobaciones mínimas que siempre conviene hacer antes de lo demás son: (1) la tensión de alimentación de cada placa, bajo carga (un cable USB fino o una fuente débil pueden caer a 4 V cuando transmite la radio); (2) la continuidad de la masa entre los dos extremos (con el cable puesto, resistencia casi nula); (3) la continuidad de cada señal de punta a punta, y que no haya continuidad entre dos señales distintas ni con la masa; (4) el reposo de la línea con el sistema en marcha pero sin transmitir: una UART de 3,3 V debe medir cerca de 3,3 V, no 0 ni 1,6 V (una línea a medias indica un pin flotante o dos transmisores peleando).

04 · La forma de la señal

El osciloscopio

El osciloscopio dibuja la tensión de una línea en función del tiempo, y de ese dibujo se leen cosas que ningún programa ve. Para una comunicación digital, las preguntas típicas son:

Qué se ve en un osciloscopio y qué significa.
Lo que se veQué indica
Un nivel alto que no llega a 3,3 V (por ejemplo, 2,4 V) o un bajo que no llega a 0 (0,8 V)Carga excesiva, dos salidas en conflicto, una resistencia de elevación o de adaptación mal elegida, o una caída por masa débil
Flancos redondeados, que tardan mucho en subirCapacidad grande con una resistencia de elevación alta (el caso típico del I²C), cable muy largo o salida lenta
Oscilaciones («ringing») y sobreimpulsos después de cada flancoCable largo sin terminar bien (reflexiones), inductancia del cable de tierra de la sonda, flancos demasiado rápidos para el cable (tema 43)
Pulsos cortos espurios («glitches») en el reposoInterferencia acoplada de otro cable, mala masa, una señal de un motor o de un relé
Ruido sobre un nivel estableAlimentación sucia, mala masa o poco filtrado; si es pequeño (decenas de milivoltios) no importa; si cruza el umbral, produce errores
Una línea en reposo a una tensión intermediaNadie la maneja (pin sin configurar o transmisor apagado sin resistencia de reposo) o dos manejándola a la vez
La señal con la polaridad invertidaBits de reposo en bajo: RS-232 (niveles negativos y positivos), o un adaptador que invierte
Un bit más ancho o más angosto que los demásUn error de reloj del transmisor, o un programa que demora entre bits

Para medir bien hay que respetar algunas reglas de uso que, ignoradas, producen imágenes que mienten:

  • Ancho de banda. Un osciloscopio recorta lo que supera su ancho de banda. Un flanco con un tiempo de subida tr tiene un contenido de frecuencias hasta aproximadamente 0,35 / tr; para verlo bien, el instrumento necesita al menos esa banda y, mejor, el doble. Un flanco de 5 ns pide 70 MHz como mínimo, y 140 MHz para medirlo con comodidad. Para una UART de 9600 baudios, con flancos de unas decenas de nanosegundos, sobra con un instrumento básico de 20 MHz; para un SPI de 20 MHz, hacen falta 100 MHz o más (herramienta 3).
  • La sonda. Se usa en la posición ×10 (reduce la carga: unos 10 MΩ y 10 a 15 pF frente a la línea) y se compensa con la señal de prueba del propio instrumento hasta que el pulso cuadrado salga cuadrado. El cable de tierra largo de la sonda forma una antena y una inductancia que dibuja oscilaciones que no existen: para señales rápidas se usa el resorte de tierra corto que trae la sonda, en vez del cable con pinza.
  • La base de tiempos y el disparo. Para ver un byte de 9600 baudios (1,04 ms) se usa una base de unos 200 µs por división; para una trama de 16 bytes (16,7 ms), unos 2 ms por división. El disparo se pone en el flanco de bajada del bit de inicio, en modo normal (espera el evento) o único (captura una vez), con el nivel en la mitad de la excursión. Un disparo mal puesto hace que la imagen salte y parezca ruido.
  • Masa. La masa de la sonda es la del osciloscopio, que normalmente está unida a la tierra de la red. Conectarla a un punto que no esté a masa del circuito produce un cortocircuito. Al medir equipos conectados a la red sin aislar, se usa una sonda diferencial o un transformador de aislación.

Un osciloscopio con función de decodificación serie (muchos modelos actuales la traen para UART, I²C y SPI) tiene lo mejor de los dos mundos para una captura corta: se ve la señal analógica y, encima, los bytes decodificados. Para capturas largas, en cambio, el analizador lógico es mejor: tiene más canales y más memoria.

05 · Ceros y unos, en abundancia

El analizador lógico

Un analizador lógico mira cada línea cada 1/fs segundos (su frecuencia de muestreo), compara la tensión con un umbral y guarda un 0 o un 1 en su memoria. El resultado es un diagrama de tiempos digital de varias líneas a la vez, que un programa decodifica según el protocolo que se le indique. Los modelos económicos (de 8 canales, con USB, de pocas decenas de euros) son suficientes para casi todo lo de este curso. Hay cinco parámetros que se eligen en cada captura:

  • Frecuencia de muestreo. Para decodificar una UART hacen falta al menos 4 muestras por bit; para medir bien los anchos, 10 o más. Con menos, un pulso corto puede perderse y el decodificador muestra errores que no existen (herramienta 3). El modelo en Python de la sección 11 lo muestra: una captura de 9600 baudios muestreada a 20 kHz (2,1 muestras por bit) todavía se decodifica en un caso ideal, pero a 15 kHz (1,6) ya da bytes incorrectos sin ningún aviso. Se prefiere 10 veces la velocidad, o más.
  • Memoria. Define cuánto tiempo se mira: muestras / fs. Con un millón de muestras a 1 MHz hay un segundo, 960 bytes de una UART a 9600. Subir la frecuencia de muestreo acorta la ventana; por eso se empieza con una frecuencia moderada, y se aumenta solo si hace falta.
  • Umbral. La tensión que separa un 0 de un 1. Para una lógica de 3,3 V suele ser 1,65 V; para 1,8 V, alrededor de 0,9 V. Muchos analizadores lo permiten ajustar; si está mal puesto, una señal de 1,8 V puede leerse como siempre 0. Un flanco lento o ruidoso cerca del umbral produce pulsos falsos (otra razón para mirarlo con el osciloscopio).
  • Disparo (trigger). Cuándo empieza a registrar. Se dispara por un flanco (la caída de CS en un SPI, el bit de inicio de una UART), por un patrón (el byte 0xA5) o por una secuencia. Sin disparo, se registra una ventana cualquiera y quizá se pierda lo interesante. Un truco muy usado: el programa baja un pin de depuración justo cuando detecta la falla, y el analizador dispara con ese pin; así queda registrado lo que pasó antes del error (el espía de la sección 10 tiene un pin así).
  • Los decodificadores. Se agregan sobre los canales: UART (velocidad, bits de datos, paridad, parada, polaridad), I²C (SDA y SCL), SPI (CS, SCLK, MOSI y MISO con el modo), CAN, 1-Wire, y otros. El resultado aparece como una capa de texto sobre las formas de onda: bytes, direcciones, ACK y NACK, errores marcados en rojo.

El analizador lógico tiene sus propias limitaciones, que hay que conocer para no ser engañado:

  • No ve la forma analógica. Un flanco que apenas llega al umbral aparece como un pulso perfecto, o no aparece. Si el decodificador muestra errores de manera intermitente y la señal «se ve limpia», el osciloscopio es el siguiente paso.
  • No ve lo que pasa entre muestras: un glitch de 20 ns pasa inadvertido a 1 MHz de muestreo, aunque sea suficiente para confundir al receptor real.
  • Carga la línea con una capacidad pequeña (varios picofaradios), que casi nunca importa pero sí en un bus I²C ya al límite.
  • Necesita la masa unida a la del circuito, como cualquier instrumento: sin ella, las mediciones no tienen referencia.
  • Registra durante un tiempo corto: para fallas que ocurren una vez por hora, se deja el sniffer de bytes (sección 8) y se usa el analizador lógico solo cuando se sabe cuándo falla.

06 · El caso más común

Decodificar una UART a mano

El byte 0xA5 en una UART 8N1 y dos relojes de muestreo La forma de onda del byte A5 con formato 8N1: línea en alto, bit de inicio en bajo, ocho bits de datos con el menos significativo primero, que son 1, 0, 1, 0, 0, 1, 0, 1, y un bit de parada en alto. En el carril superior, el receptor muestrea en la mitad de cada bit con la velocidad correcta y lee 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, que es el byte A5 con parada correcta. En el carril inferior, el receptor tiene un reloj 15 por ciento más lento: sus puntos de muestreo se van corriendo, salta el bit 3 y lee el byte D1 en lugar de A5. inicioD0D1D2D3D4D5D6D7parada Receptor con la velocidad correcta lee 0 · 1 0 1 0 0 1 0 1 · 1 → 0xA5 ✓ Receptor con el reloj 15 % lento (el muestreo se corre) lee 0 · 1 0 0 0 1 0 1 1 · 1 → 0xD1 ✗ (se salteó el bit D2 y los dos últimos puntos cayeron en la parada y en el reposo) Cada punto naranja es el instante en que el receptor mira la línea. El desajuste es exagerado para que se vea; en la práctica, la tolerancia total es del 2 al 3 %.

Dado un osciloscopio o un analizador sin decodificador, un byte de una UART se lee a mano en cuatro pasos:

  1. Medir el bit más corto. En una captura de bytes variados hay pulsos de un solo bit; el más angosto es un tiempo de bit. Si mide 104 µs, la velocidad es 1/104 µs ≈ 9615, o sea 9600 baudios. Se redondea a la velocidad estándar más cercana (1200, 2400, 4800, 9600, 19 200, 38 400, 57 600 o 115 200). Una medida que da 52 µs corresponde a 19 200 baudios, y una que da 208 µs, a 4800.
  2. Encontrar el inicio. La línea en reposo está en alto; el primer flanco de bajada es el comienzo del bit de inicio. Desde ahí, cada tiempo de bit trae un bit nuevo.
  3. Leer los datos. Se mira la línea en la mitad de cada bit. El primer bit es el menos significativo. En la figura, los ocho bits de datos son 1, 0, 1, 0, 0, 1, 0, 1: invertidos de orden (el primero es el bit 0) dan 10100101 = 0xA5.
  4. Comprobar la parada. Después de los bits de datos (y de la paridad, si la hay) la línea tiene que estar en alto. Si está en bajo, es un error de encuadre: el receptor está desfasado, la velocidad es otra o hay un corte.

El carril inferior de la figura muestra por qué una velocidad mal configurada produce basura: el receptor mira la línea en instantes cada vez más corridos respecto de los bits reales. Hacia el final del byte, el error acumulado supera medio bit, y el receptor lee un bit que no es el que corresponde. Con 10 bits por byte, el límite teórico es de ±5 %; con los errores de los osciladores de ambos lados, se considera seguro menos de ±2 a 3 %. Muchos microcontroladores generan los baudios dividiendo un reloj, y algunas velocidades (115 200 desde ciertos relojes) salen con un error de 2 a 3 %; por eso, cuando se combinan dos chips distintos, a veces conviene elegir una velocidad cuyo error sea menor (herramienta 2).

Qué dicen los datos mal leídos de una UART.
Lo que se veCausa probable
Nada: ningún byte, la línea siempre en altoEl emisor no transmite (pin mal configurado, programa detenido) o el instrumento está en una línea equivocada. Un flanco de bajada nunca llega
Muchos errores de encuadre y bytes 00 o FFLa línea está en bajo permanentemente (cortocircuito a masa, transmisor roto o sin alimentar) o la polaridad está invertida
Bytes casi correctos, con bits sueltos erradosVelocidad apenas distinta, ruido, o 7 bits contra 8 bits de datos
Bytes completamente distintos, con muchos errores de encuadreVelocidades muy diferentes (el doble, la mitad), o un formato distinto (paridad, bits de parada)
Los bytes salen con los bits en espejo (0x41 se lee 0x82)Orden de bits invertido: una UART transmite el menos significativo primero; un decodificador configurado al revés (o una implementación por software con ese error) los invierte
Errores de paridad en bytes aisladosRuido (un solo bit cambiado es justo lo que detecta la paridad), o el emisor y el receptor no usan el mismo tipo de paridad
Texto con símbolos raros («Â°C» en vez de «°C»)No es un problema de la UART: es la codificación de caracteres (UTF-8 contra una página de códigos, tema 46)

07 · Con reloj

I²C y SPI: qué se ve y qué falla

Los buses con reloj (temas 12 a 20) son más fáciles de leer que una UART, porque el reloj dice cuándo mirar cada bit, y por eso los decodificadores del analizador rara vez se equivocan. Lo que sí hacen es mostrar claramente qué falta. Para cada uno, lo que conviene mirar:

I²C

Una transacción es: condición de inicio (SDA baja con SCL alta), un byte con los siete bits de dirección y el bit de lectura o escritura, un noveno bit de confirmación a cargo del esclavo (ACK si baja SDA, NACK si la deja en alto), los bytes de datos con su ACK, y la condición de parada. Para leer un registro de un BME280 en la dirección 0x76 es: S · EC A · D0 A · Sr · ED A · 60 N · P (la dirección de escritura es 0x76 << 1 = 0xEC, la de lectura 0xED). La herramienta 4 genera la secuencia para cualquier dirección y calcula el tiempo.

Síntomas de I²C vistos en un analizador.
Lo que se veCausa probableQué hacer
NACK en el byte de direcciónNadie contesta a esa dirección: dirección equivocada, dispositivo sin alimentar, mal cableado, o confusión de formato (la hoja de datos da la dirección de 8 bits, 0xEC, y la biblioteca espera la de 7, 0x76)Comparar la dirección en el decodificador con la de la hoja de datos; recorrer todas las direcciones (un «escáner I²C»)
NACK en un byte de datosEl esclavo no acepta el dato (registro inexistente, escritura en un registro de solo lectura) o no está listoRevisar el mapa de registros
SDA o SCL nunca suben, o suben muy despacioFaltan las resistencias de elevación, son demasiado altas, o la capacidad del bus es grande. Los flancos de subida deben terminar en menos de 1000 ns a 100 kHz y 300 ns a 400 kHzCalcular R y C (herramienta 4); bajar la velocidad; acortar el cable
SDA queda en bajo para siempre (bus colgado)El esclavo quedó a mitad de un byte, por ejemplo después de un reinicio del maestro, y sigue esperando relojes para terminarloDar hasta 9 pulsos de reloj por SCL hasta que SDA se libere, y mandar una condición de parada
Datos correctos pero a veces corruptosRuido, flancos lentos que cruzan el umbral en el momento equivocado, o un cable largoMirar con el osciloscopio; reforzar la elevación
SCL se mantiene en bajo un ratoEl esclavo estira el reloj (clock stretching) mientras prepara el dato. Es legal, pero algunos maestros por software no lo respetanVerificar que el maestro lo soporte

SPI

En SPI no hay confirmaciones: un esclavo sordo no avisa. Lo que se ve son cuatro líneas: CS (que baja al inicio y sube al final de cada transacción), SCLK, MOSI y MISO. Los errores típicos son de configuración, y se reconocen por el aspecto de los datos:

Síntomas de SPI.
Lo que se veCausa probable
MISO siempre en 0xFF (o siempre 0x00)El esclavo no responde: CS no baja (o baja en el canal equivocado), MISO desconectado (flotante, con elevación o con bajada), esclavo sin alimentar
Los datos llegan corridos un bit o con ruidoModo SPI equivocado: la polaridad del reloj (CPOL) o la fase (CPHA) no coinciden. Con un analizador, se compara en qué flanco cambia MISO y en cuál se muestrea (tema 13)
El primer byte leído es basura y el resto, bienUna lectura SPI devuelve la respuesta al byte anterior; hace falta enviar un byte de relleno para recibir el primero válido
Funciona a baja velocidad y falla a altaCables largos, reflexiones o un esclavo que no alcanza esa velocidad: el reloj sube más rápido de lo que la línea responde
Con dos esclavos, uno responde malDos CS bajos a la vez, o un esclavo que no libera MISO (alta impedancia) cuando no está seleccionado (tema 14)
Los bits salen en orden inversoSe configuró el orden de bits (MSB primero o LSB primero) al revés

Para ambos buses, una técnica útil es la captura de referencia: grabar una transacción que sí funciona (con una biblioteca probada, o con la computadora) y compararla con la que falla. Las diferencias de longitud, de orden, de tiempos o de datos señalan el problema mucho más rápido que mirar el código.

08 · Oír sin hablar

Sniffers: escuchar sin intervenir

Un sniffer es un dispositivo que escucha un enlace sin participar en él y muestra lo que circula. La clave es que sea pasivo: no transmite, no confirma, no carga la línea más de lo imprescindible. Si el sniffer altera el enlace (por ejemplo, contestando un ACK que nadie le pidió), la falla que se persigue puede desaparecer o convertirse en otra. Según el medio:

Cómo escuchar cada medio.
MedioCómo se escuchaPrecauciones
UART de 3,3 VUn adaptador USB–serie (o un segundo puerto de un microcontrolador, sección 10) con su RX conectado en paralelo a la línea que se quiere ver, y la masa comúnNunca conectar el TX del adaptador a la línea. Una UART por sentido: dos adaptadores para ver las dos direcciones. Verificar el nivel (3,3 V o 5 V)
RS-485 / ModbusUn adaptador USB–RS-485 en el bus, con el transmisor desactivado (recepción permanente). Se ve todo el tráfico, en los dos sentidos, en una sola línea de tiempoUn solo nodo de más en el bus no altera los niveles si es de alta impedancia, pero sí suma capacidad. Se separan las tramas por silencios de 3,5 caracteres (herramienta 1)
CANUna interfaz USB–CAN en modo solo escucha (listen-only)Fuera de ese modo, el controlador confirma las tramas que recibe y altera el bus (tema 28)
Ethernet, Wi-Fi, TCP/IPtcpdump o Wireshark en una computadora conectada al tráfico (el propio equipo, un puerto espejo de un conmutador o una interfaz Wi-Fi en modo monitor)El tráfico cifrado (TLS) solo muestra su estructura exterior (tema 49)
MQTTUn cliente suscripto a todo: mosquitto_sub -v -t '#' muestra cada tema y mensaje en el momento en que se publicaCon autenticación, un usuario con permiso de lectura. Un suscriptor de «todo» puede recibir mucho volumen
BLEUn sniffer específico (como la herramienta de Nordic con un nRF52) o una aplicación de exploración como nRF Connect para ver los anunciosSeguir una conexión exige capturar su inicio; las conexiones cifradas requieren las claves (tema 38)

Un buen sniffer registra, para cada trama: el instante (con la mejor resolución posible), quién habló (la línea o la dirección de origen), los bytes crudos en hexadecimal y el resultado de aplicar las reglas del protocolo: ¿el inicio es el esperado?, ¿el largo es posible?, ¿el CRC verifica?, ¿qué tipo es y qué secuencia lleva? Esto último es lo que distingue una «lista de bytes» de una herramienta de diagnóstico: una línea como [receptor] +26.0 ms 8 bytes MALA: CRC incorrecto | A5 04 01 02 41 00 45 AD dice más que el mismo volcado sin interpretar.

Los sniffers tienen límites que conviene tener claros. La precisión del tiempo es la de la captura: un adaptador USB entrega los bytes con una demora de uno o varios milisegundos que no es constante, así que los instantes de las tramas sirven para ver el orden y los tiempos gruesos (el período, los reintentos a 60 o 120 ms) pero no para medir un viaje de 26 ms con precisión; eso es del analizador lógico, que muestrea con su propio reloj. El sniffer no ve lo eléctrico: una trama que llegó dañada por un flanco lento aparece como una trama con CRC incorrecto, sin decir por qué. Y no puede escuchar lo que no está en su medio: no sirve para ver qué hace el programa dentro del dispositivo. Para eso, los contadores y el registro del propio programa, que a su vez no ven lo que hace el cable. Los tres enfoques se combinan.

09 · Experiencia acumulada

Síntomas y causas típicas

La tabla siguiente reúne las fallas de comunicación más frecuentes en los proyectos de este curso, ordenadas del síntoma a la medición que las confirma. Es la lista de hipótesis que conviene recorrer antes de sospechar del protocolo o del programa.

Del síntoma a la causa.
SíntomaCausa probableCómo se confirmaArreglo
No llega nada; el receptor no ve ni un byteTX y RX sin cruzar; masa sin unir; pin equivocado; el emisor no transmiteAnalizador en TX del emisor: ¿hay actividad? Continuidad con el multímetro; bucle de prueba en cada placaCruzar TX con RX, unir las masas, revisar los pines del begin()
Llega basura constante, sin formaVelocidad o formato distintos; niveles incompatibles (5 V contra 3,3 V, RS-232 contra TTL)Medir el bit más corto: ¿coincide con los baudios configurados? Ver el nivel en el osciloscopioIgualar velocidad y formato; adaptar los niveles
Funciona un rato y se degrada o pierde bytesDesborde del búfer de recepción (el programa no lee a tiempo); desvío del reloj; un delay() largoContador de desbordes; contar bytes enviados contra recibidos; revisar si el loop() se bloqueaLeer el puerto con más frecuencia; usar interrupciones o la cola de la UART con un búfer mayor
Anda con el cable corto y falla con el largoRuido, caída de tensión, capacidad del cable, reflexiones (RS-485 sin terminación)Osciloscopio: forma de los flancos y oscilaciones; tasa de error contra la longitudBajar la velocidad; terminar el bus; par trenzado; reforzar la elevación
RS-485: no se entiende nada, o todo invertidoLos terminales A y B están intercambiados (los fabricantes los nombran distinto)Con el bus en reposo, la tensión A−B debe ser positiva (≥ 200 mV); si es negativa, están invertidosIntercambiar A y B en un extremo; usar una resistencia de polarización (tema 22)
RS-485: se pierde el primer o el último byte de cada tramaEl transceptor no conmuta a tiempo entre transmitir y recibir (DE/RE tarde o temprano)Analizador con DE y la línea de datos: ¿DE sube antes del primer bit y baja después del último?Esperar a que se vacíe la UART (flush()) antes de bajar DE; sumar una pausa corta antes de subirlo
I²C: NACK al hablarle a un sensorDirección equivocada (7 contra 8 bits); sensor sin alimentar; faltan resistencias de elevaciónEscáner I²C; ver SDA y SCL en reposo (deben estar en alto)Corregir la dirección; agregar resistencias de 4,7 kΩ
SPI: se lee siempre 0xFF o 0x00CS no baja; modo SPI mal; MISO desconectado o esclavo sin alimentarAnalizador con las cuatro líneas: ¿baja CS? ¿cambia MISO?Verificar el modo, el CS y el cableado
El CRC siempre falla aunque los bytes parecen bienEl algoritmo no coincide: polinomio, valor inicial, reflexión, orden de los bytes del CRC o el rango que se calculaCalcular el CRC de «123456789» y comparar con el valor de referencia (0x4B37 para Modbus)Ajustar los parámetros hasta que coincida con el vector de prueba (tema 44)
El CRC falla a veces, en tramas sueltasRuido real; un byte perdido por desborde; dos tramas pegadas por un silencio mal medidoVer en el sniffer en qué posición cae el error y si el largo coincideSegún la causa: reforzar el medio, leer a tiempo, o corregir el criterio de fin de trama
Los valores llegan con CRC correcto pero absurdosOrden de bytes, signo o escala distintos entre emisor y receptorDecodificar a mano un mensaje conocido (tema 46)Fijar el formato en una tabla y probar con vectores
Aparecen copias sin que haya pérdidasEl tiempo de espera es menor que el viaje de ida y vueltaMedir el viaje con el analizador y compararlo con la espera (tema 47, prueba 7)Subir la espera a 2 o 3 veces el viaje
El problema desaparece al agregar un Serial.printUna condición de carrera o un tiempo ajustado: el print demora y cambia el ritmoReemplazar el print por un pin de depuración y mirarlo con el analizadorCorregir la sincronización de fondo, no la medición
Se pierde el primer mensaje después de despertar de un sueño profundoLa UART o el transceptor tardan en estabilizarse; el receptor no estaba listoAnalizador: ¿cuánto pasa entre el despertar y el primer byte?Esperar a que el transceptor esté listo; agregar un preámbulo
Pasa en el campo y no en el laboratorioDiferencias de masa, ruido de motores o fuentes, humedad o conexiones flojasRegistrar errores con marca de tiempo y correlacionar con los eventos del lugar (arranque del motor)Aislar galvánicamente, filtrar, blindar; conectores firmes

10 · Con el microcontrolador

Un espía de tramas para el enlace del taller

El programa siguiente es un sniffer pasivo para ESP32 que escucha el enlace del tema 47. Usa dos UART de recepción, una por cada línea (TX del emisor y TX de la receptora), en paralelo con los cables que ya existen, y nunca transmite. Separa las tramas por silencio (5 ms sin bytes), les aplica las reglas del protocolo (inicio, largo, CRC) y muestra una línea por trama con el instante, el tiempo desde la trama anterior y el diagnóstico; las tramas malas aparecen con todos sus bytes. Además, sube un pin de depuración durante 50 µs cada vez que ve una trama mala: conectado a un analizador lógico como canal de disparo, deja capturada la señal real justo en el instante de la falla.

Conexión del espía Un ESP32 espía en el centro. Su GPIO 25 se conecta, en paralelo, con la línea que sale del TX del emisor hacia la receptora; su GPIO 26, con la línea que sale del TX de la receptora hacia el emisor. Las masas de todos se unen. Su GPIO 4 es un pin de depuración que se lleva a un canal de disparo del analizador lógico. Los pines de transmisión del espía quedan sin conectar. Emisor Receptora TX emisor → RX receptoraTX receptora → RX emisor ESP32 espíasolo recibe · USB a la computadora GPIO 25GPIO 26 disparo del analizadorGPIO 4 Masas unidas. Dos entradas de alta impedancia en paralelo no alteran el enlace.
// ---------- Espía pasivo del enlace del tema 47: escucha dos líneas y no transmite nada ----------
const uint8_t  PIN_RX_EMISOR = 25;                             // en paralelo con el TX del emisor
const uint8_t  PIN_RX_RECEPTOR = 26;                           // en paralelo con el TX de la receptora
const uint8_t  PIN_TX_LIBRE_1 = 27, PIN_TX_LIBRE_2 = 14;       // pines de TX de las UART: se dejan sin conectar
const uint8_t  PIN_DEPURAR = 4;                                // un pulso por cada trama mala, para disparar un analizador
const uint32_t BAUDIOS = 9600;
const uint32_t SILENCIO_US = 5000;                             // unos 5 caracteres sin bytes: la trama terminó
const uint32_t INFORME_MS = 10000;

const uint8_t  SOF = 0xA5;
const uint8_t  MAX_LEN = 35;
const size_t   MAX_TRAMA = 64;

uint16_t crc16(const uint8_t *d, size_t n) {
    uint16_t crc = 0xFFFF;
    while (n--) {
        crc ^= *d++;
        for (uint8_t i = 0; i < 8; i++) crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
    }
    return crc;
}

// Un canal es una línea que se escucha: acumula bytes hasta que hay un silencio.
struct Canal {
    const char *nombre;
    HardwareSerial *puerto;
    uint8_t  buf[MAX_TRAMA];
    size_t   n = 0;
    bool     desbordado = false;
    uint32_t inicioUs = 0, ultimoByteUs = 0;
    uint32_t validas = 0, malas = 0, bytes = 0;
};

Canal emisor = { "emisor", &Serial1 };
Canal receptor = { "receptor", &Serial2 };
uint32_t ultimoInicioUs = 0;

// Devuelve nullptr si la trama es buena, o el motivo por el que no lo es.
const char *diagnostico(const uint8_t *b, size_t n) {
    if (b[0] != SOF) return "no empieza con A5";
    if (n < 7) return "demasiado corta";
    if (b[1] < 3 || b[1] > MAX_LEN) return "LEN imposible";
    if (n < (size_t)b[1] + 4) return "cortada (faltan bytes)";
    if (n > (size_t)b[1] + 4) return "con bytes de más (dos tramas pegadas?)";
    if (crc16(b + 1, n - 1) != 0) return "CRC incorrecto";
    return nullptr;
}

void cerrar(Canal &c) {
    const char *motivo = c.desbordado ? "más larga que el búfer" : diagnostico(c.buf, c.n);
    c.bytes += c.n;
    uint32_t delta = c.inicioUs - ultimoInicioUs;               // desde el comienzo de la trama anterior, en cualquiera de las dos líneas
    ultimoInicioUs = c.inicioUs;
    Serial.printf("[%-8s] t=%lu.%06lu s  +%7.3f ms  %2u bytes  ", c.nombre, c.inicioUs / 1000000, c.inicioUs % 1000000, delta / 1000.0, (unsigned)c.n);
    if (motivo == nullptr) {
        c.validas++;
        if (c.buf[4] == 0x01) Serial.printf("LECTURA #%u\n", c.buf[5]);
        else if (c.buf[4] == 0x41) Serial.printf("ACK #%u\n", c.buf[5]);
        else Serial.printf("tipo 0x%02X\n", c.buf[4]);
    } else {
        c.malas++;
        Serial.printf("MALA: %s |", motivo);
        for (size_t i = 0; i < c.n; i++) Serial.printf(" %02X", c.buf[i]);
        Serial.println();
        digitalWrite(PIN_DEPURAR, HIGH);                        // el flanco sirve de disparo para el analizador lógico
        delayMicroseconds(50);
        digitalWrite(PIN_DEPURAR, LOW);
    }
    c.n = 0;
    c.desbordado = false;
}

void atender(Canal &c) {
    while (c.puerto->available()) {
        uint8_t b = c.puerto->read();
        uint32_t ahora = micros();
        if (c.n == 0) c.inicioUs = ahora;
        if (c.n < MAX_TRAMA) c.buf[c.n++] = b; else c.desbordado = true;
        c.ultimoByteUs = ahora;
    }
    if (c.n > 0 && micros() - c.ultimoByteUs > SILENCIO_US) cerrar(c);
}

void setup() {
    Serial.begin(115200);
    pinMode(PIN_DEPURAR, OUTPUT);
    Serial1.begin(BAUDIOS, SERIAL_8N1, PIN_RX_EMISOR, PIN_TX_LIBRE_1);
    Serial2.begin(BAUDIOS, SERIAL_8N1, PIN_RX_RECEPTOR, PIN_TX_LIBRE_2);
    Serial.println("Espía listo: escucho el emisor (GPIO 25) y la receptora (GPIO 26) a 9600 baudios");
}

void loop() {
    atender(emisor);
    atender(receptor);
    static uint32_t ultimoInforme = 0;
    if (millis() - ultimoInforme >= INFORME_MS) {
        ultimoInforme = millis();
        Serial.printf("--- emisor: %lu buenas, %lu malas, %lu bytes | receptor: %lu buenas, %lu malas, %lu bytes\n",
                      emisor.validas, emisor.malas, emisor.bytes, receptor.validas, receptor.malas, receptor.bytes);
    }
}

Qué hay que notar:

  • Pasivo de verdad. Las UART se abren con los pines de TX en dos pines sin conectar; el programa jamás llama a write. Las entradas del ESP32 son de alta impedancia, por lo que dos de ellas en paralelo con una línea no la alteran de forma apreciable.
  • El fin de una trama es el silencio, no el largo: así se detectan también las tramas cortadas o pegadas. Con 9600 baudios un byte dura 1,04 ms, y 5 ms equivalen a casi cinco caracteres; entre dos bytes de la misma trama nunca hay una pausa así. (Para la velocidad de otra aplicación se ajusta SILENCIO_US: Modbus RTU usa 3,5 caracteres.)
  • El diagnóstico está ordenado como el decodificador del tema 41: inicio, largo mínimo, largo posible, largo coincidente con lo recibido y, por último, CRC. El primer fallo es el motivo que se informa, que apunta a la capa donde buscar.
  • El tiempo es de la lectura de la UART, no del bit en el cable: tiene una incertidumbre de menos de un milisegundo por el ciclo del programa. Sirve para ver la cadencia, los reintentos a 60 y 120 ms y los silencios; no para medir un viaje de 26 ms con precisión. Para eso, el analizador lógico.
  • El pin de depuración da un flanco por cada trama mala. Conectado al canal de disparo del analizador (con el disparo en flanco ascendente y una captura previa a él), se obtiene la forma real de la señal justo antes del fallo, que es lo que se necesita para distinguir un ruido de una colisión.
  • Los informes de cada 10 s cuentan las tramas buenas y malas por línea. Si el emisor tiene 100 tramas buenas y 12 malas, se sabe que el problema está en un sentido y no en el otro, sin mirar el código de ningún extremo.

11 · Analogía con programación

Un analizador lógico en Python

El modelo siguiente hace en Python lo que hace un analizador: fabrica la captura de muestras de una UART (ceros y unos tomados a una frecuencia fija) a partir de los bytes del taller anterior, mide el bit más corto para estimar la velocidad, decodifica la UART muestreando en la mitad de cada bit y, sobre los bytes obtenidos, hace de sniffer de tramas: busca el inicio, comprueba el largo y verifica el CRC-16. Con él se reproducen tres fallas clásicas: una velocidad equivocada, un muestreo insuficiente y un bit dañado en la trama.

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

import struct

BAUDIOS = (1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200)


def crc16(datos):
    crc = 0xFFFF
    for b in datos:
        crc ^= b
        for _ in range(8):
            crc = (crc >> 1) ^ 0xA001 if crc & 1 else crc >> 1
    return crc


def armar(dst, src, tipo, datos):
    cuerpo = bytes([len(datos) + 3, dst, src, tipo]) + datos
    return bytes([0xA5]) + cuerpo + crc16(cuerpo).to_bytes(2, "little")


# ---------- Lo que ve un analizador lógico: muestras de 0 y 1 ----------
def bits_de(byte):
    return [0] + [(byte >> i) & 1 for i in range(8)] + [1]        # inicio, 8 datos (LSB primero), parada


def muestrear(datos, baud, fs, reposo=3):
    bits = [1] * reposo + [b for x in datos for b in bits_de(x)] + [1] * 3
    total = int(len(bits) * fs / baud)
    return [bits[min(int((k * baud) / fs), len(bits) - 1)] for k in range(total)]


def rachas(muestras):
    """Cuántas muestras seguidas hay con el mismo valor."""
    salida, n = [], 1
    for a, b in zip(muestras, muestras[1:]):
        if a == b:
            n += 1
        else:
            salida.append(n)
            n = 1
    salida.append(n)
    return salida


def estimar_baud(muestras, fs):
    """La racha más corta es un bit: se calcula la velocidad y se busca la estándar más cercana."""
    ancho = min(rachas(muestras)[1:-1])               # sin el reposo del principio y del final
    crudo = fs / ancho
    return round(crudo), min(BAUDIOS, key=lambda b: abs(b - crudo))


def nivel(muestras, inicio, k, por_bit):
    j = int(inicio + (k + 0.5) * por_bit)             # la mitad del bit k
    return muestras[j] if j < len(muestras) else 1


def decodificar(muestras, fs, baud):
    por_bit = fs / baud
    datos, errores, i = [], 0, 1
    while i < len(muestras):
        if muestras[i - 1] == 1 and muestras[i] == 0 and nivel(muestras, i, 0, por_bit) == 0:
            v = sum(nivel(muestras, i, 1 + k, por_bit) << k for k in range(8))
            if nivel(muestras, i, 9, por_bit) == 1:
                datos.append(v)
            else:
                errores += 1                          # el bit de parada no está en alto: error de encuadre
            i = int(i + 9.5 * por_bit)
        else:
            i += 1
    return bytes(datos), errores


# ---------- Lo que ve un analizador de tramas: bytes ----------
def buscar_tramas(datos):
    tramas, crc_malo, descartados, i = [], 0, 0, 0
    while i < len(datos):
        if datos[i] != 0xA5 or i + 1 >= len(datos) or not 3 <= datos[i + 1] <= 35:
            descartados += 1
            i += 1
            continue
        total = datos[i + 1] + 4
        if i + total > len(datos):
            break                                     # trama cortada al final
        if crc16(datos[i + 1:i + total]) == 0:
            tramas.append((i, datos[i:i + total].hex(" ").upper()))
            i += total
        else:
            crc_malo += 1                             # el A5 era falso, o la trama estaba dañada
            descartados += 1
            i += 1
    return tramas, crc_malo, descartados


lectura = armar(2, 1, 0x01, struct.pack("<BBBhHH", 0, 1, 7, 2350, 5500, 3300))
confirmacion = armar(1, 2, 0x41, bytes([0]))
captura = lectura + confirmacion
fs = 1_000_000
m = muestrear(captura, 9600, fs)
print(f"{len(captura)} bytes -> {len(m)} muestras a {fs // 1000} kHz ({fs / 9600:.1f} por bit)")
print("racha más corta:", min(rachas(m)[1:-1]), "muestras | baud medido y más cercano:", estimar_baud(m, fs))

datos, err = decodificar(m, fs, 9600)
print("a 9600:", datos.hex(" ").upper(), "| errores de encuadre:", err)
print("tramas:", [(p, t[:23] + "...") for p, t in buscar_tramas(datos)[0]])

datos, err = decodificar(m, fs, 4800)
print("a 4800 (equivocada):", len(datos), "bytes,", err, "errores de encuadre, primeros:", datos[:4].hex(" ").upper())

for fs2 in (200_000, 20_000, 15_000, 10_000):
    m2 = muestrear(captura, 9600, fs2)
    d2, e2 = decodificar(m2, fs2, 9600)
    print(f"a {fs2 // 1000} kHz ({fs2 / 9600:.1f} muestras por bit): {'bien' if d2 == captura else 'mal'}, {len(d2)} bytes, {e2} errores de encuadre")

dañada = bytearray(captura)
dañada[9] ^= 0x04                                     # un bit invertido en la temperatura
tramas, crc_malo, descartados = buscar_tramas(bytes(dañada))
print("con un bit dañado:", len(tramas), "tramas válidas,", crc_malo, "rechazada por CRC,", descartados, "bytes descartados")

Resultado: la captura de 24 bytes (una lectura y su confirmación) da 25 625 muestras a 1 MHz, 104,2 por bit. La racha más corta es de 104 muestras, que corresponde a 9615 baudios y a la velocidad estándar más cercana, 9600. Decodificada a 9600 devuelve los 24 bytes, A5 0C 02 01 01 00 01 07 2E 09 7C 15 E4 0C 90 CB A5 04 01 02 41 00 45 AC, sin errores de encuadre, y el analizador de tramas encuentra las dos, en las posiciones 0 y 16. Decodificada con la velocidad equivocada (4800), entrega 3 bytes 04 A3 D0 y 8 errores de encuadre. Con el muestreo reducido: a 200 kHz (20,8 muestras por bit) y a 20 kHz (2,1) la captura se decodifica bien; a 15 kHz (1,6) devuelve 24 bytes, sin ningún error de encuadre y con los valores equivocados; y a 10 kHz (1,0) se pierden bytes (19) y aparecen 5 errores de encuadre. Con un solo bit invertido en la temperatura (byte 9), el analizador de tramas encuentra una trama válida (la confirmación), rechaza una por el CRC y descarta 16 bytes (la lectura entera, porque el inicio falso se rescanea byte a byte).

Tres lecciones del modelo. Primera: la velocidad se mide, no se supone: la racha más corta y una regla de tres dan la velocidad con un error del 0,16 % en este caso, suficiente para reconocer la estándar. Segunda: un muestreo insuficiente no siempre avisa: a 15 kHz la decodificación «sale» sin errores y con los datos mal, el peor tipo de falla; por eso se muestrea con margen y se verifica con el CRC lo que sale. Tercera: el CRC convierte un daño de un bit en un diagnóstico: la trama dañada no se pasa por válida, y el sniffer dice cuántas se rechazaron, que es lo que se busca cuando se persigue una falla intermitente.

12 · Exploración interactiva

Laboratorio: UART, muestreo, I²C y capturas

El laboratorio tiene cinco herramientas. La primera calcula los tiempos de una UART. La segunda decodifica una UART con la velocidad del receptor desajustada, muestreando cada bit como lo haría el hardware. La tercera calcula el muestreo, la memoria y el ancho de banda de los instrumentos. La cuarta genera la secuencia de una transacción I²C y calcula los tiempos y las resistencias de elevación. La quinta analiza una captura de tramas del protocolo del tema 47, como lo haría un sniffer.

1. Tiempos de una UART

Un bit—
Un byte—
Caudal—
Una ráfaga—
Silencio de fin de trama—
Frecuencias en la línea—
Lectura—

Escribí una velocidad.

2. Decodificar una UART con la velocidad desajustada

Primer byte en el cable—
Desfase del muestreo—
Lo que lee el receptor—
Errores—
Veredicto—

Escribí los bytes.

3. Muestreo, memoria y ancho de banda

Muestras por bit—
Precisión del ancho—
Ventana de captura—
Cuánto cabe—
Osciloscopio—
Veredicto—

Escribí los parámetros.

4. Una transacción I²C y sus resistencias de elevación

Secuencia en el bus—
Bits—
Duración—
Subida de los flancos—
Límite de la norma—
Resistencia mínima—
Veredicto—

Escribí los parámetros.

5. Analizar una captura de tramas

Captura—
Tramas válidas—
Rechazadas por el CRC—
Bytes descartados—
Largos imposibles—
Final de la captura—
Diagnóstico—

Escribí una captura.

En la herramienta 1, un byte tiene un bit de inicio, los de datos, una paridad opcional y una o dos paradas; el silencio de fin de trama es el de 3,5 caracteres de Modbus RTU. En la 2, el receptor busca el flanco de bajada del inicio y mira cada bit en su mitad con su propio reloj; los formatos son iguales en los dos extremos y lo que varía es la velocidad (un 7E1 enviado a un receptor de 8 bits perdería el octavo bit; acá se ve que A5 no entra en 7 bits y se lee 25). En la 3, la incertidumbre de un ancho es de una muestra. En la 4, el tiempo de subida se mide entre el 30 y el 70 % de la excursión (0,8473 · R · C) y el mínimo de la resistencia supone que un pin puede hundir 3 mA con 0,4 V. En la 5, la captura se explora como el decodificador del tema 41 con el CRC-16 del tema 44.

Recorrido guiado

  1. En la herramienta 1, con 9600 8N1: 104,2 µs por bit, 1,04 ms por byte, 960 bytes por segundo (80 % de datos), una ráfaga de 16 bytes en 16,67 ms, un silencio de fin de trama de 3,65 ms y 4,8 kHz en el patrón más rápido (0x55). Con 115 200 8E1: 8,7 µs, 11 bits por byte (95,5 µs), 10 473 bytes por segundo (73 % de datos) y 1,53 ms para los 16 bytes.
  2. En la herramienta 2, con A5 0C a 9600 contra 9600: se lee A5 0C sin errores. A 9800 (2,1 % de desajuste, un desfase de 0,20 bits): sigue bien. A 10 200 (6,3 %, 0,59 bits): A5 sale bien y el 0C sale con un error de encuadre (✗): el límite está en el filo, y que un byte salga bien y otro mal depende de los datos que lleva. A 10 500 (9,4 %): hasta el primer byte es incorrecto (45). Con el receptor a 4800: lee un único byte, CA, y dos inicios falsos. Con 19 200: tres bytes en lugar de dos y dos errores de encuadre. Con el formato 7E1: A5 se lee como 25, porque el octavo bit no existe.
  3. En la herramienta 3, con 9600 baudios y 1 MHz: 104 muestras por bit (cómodo), incertidumbre del 1 %, una ventana de 1 s con 1000 mil muestras (960 bytes, 60 tramas de 16 bytes) y, para un flanco de 5 ns, un osciloscopio de 70 MHz como mínimo. Con 115 200 y 0,5 MHz: 4,3 muestras por bit (justo), con una incertidumbre del 23 %: decodifica pero no sirve para medir. Con 1 Mbaud y 2 MHz: 2 muestras por bit, insuficiente.
  4. En la herramienta 4, con la dirección 76, lectura de 1 byte, 100 kHz, 4,7 kΩ y 100 pF: S · EC A · reg A · Sr · ED A · 1 byte · P, 39 bits en 390 µs, subida de 398 ns (el límite es 1000 ns; con 4,7 kΩ el bus soportaría hasta 251 pF) y resistencia mínima de 0,97 kΩ. Con 400 kHz, 10 kΩ y 200 pF: la subida es de 1695 ns contra un límite de 300, el bus ya no cumple (con 10 kΩ solo aguantaría 35 pF). Con 0,5 kΩ y 5 V: el mínimo es de 1,53 kΩ y el pin no lograría bajar la línea. Con escritura de 2 bytes a 400 kHz, 4,7 kΩ y 50 pF: 29 bits en 72,5 µs y 199 ns de subida: correcto.
  5. En la herramienta 5, con la captura de ejemplo (62 bytes): 3 tramas válidas (una LECTURA #0 en la posición 0, un ACK #0 en la 18 y una LECTURA #2 en la 42), 1 rechazada por el CRC (la lectura con un bit invertido), 18 bytes descartados (los dos de ruido, FF 00, y los 16 de la trama dañada) y una trama cortada de 4 bytes al final. Probá borrar un byte del medio de una trama, o cambiar uno solo: aparece una nueva candidata rechazada.
Desafío: la bomba que arranca y rompe el bus

Una planta tiene un maestro y cuatro esclavos sobre un bus RS-485 de 80 m a 19 200 baudios (Modbus RTU). Funciona bien, pero «a veces» el maestro registra una falla de comunicación con un esclavo; siempre alrededor de los mismos horarios. Con lo visto, un plan de diagnóstico: (1) Registrar antes de suponer: dejar un sniffer pasivo (adaptador USB–RS-485 en escucha, sección 8) con un archivo de salida que guarde las tramas buenas y las malas con la hora. Después de un día, los informes muestran que las tramas malas son CRC incorrecto, en ráfagas de 2 a 10 tramas seguidas, en los mismos horarios, y que nunca se pierden el inicio ni el largo. (2) Interpretar: ráfagas en horarios fijos y no al azar apuntan a una causa externa periódica, no al protocolo. El CRC detecta los daños, de modo que el protocolo está haciendo su trabajo; lo que falta es entender el origen. (3) Correlacionar: los horarios coinciden con el arranque de una bomba de 3 kW cerca del cable. (4) Medir: con el osciloscopio (una canal en A−B con el disparo por el pin de depuración que se enciende en cada trama mala) se ve un pico de unos 3 V, de 100 µs, en cada arranque, acoplado al par: es ruido inductivo. (5) Probar hipótesis de a una: comprobar que el cable es un par trenzado y que la malla está a tierra en un solo extremo; que existe la terminación de 120 Ω en los dos extremos y nada más; que el cable va separado del cable del motor (al menos 30 cm, y si cruza, a 90°). (6) Arreglos: separar el cable, blindarlo, agregar un filtro en el motor y, si no alcanza, bajar a 9600 baudios o usar reintentos con un tiempo de espera mayor (tema 45). (7) Verificar: la misma captura de un día, con la cuenta de tramas malas por hora, antes y después. Es el método completo en un caso real: registrar, interpretar, correlacionar, medir, cambiar una cosa, verificar.

13 · Hábitos

Buenas prácticas de depuración

  • Diseñar para poder depurar. Lo más barato es incluirlo desde el principio: un contador por cada cosa que puede salir mal (CRC, largo, desborde, copias, rendidos), un informe periódico, un modo de registro de tramas en hexadecimal y un pin de depuración libre (tema 47).
  • Dejar puntos de prueba. En una placa propia, pads accesibles para TX, RX, masa y alimentación, y un conector para el analizador. Cuesta un centavo en el diseño y ahorra horas en el campo.
  • Usar un vector de prueba conocido. Un mensaje fijo (la trama de ejemplo) con su resultado esperado permite comprobar los dos extremos sin depender de los datos de un sensor.
  • El registro no debe cambiar el comportamiento. Un Serial.print a 9600 baudios de 40 caracteres tarda 42 ms: puede ser mayor que el viaje que se mide. Se usa una velocidad alta para la consola (115 200), mensajes cortos, un pin de depuración que cambia en eventos clave, o un búfer que se vuelca fuera de la parte crítica.
  • Guardar las capturas. Una captura buena y una mala del mismo evento, con una nota de las condiciones, valen más que cualquier descripción. Sirven también para reportar el problema a un compañero o al fabricante.
  • Sospechar de lo físico primero cuando es intermitente. Una falla que aparece y desaparece sola suele ser un contacto, una masa, un conector o ruido; una que ocurre siempre en las mismas condiciones suele ser lógica. Las fallas lógicas se reproducen; las eléctricas, se correlacionan.
  • No creer en un solo instrumento. Si el analizador y el programa discrepan, algo de lo que se supone está mal: el umbral, la velocidad, el disparo, el cableado de la sonda.
  • Cambiar una cosa y volver. Un arreglo que «funcionó» sin entender por qué es una promesa sin garantía: se revierte, se comprueba que la falla vuelve, y se reaplica.

14 · Comprensión

Confusiones frecuentes

«Si el analizador lógico decodifica bien, la señal es buena»

Solo si el decodificador está bien configurado y se muestrea con margen. Un analizador no ve la forma analógica: un flanco lento o ruidoso puede decodificarse bien y, en el receptor real, con otro umbral, fallar. Si los bits llegan correctos pero el enlace falla, el osciloscopio es el paso siguiente.

«Con 2 muestras por bit alcanza, porque el bit dura más que eso»

Teóricamente, para una señal ideal; en la práctica, no. Con muestras tan escasas, un pequeño desajuste de reloj o un flanco con ruido cambia el bit muestreado, y los errores aparecen sin aviso, con datos equivocados y sin error de encuadre (el modelo de Python lo muestra a 15 kHz). Se muestrea a 4 veces como mínimo y a 10 o más para medir.

«El osciloscopio de mayor ancho de banda es siempre el mejor»

Lo necesario es suficiente ancho de banda para los flancos que se miden (0,35 / tr, el doble en la práctica). Más ancho de banda deja ver más ruido de alta frecuencia que no afecta al circuito, y exige más cuidado con la sonda y la masa. Lo que sí importa es la memoria y la calidad de la sonda.

«Si la velocidad configurada coincide en los dos programas, las velocidades reales coinciden»

La velocidad real depende del reloj del chip y del divisor, y puede diferir de la pedida en un 2 o 3 % en algunas combinaciones. Dos dispositivos con errores opuestos suman la diferencia. Por eso se mide el bit más corto en el cable, y se elige una velocidad cuya divisibilidad sea buena en ambos relojes.

«Un sniffer no molesta, así que se puede conectar de cualquier forma»

Un sniffer pasivo con entradas de alta impedancia casi no altera la señal, pero uno mal conectado sí: un adaptador cuyo TX queda conectado a la línea hace una colisión; una masa flotante agrega ruido; un transceptor RS-485 con el transmisor habilitado compite con los nodos. En CAN, fuera del modo de solo escucha, el sniffer confirma tramas y modifica el bus.

«El tiempo que marca el sniffer es el tiempo real en el cable»

Es el tiempo en que la computadora recibió el byte, con la demora y el jitter del adaptador USB y del sistema operativo: de uno a varios milisegundos. Sirve para ordenar eventos y ver tiempos gruesos, no para medir un viaje de 26 ms. Para eso, el analizador lógico con su propio reloj.

«Un CRC malo es siempre ruido»

No: también es un byte perdido, dos tramas pegadas, un algoritmo de CRC distinto, un orden de los bytes del CRC al revés o un cálculo sobre un rango equivocado. Si todas las tramas fallan, es casi seguro una discrepancia de algoritmo; si solo algunas, ruido o pérdida. Se prueba con el vector «123456789».

«Si el problema desaparece al mirarlo, ya está arreglado»

Un Serial.print o un analizador conectado modifican los tiempos y las cargas. Una falla que desaparece al medirla es una pista (una condición de carrera, un margen justo), no una solución. Hay que medirla de una forma menos intrusiva, como un pin de depuración, o entender por qué el cambio la oculta.

«Para depurar una comunicación hay que revisar primero el protocolo»

El protocolo es una capa alta; una masa floja o una velocidad distinta producen síntomas que parecen fallas de protocolo. Se empieza por abajo: alimentación, nivel eléctrico, tiempos, bytes, tramas, y recién después los reintentos y los contadores.

15 · Práctica guiada

Predecí antes de comprobar

1. La velocidad a partir de un pulso

En un analizador, el pulso más angosto de una UART mide 26 µs. ¿A qué velocidad estándar corresponde, y cuánto dura un byte 8N1?

Ver solución

1 / 26 µs ≈ 38 462 baudios, o sea la estándar 38 400. Un byte 8N1 son 10 bits: 10 × 26 µs ≈ 260 µs (10 / 38 400 = 260,4 µs).

2. Leer un byte a mano

Una UART 8N1 muestra, después del inicio, los bits de datos 1, 0, 0, 0, 0, 0, 1, 0 y la parada en alto. ¿Qué byte es? ¿Qué se leería si se tomara el primer bit como el más significativo?

Ver solución

El primer bit es el menos significativo, así que los bits del bit 0 al 7 son 1, 0, 0, 0, 0, 0, 1, 0; escritos del 7 al 0: 0 1 0 0 0 0 0 1 = 0x41 (la letra «A»). Si se toma el primer bit como el más significativo, quedaría 10000010 = 0x82. Es el síntoma de «bytes en espejo».

3. El muestreo del analizador

Se quiere analizar una UART de 115 200 baudios. ¿Qué frecuencia de muestreo mínima y cuál recomendada usarías? ¿Cuánta memoria hace falta para capturar 100 ms?

Ver solución

Mínima, 4 muestras por bit: 4 × 115 200 = 460,8 kHz, o sea un analizador de 0,5 MHz (justo). Recomendada, 10 veces: 1,15 MHz, o sea 2 MHz en la práctica (17 muestras por bit). Para 100 ms a 2 MHz: 0,1 s × 2 000 000 = 200 000 muestras.

4. El límite de la velocidad

El emisor transmite a 115 200 con un error de +2 % y el reloj del receptor tiene un error de −4 %. Con 10 bits por byte, ¿se lee bien? ¿Y con −2 % y +2 %?

Ver solución

La diferencia relativa es de aproximadamente 6 %. Al llegar a la mitad del bit de parada (9,5 bits), el corrimiento es 9,5 × 0,06 = 0,57 bits, más que 0,5: el muestreo cae en el bit vecino y aparecen errores de encuadre y bytes errados. En el segundo caso la diferencia es de 4 %: 9,5 × 0,04 = 0,38 bits, que todavía cabe, pero con poco margen frente al ruido: es el límite práctico.

5. Las resistencias de un bus I²C

Un bus de 400 kHz a 3,3 V tiene 150 pF de capacidad. Se probó con resistencias de 10 kΩ. ¿Cumple? ¿Qué valor elegirías?

Ver solución

Subida: 0,8473 × 10 000 × 150 pF ≈ 1271 ns, contra un máximo de 300 ns a 400 kHz: no cumple. La resistencia máxima es 300 ns / (0,8473 × 150 pF) ≈ 2,36 kΩ; la mínima, (3,3 − 0,4) / 3 mA ≈ 0,97 kΩ. Un valor entre los dos, como 2,2 kΩ, da una subida de 280 ns: cumple. Si hiciera falta más margen, se baja la velocidad a 100 kHz (1000 ns) o se reduce la capacidad.

6. Qué hace un sniffer ante una trama dañada

Un sniffer ve A5 0C 02 01 01 … con un byte dañado en el medio y el CRC no verifica. ¿Por qué sigue buscando desde el byte siguiente al A5 y no desde el final de la supuesta trama?

Ver solución

Porque el CRC incorrecto significa que ese A5 no era un inicio verdadero o que la trama estaba dañada, y en ninguno de los dos casos se sabe dónde termina de verdad. Una trama buena puede estar escondida dentro de la candidata: si el A5 era un dato cualquiera, la verdadera empieza más adelante. Avanzar un byte a la vez no pierde ninguna (es lo que hace el decodificador del tema 41). La herramienta 5 lo muestra: tras la trama dañada, la siguiente se encuentra bien.

7. Un diagnóstico con el espía

Después de 10 s el espía informa: línea del emisor, 20 buenas y 0 malas; línea de la receptora, 12 buenas y 8 malas, todas «cortada (faltan bytes)». Las tramas de la receptora son confirmaciones de 8 bytes. ¿Qué hipótesis plantearías y qué medirías?

Ver solución

Las lecturas del emisor viajan bien; las confirmaciones de la receptora llegan incompletas. Hipótesis: (a) la receptora corta su transmisión (por ejemplo, desactiva el transmisor antes de que termine el último byte: en RS-485, DE que baja antes de vaciar la UART; o un reinicio); (b) hay una pausa de más de 5 ms dentro de la trama (el espía la toma por el final); (c) un nivel de tensión o un cable defectuoso en ese sentido. Medición: el analizador lógico sobre TX de la receptora y, si hay RS-485, sobre DE; contar los bytes y medir las pausas. Si hay 8 bytes con una pausa larga en el medio, es el caso (b); si hay menos de 8, el (a) o el (c).

8. El orden de las mediciones

Dos placas conectadas por UART no se entienden y no llega ningún byte. Ordená estas mediciones de la primera a la última: decodificar los bytes en el analizador, medir la tensión de cada placa, ver si hay actividad en TX del emisor, comprobar la continuidad de la masa y de los dos cables, medir el bit más corto.

Ver solución

De abajo hacia arriba: (1) tensión de cada placa y (2) continuidad de la masa y de los cables (cruzados TX–RX), con el multímetro; (3) actividad en TX del emisor con el analizador: si no hay flancos, el emisor no transmite y el cable no tiene la culpa; (4) medir el bit más corto y comparar con la velocidad configurada; (5) recién entonces decodificar los bytes. Saltar directo a decodificar sin verificar lo de abajo es perder tiempo.

16 · Síntesis

Ideas para recordar

  • Un enlace que no se ve no se puede razonar: se mide antes de suponer. Los síntomas de fallas distintas se parecen, y la depuración consiste en distinguirlas con pocas mediciones.
  • El método es de abajo hacia arriba: alimentación y masa, nivel eléctrico, bits y tiempos, bytes, tramas, protocolo y aplicación. Una falla en una capa baja se disfraza de falla en una alta. Se cambia una cosa a la vez, se parte el sistema por la mitad (con bucle de prueba o con un interlocutor de referencia) y se escribe lo que se ve.
  • Cada instrumento responde preguntas distintas: el multímetro, tensiones y continuidad; el osciloscopio, la forma analógica (niveles, flancos, ruido, reflexiones); el analizador lógico, los bits de muchas líneas en el tiempo y su decodificación; el sniffer, la conversación; los contadores del programa, lo que piensa cada extremo.
  • Una UART se decodifica a mano midiendo el bit más corto (104 µs son 9600 baudios), leyendo en la mitad de cada bit, con el bit menos significativo primero, y comprobando la parada. Una velocidad desajustada más del 2 a 3 % (el límite teórico es 5 %) produce bytes errados y errores de encuadre.
  • El analizador necesita al menos 4 muestras por bit, 10 o más para medir bien; la memoria define cuánto tiempo se mira. Un muestreo insuficiente puede dar datos equivocados sin ningún error. El osciloscopio necesita un ancho de banda de 0,35 / tr como mínimo y, mejor, el doble, y una sonda bien compensada con tierra corta.
  • En I²C, un NACK en la dirección es el primer síntoma de una dirección equivocada (7 contra 8 bits); la subida de los flancos (0,8473 · R · C) no puede pasar de 1000 ns a 100 kHz ni de 300 ns a 400 kHz. En SPI, un MISO fijo en 0xFF suele ser un CS que no baja, el modo equivocado o un esclavo sin respuesta.
  • Un sniffer es pasivo: nunca transmite ni confirma. Registra instante, quién habló, bytes crudos y el diagnóstico de cada trama (inicio, largo, CRC). Su reloj no tiene la precisión del analizador lógico, y no ve lo eléctrico.
  • La tabla de síntomas y causas permite ir directo a la medición que confirma cada hipótesis. Las fallas intermitentes se correlacionan con eventos externos y se miden de forma poco intrusiva (un pin de depuración, no un print); el arreglo se verifica con la misma medición que mostró la falla.

¿Listo para el siguiente tema?

Antes de avanzar, explicá cómo deducirías la velocidad de una UART desconocida con un analizador lógico y qué muestreo usarías para 57 600 baudios; calculá la resistencia de elevación máxima para un bus I²C de 400 kHz con 120 pF; y describí el orden en que medirías un enlace RS-485 que no funciona. Si podés justificar las tres respuestas, sabés cómo se mira un enlace antes de suponer.

En el próximo tema, seguridad en la comunicación, se agrega lo que ni el CRC ni los reintentos resuelven: que alguien con mala intención lea, falsifique o repita los mensajes. Se estudian el cifrado, la autenticación, TLS, la gestión de claves y los mensajes repetidos, y se verá que los sniffers de este tema son también las herramientas que usa un atacante.