← Índice del curso

Comunicación entre Dispositivos · Tema 43 · Protocolos, paquetes y errores

Errores de transmisión

Hasta ahora supusimos que lo que sale por TX es lo que llega por RX. En un escritorio, con un cable de treinta centímetros, casi lo es. En una planta, con un bus de trescientos metros al lado de un motor, en una radio de 2,4 GHz compartida con todo el edificio o en un pulsador que rebota, no. La señal que viaja es una magnitud física (una tensión, un campo, una luz) y el mundo la altera: le suma ruido, la atenúa, la refleja, la mezcla con otras. El receptor decide cada bit comparando lo que mide con un umbral, y a veces se equivoca. Este tema estudia por qué se producen los errores, cómo se ven desde el programa, cómo se mide su frecuencia (la tasa de error de bit y la de trama), qué cambia cuando llegan juntos en ráfagas, y qué hacer en el cable y en el programa para diagnosticarlos y reducirlos. Es el tercer paso del bloque de protocolos: explica por qué la suma de verificación del paquete existe, y prepara la detección con paridad, suma y CRC (tema 44) y las confirmaciones y los reintentos (tema 45).

01 · Objetivo

Un canal imperfecto

Ruido que cambia dos bits Una señal de ocho bits, 1 0 1 1 0 1 0 0, transmitida entre dos niveles con un umbral en el centro. La señal limpia es una línea punteada. La señal real, con ruido, tiene un hundimiento en el tercer bit, que baja del umbral, y un pico en el séptimo bit, que lo supera. El receptor muestrea en el centro de cada bit y lee 1 0 0 1 0 1 1 0: dos bits errados, el tercero y el séptimo. El receptor mide la señal en el centro de cada bit y la compara con un umbral: si el ruido la cruza, lee mal. umbral 10110100 10010110 enviadoleído el ruido hunde el 1el ruido sube el 0 señal enviadaseñal que llega (con ruido)lectura correctalectura errónea Un solo bit errado alcanza para que la trama entera sea inválida.

La señal de un bus o de una radio es una magnitud física, y todo lo físico se puede perturbar. Entre el emisor y el receptor, el mundo hace cuatro cosas: la atenúa (llega con menos amplitud), la distorsiona (los flancos se redondean, rebotan o se retrasan), le suma otras señales (ruido propio del circuito, interferencias de motores, radios, otros cables) y a veces la pisa (otro transmisor habla al mismo tiempo). El receptor no ve «el bit enviado»: ve una tensión, y tiene que decidir si es un 0 o un 1. Mientras el ruido sea chico frente a la diferencia entre los dos niveles, decide bien. Cuando no lo es, se equivoca, y no sabe que se equivocó.

Una falla de este tipo es especialmente incómoda porque no avisa: el programa recibe un byte válido, de un valor distinto al enviado. Una temperatura de 23,50 °C que llega como 87,50 °C no produce ningún error en el UART. La defensa es del protocolo: la suma de verificación del paquete (tema 41) y las técnicas de los temas 44 y 45. Pero para diseñarla bien hay que saber cuántos errores esperar, de qué forma llegan y qué los produce, y eso se estudia aquí. Dos conceptos organizan el tema: la tasa de error de bit (BER, bit error rate: la fracción de bits que llegan alterados) y la tasa de error de trama (la fracción de tramas que llegan con algún error), y la relación entre las dos.

02 · Por qué fallan

Las causas físicas

Cada causa tiene una firma distinta (cuándo aparece, cuántos bits afecta, cómo cambia con la distancia o la velocidad), y conocerlas es lo que permite arreglar la causa en lugar de tapar los síntomas:

Causas físicas de los errores de transmisión.
CausaQué esCómo se manifiestaQué ayuda
Ruido térmico y electrónicoLa agitación de los electrones en las resistencias y los amplificadores; está siempre, como un «soplido» de fondoErrores aislados y raros; empeoran con la velocidad, con la distancia y con señales débilesMás amplitud de señal, menos ancho de banda, buenos componentes
Interferencia electromagnética (EMI)Campos de motores, relés, contactores, variadores de frecuencia, soldadoras, fuentes conmutadas, descargas y transmisores de radio, que se acoplan al cableRáfagas, ligadas a un evento (un relé que conmuta, un motor que arranca); errores a ciertas horasPar trenzado, señal diferencial, blindaje, separación de los cables de potencia, filtros
Diafonía (crosstalk)La señal de un cable se acopla a otro paralelo; es más fuerte con flancos rápidos y tramos paralelos largosErrores que coinciden con la actividad de la línea vecinaMás separación, pares trenzados, cruzar a 90°, flancos más lentos
Ruido de masa y diferencias de potencialDos equipos con tierras distintas tienen tensión entre sus masas; las corrientes de retorno hacen «saltar» la referenciaErrores intermitentes en enlaces con masa común (RS-232, UART largo); a veces, daño del puertoDiferencial (RS-422 y RS-485), aislamiento galvánico, un solo punto de tierra
Alimentación ruidosaCaídas o picos de la tensión de alimentación del emisor o del receptor, por consumos pulsantes (radio, motores, relés)Errores o reinicios cuando el equipo hace algo que consume muchoCapacitores de desacople, reguladores, fuentes separadas
Atenuación y capacidad del cableEl cable pierde amplitud con la distancia y su capacidad redondea los flancos (un filtro RC, tema 19)Bits mal formados que empeoran con el largo y con la velocidad; el límite de I²C o de 1-WireMenos velocidad, resistencias de pull-up más chicas, repetidores, cable de menor capacidad
ReflexionesUna línea larga no terminada devuelve parte de la señal por el mismo cable (sección 6)Flancos con rebotes que cruzan el umbral; pasa siempre igual con el mismo cableTerminación adaptada a la impedancia del cable, derivaciones cortas
Rebotes de contactosLas láminas de un pulsador o relé rebotan unos milisegundos antes de asentarse (sección 7)Una pulsación se cuenta como variasAntirrebote por programa o por hardware
Desvío de reloj y de muestreoEmisor y receptor discrepan en la velocidad, o el muestreo cae cerca del borde del bit (tema 8)Errores de trama o bytes mal leídos, más en los bytes largos o con ciertos valoresCristales en lugar de osciladores internos, velocidades con divisor exacto
Desvanecimiento y bandas compartidas (radio)La señal cambia con obstáculos, el movimiento y el multitrayecto; en 2,4 GHz comparte la banda con Wi-Fi, Bluetooth, Zigbee y hornos de microondas (tema 34)Pérdidas variables, según la hora, la ocupación del espacio y la distanciaElegir canales libres, más potencia o antena, reintentos
ColisionesDos transmisores hablan a la vez (tema 42)Tramas dañadas que crecen con la carga y no con el ruidoAcceso al medio con turnos o escucha previa
Fallas del programaUn búfer que se desborda, una interrupción que tarda, un byte que se pisa (tema 9)Bytes perdidos, sobre todo a velocidades altas o con otras tareas ocupadasBúferes más grandes, interrupciones cortas, control de flujo

Un criterio útil para ordenarlas es separar los errores aleatorios de los sistemáticos. Los aleatorios (el ruido térmico, la EMI) tienen un origen estadístico: no se pueden evitar del todo, solo reducir y tolerar, y se tratan con probabilidades. Los sistemáticos (una línea sin terminar, un baudio equivocado, un rebote, una masa mal conectada) se repiten igual cada vez que se dan las condiciones, y se arreglan: no tiene sentido tolerarlos con reintentos cuando una resistencia de 120 Ω los elimina. La regla del tema 48 (depurar) empieza por ahí: primero se descartan los sistemáticos y después se calculan los aleatorios.

03 · Qué llega al programa

Cómo se ve un error desde el programa

El programa no ve tensiones: ve bytes (o su ausencia). Un mismo daño físico se presenta de maneras distintas, y conviene reconocerlas porque cada una se detecta de otro modo:

Tipos de error vistos por el receptor.
TipoQué ocurreCómo lo ve el receptorDónde se detecta
Bit cambiadoUn 0 se lee como 1, o al revésUn byte válido de valor distintoSuma o CRC del paquete (tema 44); la paridad lo ve solo si cambia un bit
RáfagaVarios bits seguidos alterados por un evento cortoUno o varios bytes seguidos con valores arbitrariosCRC (cubre ráfagas); una suma simple puede no verla
Error de trama del UARTEl bit de parada llega en 0 (el muestreo cayó mal)La UART levanta el indicador de «error de trama»La UART, antes del programa (tema 8)
Error de paridadCambió un número impar de bits en un byteLa UART levanta el indicador de paridad (si está activada)La UART (tema 7)
Byte fantasmaUn pulso de ruido en la línea en reposo imita un bit de inicioUn byte que nadie envió, con la UART desalineada hasta la próxima paradaDelimitador de inicio y suma del paquete (tema 41)
Byte perdidoEl búfer estaba lleno, o la interrupción tardó (desbordamiento)Falta un byte: el largo no cierra, o la suma fallaIndicador de desbordamiento; largo y suma
Trama truncadaEl mensaje se corta (desconexión, interferencia larga)Faltan bytes y el siguiente paquete empieza dentro del cuerpoTiempo de espera entre bytes (tema 41)
Trama perdidaNo llegó nada, o nada válidoEl receptor no sabe que algo faltóNúmeros de secuencia y confirmaciones (tema 45)
Trama duplicada o desordenadaUn reintento llega junto con el original; un camino tarda más que otroDos tramas iguales, o una vieja después de una nuevaNúmeros de secuencia (tema 45)

Dos observaciones. Primero, el peor error es el que no se detecta: un daño que deja la suma de verificación en el valor correcto, y que el receptor acepta. Con una suma de un byte, un daño aleatorio importante pasa inadvertido una vez cada 256 aproximadamente; un CRC de 16 bits, una de cada 65 536 (tema 44). Cuanto más larga la verificación, menos errores se cuelan, pero nunca es cero, y por eso en sistemas críticos se agrega validación de los valores (un rango razonable para la temperatura) por encima del protocolo. Segundo, los errores de un nivel generan errores en el siguiente: un bit mal leído en el LEN desplaza el resto de la trama, y todos los bytes siguientes se leen en la posición equivocada hasta que el receptor se resincroniza con el próximo 0xA5. La máquina de estados del tema 41, con su vigilancia de tiempo y su reanálisis tras una suma incorrecta, existe para eso.

04 · Cuánto ruido soporta un bit

Ruido, margen y tasa de error de bit

El receptor decide cada bit comparando la tensión con un umbral, normalmente a mitad de camino entre los dos niveles. La distancia entre el nivel y el umbral es el margen de ruido: con una señal de 3,3 V de amplitud, es de 1,65 V. Un error ocurre cuando el ruido, en el instante de muestreo, supera ese margen. Si el ruido es gaussiano (la forma típica del ruido térmico y de la suma de muchas fuentes pequeñas) con una desviación típica σ (el valor eficaz del ruido), la probabilidad de que un bit se lea mal es:

BER = Q(m / σ) = ½ · erfc( m / (σ·√2) )

donde m es el margen y erfc la función de error complementaria. Lo que importa es la relación z = m / σ, cuántas desviaciones del ruido caben en el margen. La curva es dramática:

Tasa de error de bit según el margen medido en desviaciones del ruido (ruido gaussiano, umbral en el centro).
z = margen / ruidoEn decibeles (20·log₁₀ z)Tasa de error de bitUna trama de 10 bytes (100 bits) se daña
26,0 dB2,3 × 10−2El 90 %
39,5 dB1,35 × 10−3El 12,6 %
412,0 dB3,2 × 10−5El 0,32 %
514,0 dB2,9 × 10−7El 0,003 %
615,6 dB9,9 × 10−10Una de cada 10 millones
716,9 dB1,3 × 10−12Una de cada 8000 millones

La enseñanza está en la pendiente: cada unidad extra de margen (una desviación más del ruido) mejora la tasa de error entre uno y tres órdenes de magnitud. Pasar de 3 a 5 veces el ruido reduce los errores unas cinco mil veces; perder un poco de margen (un cable más largo, un motor encendido a un metro) los multiplica por la misma proporción. Por eso un enlace que «anda perfecto» puede romperse con un cambio pequeño: el margen estaba justo, y la curva es empinada. Y por eso, una vez que el margen supera unas seis veces el ruido, el enlace queda prácticamente libre de errores aleatorios, y los que quedan son de los otros tipos (interferencias impulsivas, fallos del programa). La herramienta 2 calcula la tasa para cualquier señal y cualquier ruido.

Dos maneras de mejorar la relación: aumentar la señal (más tensión, o una menor atenuación por menos distancia, un cable de mejor calidad, un amplificador) o disminuir el ruido (blindaje, filtrado, menos ancho de banda). La señal diferencial (tema 23) logra lo segundo de manera elegante: el receptor mide la diferencia entre dos hilos trenzados, de modo que una interferencia que llega igual a los dos (modo común) se resta. Un receptor RS-485 con un rechazo de modo común de 20 dB reduce el ruido común diez veces: el margen medido en desviaciones se multiplica por diez (la herramienta 2, con el campo de rechazo). Es la razón de que los buses industriales sean diferenciales. También hay un compromiso con la velocidad: un bit más corto tiene menos tiempo para que el ruido se promedie, y el receptor necesita más ancho de banda (que deja entrar más ruido). Duplicar la velocidad empeora el margen, y cuando un enlace da errores, bajar la velocidad es el primer remedio gratuito.

Órdenes de magnitud

Tasas de error orientativas (órdenes de magnitud, según el medio y la instalación).
EnlaceTasa de error típicaComentario
UART en una placa, cables cortosPrácticamente nula (menos de 10−12)Los errores que aparecen son de configuración (baudios, niveles) o del programa
RS-232 o RS-485 bien instalado10−9 a 10−12Con terminación, par trenzado y buena masa; empeora mucho con una mala instalación
Ethernet de cobre10−10 a 10−12 como objetivo del estándarY las tramas llevan un CRC de 32 bits (tema 29)
Bluetooth clásicoLa sensibilidad se define con 10−3 (0,1 %)Por eso el estándar incluye corrección y reintentos (tema 37)
Wi-Fi, BLE, LoRa y otras radiosPérdidas de paquetes de 1 % a 10 % en uso normalEl diseño supone que se pierden y se retransmiten (temas 35 a 39)

La lección práctica: en un cable corto y bien hecho los errores son rarísimos y casi siempre se deben a otra cosa; en un cable industrial son raros pero existen, y hay que detectarlos; en una radio, son parte normal del funcionamiento y hay que reintentar.

05 · Qué se pierde de verdad

De los bits a las tramas, y las ráfagas

El protocolo no entrega bits sueltos: entrega tramas completas, y una trama vale lo que vale su bit más débil. Si cada bit se altera con probabilidad p (la tasa de error de bit), una trama de N bits llega intacta con probabilidad (1 − p)N, y llega dañada con:

P(trama dañada) = 1 − (1 − p)N ≈ N · p (para N · p pequeño)

En un enlace UART 8N1 cada byte ocupa 10 bits en la línea. Una trama de 10 bytes (como las del tema 42) son 100 bits. Con p = 10−5, se dañan 1 de cada 1000 tramas. Parece poco, pero a 9600 baudios, con tramas seguidas, son casi 100 tramas por segundo: una trama dañada cada diez segundos, unas 345 por hora: hay que detectarlas. La tasa de error de bit casi nunca es lo que le importa a la aplicación: importa la fracción de tramas que se pierden y el tiempo entre una y otra, y es lo que calcula la herramienta 1.

Fracción de tramas dañadas según la tasa de error de bit y el largo de la trama (errores aislados).
Tasa de error de bit10 bytes (100 bits)64 bytes (640 bits)255 bytes (2550 bits)
10−60,010 %0,064 %0,255 %
10−50,10 %0,64 %2,5 %
10−41,0 %6,2 %22,5 %
10−39,5 %47 %92,2 %

Dos consecuencias de diseño. Primero, una trama larga sufre más: con 10−4, una trama de 255 bytes se pierde una vez de cada cuatro y media, y una de 10 bytes, una de cada cien. Además, cuando una trama se pierde, hay que reenviarla entera: el costo de un error es proporcional al largo. Por eso los enlaces ruidosos usan tramas cortas y los silenciosos, largas (más eficiencia: tema 42). Segundo, cuando se reintenta, hacen falta en promedio 1 / (1 − P) envíos por trama: 1,29 para el 22,5 %, 1,105 para el 9,5 %. Con una pérdida de un 20 % se envía un cuarto más de tráfico y se pierde ese ancho de banda (tema 45).

Errores aislados y en ráfagas

La fórmula supone que cada bit se altera por separado. Casi nunca es así: el ruido térmico sí es independiente de un bit al siguiente, pero las interferencias son impulsivas y duran más que un bit. Un relé que conmuta, un arco, un motor que arranca producen un pulso de microsegundos o milisegundos, que a 9600 baudios (104 µs por bit) altera varios bits seguidos: una ráfaga. El efecto es contraintuitivo: con la misma tasa de error de bit, las ráfagas dañan menos tramas, pero cada una queda más dañada. En la simulación de la herramienta 3, con una tasa de 10−3, tramas de 10 bytes y errores aislados se pierde alrededor del 9,6 % de las tramas; con ráfagas de 8 bits, el 1,2 %, y con ráfagas de 32 bits, el 0,4 %. Los mismos bits errados se concentran en pocas tramas.

Esto tiene tres efectos prácticos. Primero, la tasa de error de bit, medida sobre un tiempo largo, engaña: un enlace con 10−6 puede estar perfecto 99,9 % del tiempo y pésimo durante unos segundos al día; lo que importa es la distribución. Segundo, los reintentos inmediatos sirven poco contra una ráfaga larga: la segunda trama cae dentro del mismo evento y falla igual; conviene esperar un poco entre intentos, con una espera creciente (tema 45). Tercero, la detección de errores tiene que servir para ráfagas: un CRC garantiza detectar cualquier ráfaga de hasta la cantidad de bits de su propio tamaño (16 bits para un CRC-16), mientras que una suma de un byte puede perder ráfagas que se compensan.

Por último, una advertencia estadística: una medición corta no dice casi nada. Con una tasa de 10−6 y una trama de 100 bits hay una trama mala cada 10 000: para contar al menos veinte y tener un valor con un 20 % de incertidumbre hay que enviar 200 000 tramas, unos 35 minutos de tráfico continuo a 9600 baudios (y mucho más si las tramas son esporádicas). Diez minutos a 9600 baudios son 5,8 millones de bits: si no se vio ningún error, solo se sabe, con un 95 % de confianza, que la tasa es menor que unos 5 × 10−7 (la regla de tres: 3 dividido por los bits observados), no que sea cero. El medidor de la sección 9 sirve para dejar un enlace contando durante horas.

06 · El eco de la línea

Reflexiones y terminación

Reflexión de un flanco en el extremo de una línea Un emisor envía un flanco por un cable hacia una carga. Una parte vuelve como onda reflejada. Debajo, tres gráficos de la tensión en el extremo de la línea. Con el extremo abierto, el coeficiente de reflexión es más uno, la tensión sube al doble y oscila antes de asentarse. Con una carga igual a la impedancia del cable, es cero y la tensión sube limpiamente al valor final. Con un cortocircuito, es menos uno, y la tensión en la carga se queda en cero. Emisor Carga onda incidente: viaja hacia la cargaonda reflejada: Γ · V, vuelve al emisor Extremo abierto · Γ = +1Adaptado (ZL = Z0) · Γ = 0Cortocircuito · Γ = −1 V2 V sube al doble y oscila (rebota)sube limpiamente: nada vuelvela carga nunca recibe tensión Tensión en la carga ante un escalón de 1 V: la línea «ve» su carga y devuelve lo que no puede entregar.

Un cable largo no es un simple hilo: a las velocidades de un flanco rápido es una línea de transmisión. La señal viaja por él como una onda, a unos 5 ns por metro en un cable típico (dos tercios de la velocidad de la luz), y mientras avanza «ve» una impedancia constante, la impedancia característica Z0 (unos 120 Ω en un par trenzado para RS-485, 50 Ω en un coaxial). Al llegar al final, si la carga tiene la misma impedancia, absorbe toda la energía y nada vuelve. Si no, una parte regresa por el cable, con el coeficiente de reflexión:

Γ = (ZL − Z0) / (ZL + Z0)

Con el extremo abierto (ZL enorme), Γ = +1: la onda vuelve entera y con el mismo signo, y la tensión en el extremo se duplica. En cortocircuito, Γ = −1: vuelve invertida y cancela la señal. Una carga igual a Z0 da Γ = 0. La onda reflejada llega al emisor, que (con una impedancia de salida baja) la refleja de nuevo: el flanco rebota de un extremo al otro, con amplitudes decrecientes, y en cada pasada se suma a la señal. El receptor ve un flanco con oscilaciones que pueden cruzar el umbral varias veces: bits de más, y un error sistemático que se repite igual cada vez.

Solo importa si la línea es larga frente al flanco. El rebote tarda en volver el doble del tiempo de viaje; si el flanco ya terminó de subir antes de que llegue, la reflexión se ve como un detalle posterior, lejos del instante en que el receptor mide. Una regla práctica es que la línea es crítica si su largo supera el tiempo de subida dividido por seis veces los 5 ns/m: Lcrítico = tsubida / (6 · 5 ns/m). Con un flanco de 50 ns son 1,7 m; con uno de 1 µs, 33 m. Los tramos cortos de una placa (I²C o SPI a decenas de centímetros) no la necesitan; un bus industrial de cientos de metros con flancos de decenas de nanosegundos, sí.

El remedio es la terminación: una resistencia igual a Z0 en el extremo (y, en un bus bidireccional como RS-485, en los dos extremos, nunca en el medio), que absorbe la onda. También conviene que las derivaciones (los cables que llevan del bus a cada nodo) sean cortas, de pocos centímetros o decenas, porque cada una es un pequeño tramo sin terminar. Otras ayudas: un transceptor con flancos más lentos (slew rate limitado, muy usado en RS-485 de baja velocidad), una resistencia en serie de unas decenas de ohms en la salida de un driver rápido, y una topología en línea (daisy chain) en lugar de estrella: una estrella tiene muchos extremos sin terminar. En el tema 24 se vio el detalle de RS-485; acá está el porqué. La herramienta 4 calcula Γ, el largo crítico y si hay que terminar.

07 · El ruido que hace un contacto

Rebotes de contactos y antirrebote

Rebote de un pulsador y su filtrado Arriba, la señal cruda de un pulsador con resistencia de pull-up: está en alto, al presionar baja y conmuta cuatro veces durante unos milisegundos antes de asentarse en bajo, y al soltar, vuelve a conmutar varias veces antes de quedar en alto. Abajo, la señal después del antirrebote: una sola transición al presionar y una sola al soltar, cada una retrasada por el tiempo de espera del filtro. Un contacto mecánico no conmuta una vez: rebota. Para el microcontrolador, cada rebote es un pulso real. AltoBajoAltoBajo Señal cruda del pulsador (con pull-up)Después del antirrebote rebotereboteesperaespera se presionase suelta El filtro acepta el nuevo valor cuando se mantuvo estable más tiempo que el rebote.

El error de transmisión más cotidiano no está en un cable largo: está en un pulsador. Un contacto mecánico se cierra con láminas metálicas que chocan y vuelven a chocar, y durante un intervalo que va de 1 a 20 ms (según el pulsador, la fuerza y la edad) la conexión se abre y se cierra decenas de veces. Para el microcontrolador, que lee un pin en microsegundos, esos rebotes son pulsos legítimos: un contador de pulsaciones suma diez por cada presión, un contador de eventos de un interruptor de final de carrera se dispara, un estado alterna sin motivo. Lo que llega por el cable no es lo que el usuario quiso decir. Es el mismo problema que el ruido, con un origen mecánico: la señal es correcta en promedio y errónea en detalle.

El remedio común es el antirrebote, que acepta un cambio solo cuando la señal se mantuvo estable más tiempo que el rebote. Hay dos familias:

  • Por programa: se lee el pin cada pocos milisegundos y se acepta un nuevo valor cuando varias lecturas seguidas coinciden, o cuando pasó cierto tiempo desde el último cambio. No cuesta componentes y sirve para cualquier pin, pero ocupa al programa y agrega un retardo igual al tiempo de espera. Es lo que se hace en el programa de más abajo.
  • Por hardware: un filtro RC (resistencia y capacitor) suaviza el flanco, y un inversor con histéresis (entrada Schmitt) lo convierte en una conmutación limpia. Cuesta una resistencia y un capacitor, no ocupa al programa y funciona aunque el procesador esté ocupado. Con 10 kΩ y 1 µF, la constante de tiempo es 10 ms, y la señal tarda unos 12 ms en cruzar el 70 % de la alimentación. Sin histéresis, un pin digital común puede oscilar al cruzar la zona intermedia.

Las dos tienen el mismo costo: un retardo. El filtro no puede ser más lento que lo que se quiere detectar. Con 10 lecturas iguales cada milisegundo, la espera es de 10 ms, y solo se distinguen pulsaciones separadas por más de eso: unas cien por segundo como máximo, de sobra para un dedo y poco para un codificador rotativo mecánico, que se filtra con más cuidado. El mismo concepto reaparece con otros nombres: el filtro de un sensor ruidoso (promediar varias lecturas), el debounce de una tecla de teclado, la confirmación de un valor cuando tres lecturas coinciden. En todos, se cambia tiempo por confiabilidad. La herramienta 5 compara los dos métodos.

const uint8_t  PIN_BOTON = 4;                                  // pulsador entre el pin y GND, con pull-up interno
const uint8_t  LECTURAS_ESTABLES = 10;                         // lecturas iguales seguidas para aceptar un cambio
const uint32_t PERIODO_LECTURA_MS = 1;

bool estable = HIGH, anterior = HIGH;
uint8_t iguales = 0;
uint32_t flancosCrudos = 0, pulsaciones = 0;
unsigned long ultimaLectura = 0;

void setup() {
    Serial.begin(115200);
    pinMode(PIN_BOTON, INPUT_PULLUP);
}

void loop() {
    if (millis() - ultimaLectura < PERIODO_LECTURA_MS) return;
    ultimaLectura = millis();
    bool lectura = digitalRead(PIN_BOTON);
    if (lectura != anterior) { flancosCrudos++; iguales = 1; }          // la señal cruda cambió: se empieza a contar de nuevo
    else if (iguales < 255) iguales++;
    anterior = lectura;
    if (iguales >= LECTURAS_ESTABLES && lectura != estable) {          // se mantuvo estable más tiempo que el rebote
        estable = lectura;
        if (estable == LOW) {
            pulsaciones++;
            Serial.printf("pulsación %lu (flancos crudos hasta ahora: %lu)\n", pulsaciones, flancosCrudos);
        }
    }
}

Con el pulsador de una placa, el número de flancos crudos suele ser varias veces el de pulsaciones (cada presión y cada soltada agregan sus rebotes): es la medida de cuánto rebota. Si se baja LECTURAS_ESTABLES a 1, el antirrebote desaparece y el contador cuenta cada rebote.

08 · Medir antes de arreglar

Del síntoma a la causa

Un enlace con errores se arregla igual que un programa con un fallo: con una observación que acote la causa. Antes de cambiar nada, hay que contar: cuántas tramas se pierden, en cuánto tiempo, en qué nodo, a qué hora, con qué velocidad y con qué actividad cerca. El programa de la sección siguiente lo hace. Con los números, la tabla ayuda a pasar del síntoma a la hipótesis:

Síntomas, causas probables y primeras pruebas.
Lo que se observaCausa probablePruebaRemedio
Errores que crecen con el largo del cable o con la velocidadAtenuación, capacidad, margen justoBajar la velocidad a la mitad; probar con un cable cortoMenos velocidad, mejor cable, repetidor, diferencial
Errores en ráfagas, coincidentes con un evento (un motor, un relé, un variador)Interferencia electromagnéticaRegistrar la hora de los errores y compararla con el equipo; apagar el sospechosoPar trenzado blindado, separación de los cables de potencia, filtros en el equipo que emite
Errores siempre iguales, con ciertos bytes o en cada tramaBaudios que no coinciden, reflexiones, mala terminaciónMedir el baudio real con un analizador; probar otra velocidad con otro divisorVelocidad exacta, cristal, terminación
Errores con un nodo concretoDerivación larga, conector, dirección repetida, driver defectuosoDesconectar los demás; cambiar el nodo de lugarAcortar la derivación, revisar conexiones y direcciones
Errores al aumentar el tráfico, no con el ruidoColisiones, desbordamiento de búferesMirar si los errores siguen la carga y no la horaTurnos, control de flujo, búferes mayores
El enlace anda distinto cada día, o según el tiempoConectores sueltos, humedad, temperatura, radio compartidaMover los cables; registrar por hora; mirar el espectroConectores con traba, canal de radio libre
Muchas pulsaciones por cada presiónRebotes de contactosContar flancos crudos y pulsaciones aceptadasAntirrebote por programa o hardware
Bytes perdidos sin error de trama, con tráfico altoBúfer lleno, interrupciones tardíasMirar el indicador de desbordamiento; bajar la velocidadBúfer mayor, leer más seguido, control de flujo

Contener los errores en capas

Los errores de transmisión no se eliminan: se contienen, con medidas en varios niveles, cada una más barata que la siguiente cuando se la aplica antes. El orden de este curso refleja ese orden de preferencia:

  1. Reducir la causa en el cable: par trenzado, blindaje conectado en un solo extremo, terminación, separación de la potencia, masas bien hechas, desacople de la alimentación, conectores firmes. Es lo más barato por error evitado, y la única medida que baja los errores sin costo de ancho de banda.
  2. Elegir la velocidad y el nivel con margen: más lento, más tensión, menos distancia; señal diferencial o con aislamiento galvánico (tema 50 para elegir).
  3. Detectar los que quedan: paridad, suma, CRC (tema 44). Sin esto, el receptor no sabe que se equivocó.
  4. Reparar por reenvío: confirmaciones, tiempos de espera, reintentos y números de secuencia (tema 45).
  5. Reparar sin reenvío: códigos de corrección, como el de Hamming (tema 45), cuando reenviar es caro o imposible (una radio con una sola dirección, un enlace con mucha latencia).
  6. Validar en la aplicación: rangos plausibles, filtros de valores y alarma si el enlace falla (tema 51).

Cada nivel supone al anterior. Un protocolo con CRC y reintentos sobre un cable sin terminar anda, con la mitad del ancho de banda. Un cable perfecto sin detección anda hasta que un día un error pasa sin ser visto. La combinación es lo que hace confiable un enlace imperfecto.

09 · Con el microcontrolador

Un medidor de calidad de enlace

El programa siguiente mide un enlace con el paquete del tema 42. Una placa transmite tramas de 10 bytes con un número de secuencia, cada 50 ms; la otra las recibe y cuenta las que llegan bien, las que llegan dañadas (suma incorrecta, largo inválido, corte por tiempo) y las que faltan, deducidas de los saltos en el número de secuencia. Con eso estima la tasa de error de trama y la de bit, y las informa cada diez segundos. Para ensayar el comportamiento sin un entorno ruidoso, el emisor puede inyectar errores: cambia bits de las tramas ya armadas, con una tasa y una longitud de ráfaga configurables. Se carga en dos placas con TX y RX cruzados (o un bus RS-485 con transceptores) y se cambia SOY_EMISOR en cada una.

// ---------- Configuración ----------
const bool     SOY_EMISOR = false;                             // true en la placa que envía; false en la que mide
const uint32_t RUIDO_PPM = 0;                                  // tasa de error de bit inyectada, en partes por millón (1000 = 0,1 %)
const uint8_t  RAFAGA = 1;                                     // bits seguidos que se alteran en cada error (1 = aislados)
const uint32_t PERIODO_PRUEBA_MS = 50;                         // una trama cada 50 ms
const uint32_t INFORME_MS = 10000;

const uint8_t  SOF = 0xA5;
const uint8_t  MAX_LEN = 35;
const uint8_t  TIPO_PRUEBA = 0x30;
const uint8_t  DIR_RECEPTOR = 0x02, DIR_EMISOR = 0x01;
const uint32_t TIEMPO_BYTE_MS = 10;
const uint8_t  BITS_TRAMA = 100;                               // 10 bytes por 10 bits en la línea (8N1)

// ---------- Emisor ----------
uint16_t secuencia = 0;
uint32_t bitsAlterados = 0;
unsigned long ultimoEnvio = 0;

void inyectarRuido(uint8_t *p, uint8_t n) {
    for (uint16_t b = 0; b < (uint16_t)n * 8; b++) {
        if (random(1000000L * RAFAGA) < (long)RUIDO_PPM) {        // cada ráfaga arranca con RUIDO_PPM/RAFAGA: la tasa de bits errados se mantiene
            for (uint8_t k = 0; k < RAFAGA && b + k < (uint16_t)n * 8; k++) { p[(b + k) / 8] ^= 1 << ((b + k) % 8); bitsAlterados++; }
            b += RAFAGA - 1;
        }
    }
}

void enviarPrueba() {
    uint8_t p[10];
    p[0] = SOF;
    p[1] = 7;                                                  // destino, origen, tipo y 4 bytes de datos
    p[2] = DIR_RECEPTOR;
    p[3] = DIR_EMISOR;
    p[4] = TIPO_PRUEBA;
    p[5] = secuencia & 0xFF;                                   // número de secuencia, para detectar tramas que faltan
    p[6] = secuencia >> 8;
    p[7] = 0x55;
    p[8] = 0xAA;
    uint8_t suma = 0;
    for (uint8_t i = 1; i < 9; i++) suma += p[i];
    p[9] = (uint8_t)(0x100 - suma);
    if (RUIDO_PPM > 0) inyectarRuido(p, sizeof(p));            // el ruido llega después de calcular la suma, como en un cable real
    Serial1.write(p, sizeof(p));
    secuencia++;
}

// ---------- Receptor ----------
uint32_t buenas = 0, perdidas = 0, sumasMalas = 0, largosMalos = 0, cortes = 0;
int32_t  ultimaSecuencia = -1;
unsigned long ultimoInforme = 0;

void alPaquete(uint8_t dst, uint8_t src, uint8_t tipo, const uint8_t *d, uint8_t n) {
    if (tipo != TIPO_PRUEBA || n < 2) return;
    uint16_t sec = d[0] | (d[1] << 8);
    buenas++;
    if (ultimaSecuencia >= 0) perdidas += (uint16_t)(sec - ultimaSecuencia - 1);   // los números que faltan entre dos tramas buenas
    ultimaSecuencia = sec;
}

class Decodificador {
  public:
    typedef void (*AlRecibir)(uint8_t dst, uint8_t src, uint8_t tipo, const uint8_t *datos, uint8_t n);
    Decodificador(AlRecibir cb) : alPaq(cb) {}
    void alimentar(uint8_t b) {
        ultimoByte = millis();
        switch (estado) {
            case ESPERA_SOF: if (b == SOF) estado = ESPERA_LEN; break;
            case ESPERA_LEN:
                if (b >= 3 && b <= MAX_LEN) { buf[0] = b; n = 1; faltan = b + 1; estado = CUERPO; }
                else { largosMalos++; estado = ESPERA_SOF; alimentar(b); }
                break;
            case CUERPO:
                buf[n++] = b;
                if (--faltan == 0) {
                    estado = ESPERA_SOF;
                    uint8_t suma = 0;
                    for (uint8_t i = 0; i < n; i++) suma += buf[i];
                    if (suma == 0) alPaq(buf[1], buf[2], buf[3], buf + 4, n - 5);
                    else {
                        sumasMalas++;
                        uint8_t copia[MAX_LEN + 2];
                        uint8_t m = n;
                        memcpy(copia, buf, m);
                        n = 0;
                        for (uint8_t i = 0; i < m; i++) alimentar(copia[i]);   // por si el inicio de otra trama estaba dentro
                    }
                }
                break;
        }
    }
    void vigilarTiempo() {
        if (estado != ESPERA_SOF && millis() - ultimoByte > TIEMPO_BYTE_MS) { cortes++; estado = ESPERA_SOF; n = 0; }
    }
  private:
    enum Estado { ESPERA_SOF, ESPERA_LEN, CUERPO } estado = ESPERA_SOF;
    AlRecibir alPaq;
    uint8_t buf[MAX_LEN + 2];
    uint8_t n = 0, faltan = 0;
    unsigned long ultimoByte = 0;
};

Decodificador receptor(alPaquete);

void informar() {
    uint32_t total = buenas + perdidas;                        // tramas que el emisor mandó desde la primera recibida
    double pTrama = total ? (double)perdidas / total : 0.0;
    double ber = 1.0 - pow(1.0 - pTrama, 1.0 / BITS_TRAMA);    // inversa de P = 1 - (1 - p)^N
    Serial.printf("buenas %lu · faltan %lu (%.2f %%) · suma mala %lu · largo malo %lu · cortes %lu · BER estimada %.2e\n",
                  buenas, perdidas, pTrama * 100.0, sumasMalas, largosMalos, cortes, ber);
}

void setup() {
    Serial.begin(115200);
    Serial1.begin(9600, SERIAL_8N1, 16, 17);
}

void loop() {
    if (SOY_EMISOR) {
        if (millis() - ultimoEnvio >= PERIODO_PRUEBA_MS) { ultimoEnvio = millis(); enviarPrueba(); }
        if (millis() - ultimoInforme >= INFORME_MS) { ultimoInforme = millis(); Serial.printf("enviadas %u · bits alterados %lu\n", secuencia, bitsAlterados); }
        return;
    }
    while (Serial1.available()) receptor.alimentar(Serial1.read());
    receptor.vigilarTiempo();
    if (millis() - ultimoInforme >= INFORME_MS) { ultimoInforme = millis(); informar(); }
}

Qué hay que notar:

  • La inyección de ruido imita un cable real: el emisor calcula la suma primero y altera los bits después, de modo que el receptor ve exactamente lo que vería si el daño ocurriera en el trayecto. Con RUIDO_PPM = 1000 (una tasa de error de bit del 0,1 % sobre los 80 bits de cada trama de 10 bytes, sin contar los bits de inicio y de parada) se espera dañar el 7,7 % de las tramas. Con RAFAGA = 8 y la misma tasa, se dañan muchas menos tramas, pero cada una queda con unos 8 bits cambiados: es la herramienta 3 en hardware.
  • El daño se clasifica: una suma incorrecta (un bit cambiado en cualquier lugar), un largo fuera de rango (se alteró el LEN), un corte por tiempo (se alteró el LEN a un valor mayor y la trama quedó esperando bytes que no llegaron). La suma de los tres cuenta los casos que el decodificador detectó. Si SOF se altera, la trama simplemente no se ve: no hay una categoría que la cuente, y por eso faltan se deduce de la secuencia, no de los errores detectados.
  • El número de secuencia detecta las tramas perdidas: es la técnica que formaliza el tema 45. Si llegan la 100 y la 103, faltan dos, sin importar por qué. (uint16_t)(sec − ultimaSecuencia − 1) maneja también el desborde de 65535 a 0.
  • La estimación de la tasa de error de bit invierte la fórmula de la sección 5: de la fracción de tramas perdidas se deduce p = 1 − (1 − P)1/N. Es una estimación de errores aislados; con ráfagas, la tasa de bits errados real es mayor que la estimada (hay más bits errados por trama dañada).
  • Hay que dejarlo correr mucho tiempo (la sección 5): con la tasa de la prueba real (digamos 10−7), no se ve un solo error en horas. Con RUIDO_PPM alto se puede probar el programa en minutos.
  • La posición donde se coloca el medidor importa: junto al receptor real, no junto al emisor, y a la velocidad real del sistema.
  • En un Arduino sin printf en Serial, se reemplaza por Serial.print; sin segundo puerto serie, se usa SoftwareSerial.

10 · Analogía con programación

El canal en Python

Casi todo el tema se prueba sin hardware: la probabilidad de que una trama se dañe, la tasa de error que produce un margen de ruido, el coeficiente de reflexión, un canal con errores aislados o en ráfagas y el antirrebote de un contacto simulado. El modelo siguiente reproduce las reglas del laboratorio. El generador de números aleatorios es el mismo de la página (mulberry32), por eso las cantidades coinciden con las de la herramienta 3 con la semilla 1.

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

BITS_POR_BYTE = 10                                              # 8N1: inicio, 8 de datos y parada
MASCARA = 0xFFFFFFFF


def prob_trama(ber, n_bytes):
    """Probabilidad de que una trama de n_bytes tenga al menos un bit errado."""
    return -math.expm1(n_bytes * BITS_POR_BYTE * math.log1p(-ber))


def ber_gaussiano(amplitud_pp, ruido_rms, rechazo_db=0.0):
    """Margen en desviaciones del ruido (z) y tasa de error de bit con umbral en el centro."""
    z = (amplitud_pp / 2) / (ruido_rms / 10 ** (rechazo_db / 20))
    return z, 0.5 * math.erfc(z / math.sqrt(2))


def reflexion(z0, zl):
    return (zl - z0) / (zl + z0)


def largo_critico(t_subida_ns, ns_por_m=5):
    return t_subida_ns / (6 * ns_por_m)


def mulberry32(semilla):
    a = semilla & MASCARA
    def siguiente():
        nonlocal a
        a = (a + 0x6D2B79F5) & MASCARA
        t = ((a ^ (a >> 15)) * (a | 1)) & MASCARA
        t ^= (t + (((t ^ (t >> 7)) * (t | 61)) & MASCARA)) & MASCARA
        return ((t ^ (t >> 14)) & MASCARA) / 4294967296
    return siguiente


def canal(ber, rafaga, tramas, n_bytes, semilla):
    """Tramas seguidas por un canal con errores: cada ráfaga arranca con probabilidad ber/rafaga y altera 'rafaga' bits."""
    azar = mulberry32(semilla)
    bits_trama = n_bytes * BITS_POR_BYTE
    total = tramas * bits_trama
    log_q = math.log1p(-ber / rafaga)
    pos, bits_malos, tramas_malas, ultima = -1, 0, 0, -1
    while True:
        pos += 1 + math.floor(math.log(1 - azar()) / log_q)     # distancia geométrica hasta la próxima ráfaga
        if pos >= total:
            break
        fin = min(pos + rafaga, total)
        bits_malos += fin - pos
        for f in range(max(pos // bits_trama, ultima + 1), (fin - 1) // bits_trama + 1):
            tramas_malas += 1
            ultima = f
        pos = fin - 1
    return bits_malos, tramas_malas


def muestras_contacto(semilla, antes=20, rebote=5, apretado=35, ms=100):
    """Una muestra por milisegundo de un pulsador que se aprieta y se suelta, con rebotes al azar."""
    azar = mulberry32(semilla)
    m = []
    for t in range(ms):
        if t < antes:
            v = 0
        elif t < antes + rebote:
            v = 1 if azar() < 0.5 else 0
        elif t < antes + rebote + apretado:
            v = 1
        elif t < antes + 2 * rebote + apretado:
            v = 1 if azar() < 0.5 else 0
        else:
            v = 0
        m.append(v)
    return m


def cambios(m):
    return sum(1 for a, b in zip(m, m[1:]) if a != b)


def antirrebote(m, n):
    """Cuenta los cambios aceptados cuando el valor se mantiene n lecturas seguidas."""
    estable, anterior, iguales, aceptados = m[0], m[0], 0, 0
    for x in m[1:]:
        iguales = iguales + 1 if x == anterior else 1
        anterior = x
        if iguales >= n and x != estable:
            estable = x
            aceptados += 1
    return aceptados


for ber, n in ((1e-5, 10), (1e-4, 10), (1e-4, 64), (1e-4, 255), (1e-6, 255)):
    print(f"BER {ber:.0e}, trama de {n} bytes: {prob_trama(ber, n) * 100:.3g} % dañadas")

for amp, ruido, rechazo in ((3.3, 0.3, 0), (3.3, 0.5, 0), (5, 0.5, 0), (3.3, 0.5, 6)):
    z, ber = ber_gaussiano(amp, ruido, rechazo)
    print(f"{amp} V, ruido {ruido} V, rechazo {rechazo} dB: z = {z:.2f}, BER = {ber:.3g}")

for zl in (1e9, 120, 60, 0):
    print(f"ZL = {zl:g} Ω con Z0 = 120 Ω: Γ = {reflexion(120, zl):+.3f}")
print(f"largo crítico con flanco de 50 ns: {largo_critico(50):.1f} m; con 1000 ns: {largo_critico(1000):.1f} m")

for rafaga in (1, 8, 32):
    bits, malas = canal(1e-3, rafaga, 10000, 10, 1)
    print(f"ráfaga de {rafaga:2d}: {bits} bits errados, {malas} tramas dañadas ({malas / 100:.2f} %)")
print(f"teoría con errores aislados: {prob_trama(1e-3, 10) * 100:.2f} %")

m = muestras_contacto(42)
print("cambios de la señal cruda:", cambios(m))
for n in (1, 3, 5, 10):
    print(f"antirrebote con {n:2d} lecturas iguales: {antirrebote(m, n)} cambios aceptados")

Resultado: una trama de 10 bytes con una tasa de error de 10−5 se daña el 0,1 %; con 10−4, el 0,995 % (10 bytes), el 6,2 % (64 bytes) y el 22,5 % (255 bytes); con 10−6 y 255 bytes, el 0,255 %. Una señal de 3,3 V con 0,3 V de ruido tiene 5,50 desviaciones de margen y una tasa de 1,9 × 10−8; con 0,5 V, 3,30 y 4,83 × 10−4; una de 5 V con 0,5 V, 5,00 y 2,87 × 10−7; y con 0,5 V pero 6 dB de rechazo de modo común, 6,58 y 2,28 × 10−11. Una línea de 120 Ω con el extremo abierto da Γ = +1,000; con 120 Ω, 0,000; con 60 Ω, −0,333; en cortocircuito, −1,000. El largo crítico es de 1,7 m con un flanco de 50 ns y 33,3 m con uno de 1000 ns. Con una tasa de 10−3, 10 000 tramas de 10 bytes y la semilla 1: errores aislados, 1022 bits errados y 965 tramas dañadas (9,65 %; la teoría da 9,52 %); ráfagas de 8 bits, 928 bits y 123 tramas (1,23 %); ráfagas de 32 bits, 1024 bits y solo 41 tramas (0,41 %). El pulsador simulado con la semilla 42 tiene 8 cambios en la señal cruda; sin antirrebote (1 lectura) se aceptan los 8, y con 3, 5 o 10 lecturas iguales, solo 2 (una pulsación completa: bajar y soltar).

Dos lecciones del modelo. Primero, la misma tasa de error de bit produce tasas de error de trama muy distintas según cómo se agrupen los errores: la distribución importa tanto como el promedio. Segundo, un canal simulado en pocas líneas permite probar la detección y los reintentos de los temas siguientes con la tasa de error y la longitud de ráfaga que se quiera, antes de depender de un cable que falla una vez por hora.

11 · Exploración interactiva

Laboratorio: tasa de error, ruido, canal, reflexiones y rebote

El laboratorio tiene cinco herramientas. La primera pasa de la tasa de error de bit a la de trama y al tiempo entre tramas dañadas. La segunda calcula la tasa de error de bit a partir del margen y del ruido. La tercera simula un canal con errores aislados o en ráfagas. La cuarta calcula las reflexiones de una línea. La quinta compara los métodos de antirrebote de un contacto.

1. De la tasa de error de bit a la de trama

Bits por trama—
Tramas dañadas—
Tramas intactas—
Entre bits errados—
Entre tramas dañadas—
Veredicto—

Escribí la tasa de error de bit y el largo de la trama.

2. Ruido, margen y tasa de error

Margen—
Ruido efectivo—
Margen en desviaciones—
Tasa de error de bit—
Ruido máximo para 10^−9—
Veredicto—

Elegí la señal y el ruido.

3. Simular un canal con errores

Bits errados—
Tramas dañadas—
Con errores aislados, la teoría—
Daño por trama dañada—
Lectura—

Elegí la tasa de error y el largo de las ráfagas.

4. Reflexiones en una línea

Coeficiente de reflexión—
Primera onda en la carga—
Viaje de ida y vuelta—
Largo crítico—
Terminación—
Veredicto—

Elegí el cable, la carga y el flanco.

5. Rebote de un contacto y su antirrebote

Antirrebote por programa—
Pulsaciones que distingue—
Antirrebote por hardware (RC)—
Detalle del RC—
Veredicto—

Elegí el rebote y el filtro.

En la herramienta 1, la trama ocupa 10 bits por byte (8N1) y las tramas se envían seguidas. En la 2, el ruido es gaussiano, el umbral está en el centro y el rechazo de modo común divide el ruido. En la 3, cada ráfaga arranca con probabilidad igual a la tasa dividida por su largo, de modo que la tasa de bits errados es la misma: cambia cómo se agrupan. En la 4, el cable propaga a 5 ns por metro y la línea es crítica si supera el tiempo de subida dividido por 30 ns/m. En la 5, el filtro RC se mide hasta cruzar el 70 % de la alimentación.

Recorrido guiado

  1. En la herramienta 1, con tasa 1e-5, 10 bytes y 9600 baudios: 100 bits por trama, 0,10 % de tramas dañadas (999 de cada 1000 intactas) y una trama dañada cada 10,4 s. Con 1e-4: 1,00 %. Con 1e-4 y 255 bytes: 22,5 % (775 de cada 1000 intactas). Con 1e-3 a 115 200 baudios: 9,52 % y una trama dañada cada 9,12 ms. Con 1e-2: más del 60 %, en rojo.
  2. En la herramienta 2, con 3,3 V y 0,3 V de ruido: margen de 1,650 V, 5,50 desviaciones (14,8 dB) y una tasa de 1,90 × 10−8; el ruido máximo para 10−9 es de 275,1 mV. Con 0,5 V de ruido: 3,30 desviaciones y 4,83 × 10−4 («margen escaso»). Con 1 V: 1,65 desviaciones y 0,0495, en rojo. Con 0,5 V y 20 dB de rechazo: 33 desviaciones, una tasa menor que 10−15, margen holgado.
  3. En la herramienta 3, con 1e-3, ráfaga 1, 10 000 tramas de 10 bytes y semilla 1: 1022 bits errados y 965 tramas dañadas (9,65 %), contra 952 que da la teoría. Con ráfaga 8: 928 bits y 123 tramas (1,23 %), con 7,54 bits errados por trama dañada. Con ráfaga 32: solo unas 40 tramas. Cambiá la semilla (2, 3) para ver la dispersión: con ráfagas, 119 tramas con la semilla 2.
  4. En la herramienta 4, con Z0 = 120 Ω, carga abierta, 100 m y flanco de 50 ns: Γ = 1,000, 200 % de tensión en la carga, 1000 ns de ida y vuelta, largo crítico 1,7 m (superado) y «reflexiones importantes» en rojo. Con carga 120: Γ = 0, «línea larga pero bien adaptada». Con 60: Γ = −0,333 y 67 %. Con 0: Γ = −1 y 0 %. Con 1 m de cable y la carga abierta: no supera el largo crítico, el efecto es pequeño.
  5. En la herramienta 5, con rebote de 5 ms, lecturas cada 1 ms, 10 lecturas iguales, 10 kΩ y 1 µF: 10 ms de espera (cubre el rebote), 100 pulsaciones por segundo, τ = 10 ms y el 70 % a los 12,04 ms: cubierto por software y por hardware. Con 3 lecturas: 3 ms, no cubre el rebote; queda el hardware. Con 0,1 µF y 10 lecturas: el RC cruza en 1,20 ms y no cubre; queda el programa. Con un rebote de 20 ms: ni uno ni otro, en rojo.
Desafío: el bus que falla cuando arranca el compresor

Un bus RS-485 de 300 m, a 9600 baudios, tiene 20 sensores que el maestro sondea cada segundo con tramas de 10 bytes. Funciona bien casi todo el día, pero cuando arranca el compresor de la planta (dos o tres veces por hora) se pierden tramas durante unos minutos. Se instaló un medidor como el de la sección 9. Con las herramientas y lo visto: (1) Los datos: el medidor muestra 0 tramas dañadas la mayor parte del tiempo, y entre un 30 % y un 60 % durante los minutos del arranque, y los errores se reparten entre todos los nodos. Que sea cíclico, ligado a un evento y común a todos apunta a una interferencia (sección 2), no a un cable, un nodo ni al margen del bus. (2) No es una tasa constante: si durante el arranque la tasa de error de bit fuera 10−2, la herramienta 1 daría un 63 % de tramas dañadas, coherente con lo medido. Pero el promedio de todo el día sería de décimas de porcentaje y escondería el problema: lo que importa es la distribución (sección 5). (3) Los reintentos solos no lo arreglan: con un 63 % de pérdida, un reintento inmediato falla con probabilidad 0,63 de nuevo (el segundo cae dentro de la misma ráfaga), y con cuatro intentos fallan todos en un 16 % de los casos. Hay que esperar a que pase el evento, con intervalos crecientes. (4) La causa se ataca en el cable: par trenzado blindado con el blindaje a tierra en un solo extremo; cable de datos separado de los de potencia (al menos 30 cm, y cruzando a 90° cuando hay que cruzar); filtro en la salida del variador del compresor; terminación de 120 Ω en ambos extremos con polarización; transceptor aislado si hay diferencia de masas. (5) El protocolo completa: CRC de 16 bits en lugar de la suma de un byte (tema 44), números de secuencia y confirmaciones (tema 45), y una alarma si pasan más de cierto número de intentos fallidos. Es el contenido de los temas 43 a 47 aplicado a un mismo problema.

12 · Comprensión

Confusiones frecuentes

«Si no recibo ningún error del UART, los datos llegaron bien»

El UART solo se da cuenta de dos cosas: que el bit de parada no llegó en alto, o que la paridad no cierra. Un cambio que deja el byte con la forma correcta (un bit cambiado sin paridad, o dos bits cambiados con ella) pasa sin aviso. Por eso las tramas llevan su propia verificación (suma o CRC).

«Una tasa de error de bit de 10⁻⁵ es despreciable»

Depende del largo de la trama y de la velocidad. Con tramas de 255 bytes se dañan 2,5 de cada 100, y a 9600 baudios con tramas de 10 bytes aparece una trama dañada cada diez segundos. «Pocos» errores por bit son muchos por hora.

«Con ráfagas se pierden más datos que con errores aislados»

Con la misma tasa de error de bit, es al revés: los errores se amontonan en pocas tramas. Con 10−3 y tramas de 10 bytes, se dañan el 9,5 % de las tramas con errores aislados y el 1,2 % con ráfagas de 8 bits. A cambio, cada trama dañada queda peor, y los reintentos inmediatos fallan juntos.

«Si el enlace anduvo diez minutos sin errores, es confiable»

Con una tasa baja casi no hay datos en diez minutos. Hay que medir durante horas o días, en las condiciones peores (con las máquinas encendidas) y con la velocidad definitiva. Y los errores en ráfagas pueden llegar una vez por hora.

«Agregar un reintento resuelve cualquier error»

Resuelve los aleatorios, no los sistemáticos: si una línea sin terminar daña siempre la misma trama, reenviarla la daña igual. Y con una interferencia larga, el segundo intento cae dentro del mismo evento. Primero se arregla la causa; los reintentos cubren el resto.

«El ruido es culpa del cable: cambio el cable y listo»

Puede ser, pero antes hay que contar. El ruido también entra por la alimentación, las masas, las derivaciones, el mismo transceptor, o el origen puede no ser ruido sino reflexiones, baudios que no coinciden o un búfer que se desborda. Cada causa tiene su firma (sección 8).

«Mientras más rápido, mejor: la velocidad no afecta los errores»

Un bit más corto deja menos tiempo para promediar el ruido, deja pasar más ancho de banda de interferencia, redondea los flancos con la capacidad del cable y vuelve críticas más reflexiones. Bajar la velocidad es el primer remedio y no cuesta nada, si el caudal alcanza.

«Las reflexiones son un problema de las redes grandes»

Son de las líneas largas frente al flanco: depende del tiempo de subida. Un flanco de 2 ns en una pista de 10 cm ya es crítico; un flanco de 1 µs en 40 m también. A 9600 baudios en un bus industrial largo, con transceptores de flanco rápido, aparecen igual.

«El rebote del pulsador es un defecto de pulsadores baratos»

Lo tienen todos los contactos mecánicos, caros o baratos, con distinta duración (de 1 a 20 ms). Se resuelve en el diseño, con un filtro de hardware o de programa, no cambiando el pulsador.

13 · Práctica guiada

Predecí antes de comprobar

1. Tramas dañadas por hora

Un enlace a 9600 baudios envía sin pausa tramas de 20 bytes con una tasa de error de bit de 10−5. ¿Qué fracción se daña? ¿Cuántas por hora?

Ver solución

La trama tiene 20 × 10 = 200 bits en la línea. P = 1 − (1 − 10−5)200 ≈ 200 × 10−5 = 0,2 % (0,1998 %). A 9600 baudios salen 9600 / 200 = 48 tramas por segundo, 172 800 por hora, de las cuales se dañan unas 345: una cada 10 s.

2. Cuánto ruido soporta

Una señal de 5 V pico a pico con 0,5 V eficaces de ruido, ¿qué tasa de error de bit tiene? ¿Cuánto ruido soporta para llegar a 10−9? ¿Y si la señal es de 3,3 V?

Ver solución

El margen es 2,5 V y z = 2,5 / 0,5 = 5 (14 dB): la tasa es 2,9 × 10−7. Para 10−9 hace falta z ≈ 6 (5,998): el ruido máximo es 2,5 / 5,998 ≈ 417 mV. Con 3,3 V el margen es 1,65 V y el ruido máximo baja a 275 mV: menos señal, menos ruido tolerable, en la misma proporción.

3. El largo de la trama

Con una tasa de error de 10−4, ¿qué fracción de tramas se daña si miden 10, 64 y 255 bytes? ¿Cuántos envíos hacen falta en promedio, por trama entregada, con 255 bytes?

Ver solución

Bits: 100, 640 y 2550. P = 1 − (1 − 10−4)N: 1,0 %, 6,2 % y 22,5 %. Con 255 bytes se necesitan en promedio 1 / (1 − 0,225) = 1,29 envíos por entrega, el 29 % más de tráfico. Con 10 bytes, 1,01. Por eso en enlaces con errores conviene partir los mensajes largos, a costa de repetir la estructura (tema 42).

4. Ráfagas

Con una tasa de error de bit de 10−3 y tramas de 10 bytes, un canal con errores aislados daña el 9,5 % de las tramas. Si los errores llegan en ráfagas de 8 bits, ¿qué fracción se daña, aproximadamente?

Ver solución

Las ráfagas arrancan con probabilidad 10−3 / 8 = 1,25 × 10−4 por bit. Una ráfaga toca una trama si arranca dentro de sus 100 bits o en los 7 anteriores (si cruza el límite): 107 posiciones × 1,25 × 10−4 ≈ 1,3 %. La herramienta 3 da 1,2 % (123 de 10 000). Los mismos bits errados dañan una séptima parte de las tramas, y cada trama dañada lleva unos 7 o 8 bits cambiados.

5. Reflexión

Un cable de 120 Ω termina en una carga de 60 Ω. ¿Cuál es el coeficiente de reflexión y qué tensión ve la carga en el primer instante, ante un escalón de 1 V? ¿Qué resistencia habría que poner en paralelo para eliminar la reflexión?

Ver solución

Γ = (60 − 120) / (60 + 120) = −0,333. La carga ve 1 + Γ = 0,667 V al principio, y un tercio del escalón vuelve invertido por el cable. Para adaptar hay que lograr una carga de 120 Ω: la resistencia en paralelo R con 60 Ω debe dar 120 Ω, y eso es imposible (un paralelo siempre es menor que el menor). Hay que cambiar la carga o poner en serie una resistencia de 60 Ω. Los 60 Ω aparecen en un bus RS-485 como la carga que ve el emisor con las dos terminaciones de 120 Ω en paralelo; pero la terminación de cada extremo sigue siendo de 120 Ω.

6. Largo crítico

Un transceptor tiene un tiempo de subida de 20 ns. ¿Desde qué largo de cable hay que terminar la línea? ¿Qué cambia si se usa un transceptor de flancos limitados de 1 µs?

Ver solución

Lcrítico = 20 ns / (6 × 5 ns/m) = 0,67 m: casi cualquier bus real es crítico. Con flancos de 1 µs: 1000 / 30 = 33 m: los tramos cortos no necesitan terminación. Por eso los transceptores RS-485 de baja velocidad con flancos limitados son más tolerantes a una mala instalación, y los rápidos exigen terminar siempre.

7. Antirrebote

Un pulsador rebota hasta 8 ms y se lee cada 2 ms. ¿Cuántas lecturas iguales seguidas hay que pedir? ¿Qué filtro RC con 10 kΩ lo cubre? ¿Cuántas pulsaciones por segundo distingue el filtro de programa?

Ver solución

Por programa: N × 2 ms debe superar los 8 ms, así que N ≥ 5 (10 ms; con N = 4 son justo 8 ms, sin margen). Distingue como máximo 1000 / 10 = 100 pulsaciones por segundo. Por hardware: 1,204 · τ ≥ 8 ms ⇒ τ ≥ 6,6 ms ⇒ C ≥ 6,6 ms / 10 kΩ = 0,66 µF; con 1 µF (τ = 10 ms) cruza el 70 % a los 12 ms. Con entrada Schmitt.

8. Diagnóstico

Un enlace RS-485 pierde tramas solo cuando se enciende la soldadora de otro taller, y siempre en todos los nodos a la vez. ¿Qué tipo de causa es, qué se mediría y qué se haría primero?

Ver solución

Es interferencia electromagnética (errores en ráfagas, ligados a un evento, comunes a todos los nodos), no un problema de margen ni de un nodo. Se registran las horas de los errores y se las compara con la soldadora; con un osciloscopio, se mira el ruido sobre el bus en esos momentos. Se actúa primero sobre el cable (par trenzado blindado a tierra en un extremo, separación de los cables de potencia, terminación y polarización) y recién después sobre el protocolo (CRC y reintentos espaciados). Bajar la velocidad también ayuda, pero no soluciona el origen.

14 · Síntesis

Ideas para recordar

  • El receptor decide cada bit comparando una magnitud física con un umbral, y el mundo la altera: ruido, interferencias, atenuación, reflexiones, rebotes, desvío de reloj, colisiones. Cuando el ruido supera el margen, el bit se lee mal y nadie avisa: el UART entrega un byte válido pero distinto.
  • Las causas dejan firmas distintas. Los errores aleatorios (ruido térmico, EMI) se reducen y se toleran; los sistemáticos (línea sin terminar, baudios que no coinciden, rebotes) se repiten igual y se arreglan. Se mide antes de arreglar: contar por nodo, por hora y por velocidad.
  • Desde el programa, los errores se ven como bits cambiados, ráfagas, errores de trama o de paridad, bytes fantasma o perdidos, tramas truncadas, perdidas o duplicadas. El peor es el que no se detecta, y la verificación nunca lo reduce a cero.
  • Con ruido gaussiano, la tasa de error de bit es Q(z) = ½·erfc(z/√2) con z = margen / ruido. La curva es empinada: z = 3 da 10−3, z = 5 da 3 × 10−7 y z = 6 da 10−9. Un poco de margen cambia órdenes de magnitud. La señal diferencial, el blindaje y menos velocidad lo aumentan.
  • Una trama de N bits se daña con probabilidad 1 − (1 − p)N ≈ N·p: las tramas largas sufren más y los reintentos cuestan 1/(1 − P) envíos. La tasa de error de bit casi nunca se mide directamente: se mide la de tramas, durante mucho tiempo.
  • Los errores reales llegan en ráfagas. Con la misma tasa de error de bit, las ráfagas dañan menos tramas pero más fuerte, y los reintentos inmediatos fallan juntos. La detección tiene que cubrir ráfagas (CRC) y los reintentos tienen que esperar.
  • Un flanco que llega a una carga distinta de Z0 se refleja con Γ = (ZL − Z0)/(ZL + Z0). Importa si la línea es larga frente al flanco (L > tsubida/(6 · 5 ns/m)). Se resuelve con terminación en los extremos, derivaciones cortas y flancos controlados.
  • Un contacto mecánico rebota de 1 a 20 ms, y cada rebote es un pulso real. El antirrebote, por programa (lecturas iguales seguidas) o por hardware (RC con entrada Schmitt), cambia tiempo por confiabilidad. Los errores se contienen en capas: el cable primero, la velocidad y el nivel con margen, la detección, el reintento, la corrección y la validación en la aplicación.

¿Listo para el siguiente tema?

Antes de avanzar, calculá qué fracción de tramas de 32 bytes se dañan con una tasa de error de bit de 10−5 y cada cuántos segundos ocurre a 19 200 baudios; explicá por qué un bus RS-485 que falla solo cuando arranca un motor es un problema de interferencia y no de margen, y qué mirarías primero; y decí qué pasaría con una línea de 120 Ω terminada en una resistencia de 60 Ω y qué coeficiente de reflexión tiene. Si podés justificar las tres respuestas, entendés de dónde vienen los errores.

En el próximo tema, detección de errores, se estudian las herramientas del paquete para saber que un error ocurrió: el bit de paridad, la suma de verificación, el CRC-8 y el CRC-16, cómo se calculan y cuántos errores dejan pasar. Es la cola de la trama que ya venimos usando, vista por dentro.