← Índice del curso

Sensores y Actuadores · Tema 47

Cierre y puente a la comunicación

Cuarenta y seis temas después, un programa sabe medir el mundo, decidir y actuar sobre él sin bloquearse y sin hacer daño cuando algo falla. Este último tema hace tres cosas: repasa la cadena completa para que las piezas queden conectadas entre sí, junta las buenas prácticas y los errores más caros del curso en una lista de verificación que sirve para el próximo proyecto, y se asoma a lo que viene: cuando los dispositivos dejan de estar en la misma placa y empiezan a hablarse, aparecen las velocidades, las distancias, los errores de transmisión y los enlaces que se caen, que es el tema del curso de Comunicación.

01 · Punto de partida

Lo que recorrimos

El curso siguió el camino de una señal, primero hacia el software y después de vuelta al mundo. Nueve bloques:

Los nueve bloques del curso y la idea central de cada uno.
BloqueTemasIdea central
1 · Fundamentos de sensores1 a 5Un sensor no mide la realidad: entrega una señal con rango, resolución y error, que se acondiciona, se calibra y se filtra.
2 · Entradas digitales y de umbral6 a 8Un contacto rebota y un umbral necesita histéresis: lo robusto es leer el cambio estable, no el nivel instantáneo.
3 · Temperatura y humedad9 a 13Cada sensor de temperatura es un compromiso entre costo, exactitud, rango y electrónica; la humedad depende de la temperatura.
4 · Luz y color14 a 16La luz se mide con respuestas no lineales y saturables; el ojo (y la planta) no responden como el sensor.
5 · Distancia y movimiento17 a 21El tiempo de vuelo y la inercia dan distancia y orientación, con dependencias (temperatura, superficie, deriva) que hay que conocer.
6 · Presión, sonido, magnetismo y posición22 a 26Magnitudes pequeñas piden amplificación; las posiciones y velocidades se cuentan con encoders.
7 · Actuadores de potencia y movimiento27 a 34El pin no es una fuente de potencia: transistor, diodo de rebote, drivers, y movimientos con rampas y lazo cerrado.
8 · Salidas visuales y sonoras35 a 39Mostrar y avisar tiene sus propias cuentas: corriente, percepción, multiplexación, memoria de video y resonancia.
9 · Control desde software y proyectos40 a 46Interfaces limpias, tareas sin bloqueos, control P y PID, diseño para la falla, y dos proyectos que lo reúnen todo.

Lo que une los nueve bloques no es una lista de componentes (las hojas de datos cambian cada año), sino un modo de pensar: cada pieza física tiene un modelo con límites; esos límites se calculan antes de soldar; el software debe desconfiar de lo que lee, no bloquear mientras espera y llevar el sistema a un estado seguro cuando algo falla; y todo se verifica con números, no a ojo. Esa cadena de ideas es lo que se repasa ahora.

02 · El mapa

La cadena completa

De un fenómeno físico a un efecto físico: cada etapa, qué la limita y dónde se vio.
EtapaQué haceQué la limitaTemas
1 · TransductorConvierte el fenómeno en una señal eléctricaRango, sensibilidad, resolución, tiempo de respuesta, autocalentamiento1, 2, 9 a 12, 14 a 26
2 · AcondicionamientoDivide, amplifica, filtra, adapta nivelesImpedancia, ruido, ancho de banda, niveles de 3,3 y 5 V4
3 · ConversiónPasa a cuentas o a un dato digitalResolución y referencia del ADC, tiempo de conversión, errores del bus3, 12
4 · Software de mediciónCalibra, filtra y validaDeriva, ruido, valores centinela, datos viejos5, 8, 44
5 · DecisiónCompara con la consigna y calcula la ordenRetardo, ruido, saturación, error en régimen42, 43
6 · PotenciaConvierte la orden del pin en energíaCorriente del pin, picos inductivos, disipación27 a 30
7 · ActuadorMueve, ilumina, suena o muestraZona muerta, desgaste, resonancia, pérdida de pasos, consumo30 a 39
8 · Efecto y realimentaciónEl mundo responde y el sensor lo mideInercia, retardo, perturbaciones31, 34, 45, 46

Tres aspectos transversales atraviesan toda la cadena: el tiempo (tareas periódicas, millis(), planificación; tema 41), la arquitectura (drivers, interfaces, configuración; tema 40) y la seguridad (validación, límites, perro guardián, modos; tema 44). Cuando algo no anda, el diagnóstico es recorrer la cadena de izquierda a derecha y preguntar en cada etapa: ¿qué entra?, ¿qué sale?, ¿cuál es su límite? La mayoría de los fallos del curso se resolvieron así: un valor que sale del ADC antes de culpar al programa, un pico de corriente antes de culpar al microcontrolador, un tiempo de espera oculto antes de culpar al sensor.

03 · Entradas

Sensores: repaso por magnitud

Qué se mide, con qué, y la trampa que hay que recordar.
MagnitudSensores típicosTrampa principalTemas
Contacto y umbralPulsador, final de carrera, reed, optointerruptorRebotes; entrada flotante (pull-up); cable cortado que se lee como «libre»6, 7, 8, 24
TemperaturaNTC, LM35/TMP36, RTD, termopar, DS18B20, SHT31No linealidad, autocalentamiento, 85 °C de arranque y −127 °C de falla9 a 13
HumedadDHT22, SHT31, capacitivos de sueloDepende de la temperatura (punto de rocío); deriva en 100 %12, 13, 45
Luz y colorLDR, fotodiodo, BH1750, TCS34725Saturación; lux no son fotones; realimentación de la propia luz14 a 16, 45
DistanciaHC-SR04, Sharp, VL53L0XTemperatura y superficie; ecos cruzados; «sin eco» no es «libre»17, 18, 46
Presencia y movimientoPIR, acelerómetro, giroscopio, IMURetardos del PIR; deriva del giroscopio; ruido del acelerómetro19 a 21
Presión y fuerzaFSR, galgas con HX711, BMP280Deriva térmica; calibración con una referencia22
SonidoMicrófono MEMS o electretLa señal es alterna: se trabaja con la envoltura23
Posición y velocidadEncoder en cuadratura, magnéticoCuentas perdidas, resolución de velocidad, deriva de la odometría25, 26, 46

Tres reglas valen para todos: calibrar contra una referencia (offset y ganancia, tema 5), filtrar sin retardar de más (la mediana para picos, el exponencial para ruido) y validar antes de usar (rango, tasa, congelamiento, edad; tema 44). Y a la hora de elegir un sensor, el orden de las preguntas es: ¿qué rango y qué resolución necesito?, ¿qué exactitud?, ¿qué tiempo de respuesta?, ¿qué interfaz (analógica, digital, bus)?, ¿qué ambiente (humedad, sol, polvo, temperatura)? y ¿qué pasa cuando falla?

04 · Salidas

Actuadores: repaso por carga

Qué se maneja, con qué y la trampa que hay que recordar.
CargaInterfaz de potenciaTrampa principalTemas
LED de señalResistencia, PWMSin resistencia se quema; el ojo es logarítmico (gamma)35
Tiras y matrices de LEDsWS2812, APA102, multiplexadoConsumo y caída de tensión; tiempos de un hilo; bloqueo de interrupciones35, 36
Displays y pantallasDrivers, I2C, SPITiempos de actualización; parpadeo; memoria de video37, 38
ZumbadoresPin o transistor, tone()Activo frente a pasivo; resonancia; timers compartidos39
Cargas de continua (solenoides, ventiladores, lámparas)MOSFET con diodo de rebotePico inductivo; corriente del pin; disipación27, 29
Cargas de redRelé, SSR, contactorAislamiento; desgaste del relé; el SSR falla en corto28, 44
Motor de continuaPuente H, PWM, encoderZona muerta; corriente de arranque; batería que baja30, 31, 46
ServoPulso de 1 a 2 ms cada 20 msFuente propia; límites mecánicos32
Paso a pasoA4988, DRV8825, rampasPérdida de pasos silenciosa; corriente del driver; homing33, 34

Las reglas comunes: el pin da señal, no potencia (unos 20 mA); cada carga inductiva lleva su diodo de rebote; el reposo se escribe antes de ser salida; cada actuador tiene un estado seguro y un tiempo máximo si puede hacer daño; y cada orden se verifica con su efecto (si se manda calentar y no sube la temperatura, algo falla).

05 · Software

Patrones de software

El problema, el patrón que lo resuelve y dónde se vio.
ProblemaPatrónTemas
Cambiar un sensor obliga a tocar toda la aplicaciónInterfaz con unidades físicas y estado; driver detrás; raíz de composición40
El programa se detiene esperandoTareas periódicas con millis(); lectura por etapas (iniciar, lista, leer)41
Una tarea debe recordar dónde estabaMáquina de estados con acciones de entrada y tiempo límite41, 44, 46
Una medida ruidosa hace vibrar la salidaFiltro y histéresis (≥ 2,5 a 3 σ)5, 42
El control no llega a la consigna o se pasaPI con anti-windup; PD en procesos rápidos; sin D en los lentos y ruidosos43
El sensor miente o se desconectaRango, tasa, congelamiento, edad, redundancia44
El actuador sigue activo tras una fallaEstado seguro; protección independiente en serie; perro guardián44
Varios comportamientos pelean por la misma salidaPrioridades explícitas e interbloqueos45, 46
Cuesta probar sin la placaDrivers simulados, funciones puras, fallas inyectadas40, 44

La arquitectura del curso se resume en una frase: una aplicación que solo conoce interfaces, drivers que esconden el hardware, un lazo que no espera, y una capa de seguridad que no depende de lo que protege.

06 · Lecciones

Los errores más caros

De todo lo visto, estos diez errores son los que más tiempo, componentes o seguridad cuestan; casi todos los proyectos que fallan terminan en alguno de ellos:

  1. Un LED o una carga conectados al pin sin resistencia o sin driver (temas 27 y 35): se queman el LED o el pin. Un pin da unos 20 mA.
  2. Una carga inductiva sin diodo de rebote (temas 27, 28 y 29): el pico de tensión mata al transistor o reinicia el microcontrolador.
  3. Un delay() en medio del programa (tema 41): un sensor de 750 ms bloquea 75 ciclos de un lazo de 10 ms.
  4. Comparar millis() con un instante absoluto (tema 41): falla a los 49,7 días, cuando ya nadie está mirando.
  5. Un valor centinela tomado por un dato (temas 40 y 44): el 85 °C de arranque del DS18B20 o el −127 por falta de sensor se leen como temperaturas reales.
  6. Una integral sin anti-windup (tema 43): la temperatura se pasa 13 °C al arrancar el horno.
  7. Un control todo o nada sin histéresis y con ruido (tema 42): el relé conmuta más de mil veces por hora y muere en semanas.
  8. Un límite de seguridad que depende de lo que protege (tema 44): el límite por software con el mismo sensor no ve al sensor que miente, ni abre un relé pegado.
  9. Pines flotantes al reiniciar (tema 44): los actuadores reciben niveles indefinidos hasta que arranca el programa.
  10. Creer que lo que funciona en el escritorio funciona en el campo (todo el curso): sin calibrar, sin ruido real, sin batería baja, sin fallas inyectadas y sin ensayo largo con registro.

07 · Antes de encender

Lista de verificación de diseño

Una lista corta que se repasa antes de conectar la alimentación por primera vez y antes de dar por terminado un proyecto:

Lista de verificación.
ÁreaPregunta
Eléctrica¿Cada carga está dentro de lo que su pin o su driver soporta? ¿Hay diodo de rebote, capacitores de desacople y masa común? ¿La fuente tiene 20 % de margen?
Señal¿Los niveles coinciden (3,3 y 5 V)? ¿Las entradas tienen pull-up o pull-down? ¿La referencia y la resolución del ADC alcanzan?
Sensores¿Están calibrados contra una referencia? ¿Se validan (rango, tasa, edad)? ¿Qué pasa con uno desconectado?
Tiempo¿No hay esperas bloqueantes ni delay? ¿Se midió el lazo más lento? ¿Las comparaciones de tiempo toleran la vuelta de millis()?
Control¿Hay histéresis o banda adecuada? ¿La integral tiene anti-windup? ¿El período de muestreo es constante y menor que el proceso?
Seguridad¿Cuál es el estado seguro de cada actuador? ¿Hay un límite independiente? ¿El perro guardián se alimenta solo si todo responde?
Arranque¿Los pines quedan en reposo durante el reinicio? ¿Hay autoprueba? ¿Se registra la causa del último reinicio?
Prueba¿Se probó cada falla (sensor, actuador, programa, tensión)? ¿Hubo un ensayo largo con registro?

Y algunos números del curso que conviene tener presentes: un pin da unos 20 mA; un ADC de 10 bits con 5 V resuelve 4,88 mV (uno de 12 bits con 3,3 V, 0,806 mV); un PWM de 8 bits avanza de a 0,39 %; un LED rojo a 5 V y 10 mA pide 330 Ω; millis() da la vuelta a los 49,7 días; un relé de 100 000 ciclos con una ventana de 10 s dura 278 horas (con 600 s, 1,9 años); 300 LEDs WS2812 tardan 9,3 ms por trama y a blanco pleno piden 18,3 A; una pantalla OLED completa por I2C a 400 kHz son unos 26 ms.

08 · El puente

Cuando los dispositivos se hablan

Hasta ahora todo estaba en una placa o a pocos centímetros: el microcontrolador leía sensores y movía actuadores por pines y buses cortos. Pero un sistema real crece: el sensor está a 20 metros del controlador, hay veinte nodos que reportar a una central, el robot se maneja desde un teléfono, el invernadero manda sus datos a la nube, dos microcontroladores se reparten el trabajo. Eso es comunicación, y es el tema del próximo curso.

Lo importante es que los principios no cambian, se trasladan. Casi todo lo aprendido tiene su equivalente en un enlace:

Del vocabulario del curso al de un enlace de comunicación.
En el cursoEn un enlace
Una lectura con valor, estado y edad (tema 40)Un mensaje con datos, número de secuencia y marca de tiempo
Rango, tasa y congelamiento del sensor (tema 44)Validación de longitud, de rango y de CRC del mensaje
Un dato viejo que parece actualUn mensaje repetido o retrasado: se detecta con la secuencia y la edad
Perro guardián y tiempo límite de cada espera (tema 44)Latido (heartbeat) y tiempo límite de cada respuesta
Estado seguro ante una fallaEstado seguro ante un enlace caído: el sistema no puede depender de que la red funcione
Lectura por etapas sin bloqueos (tema 41)Recepción byte a byte con una máquina de estados
Drivers detrás de una interfaz (tema 40)Capas de protocolo: físico, enlace, aplicación
No confiar en un sensorNo confiar en un dato remoto: se limita, se valida y se autentica

Y aparecen problemas nuevos: la latencia (un dato llega tarde: un lazo de control por red necesita cuentas del retardo, tema 42), la pérdida, duplicación y corrupción de mensajes, la pérdida de sincronía (media trama recibida), el ancho de banda limitado, el ruido en cables largos y la seguridad (¿quién puede mandarle una orden al robot o al calefactor?). La regla de diseño más importante se hereda del tema 44: la red es un extra, no una dependencia de la seguridad; el sistema debe poder quedar solo y estar seguro.

09 · Los cables

Buses: comparación, presupuesto y límites

Ya usamos cuatro buses sin detenernos (I2C para sensores y pantallas, SPI para pantallas TFT, 1-Wire para el DS18B20, UART para el puerto serie). Esta es la comparación que sirve para elegir (valores de referencia, que dependen de los componentes y del cableado):

Buses habituales entre microcontroladores y periféricos.
BusCables de señalVelocidad típicaDistancia típicaDispositivosUso
UART (TTL)2 (TX y RX)9600 a 115 200 baudios (hasta ~1 Mbit/s)1 a 2 m2 (punto a punto)GPS, Bluetooth, depuración
I2C2 (SDA, SCL)100 kHz, 400 kHz, 1 MHz< 1 m (≤ 400 pF)Hasta ~112 por dirección de 7 bitsSensores, OLED, RTC
SPI3 + un CS por dispositivo1 a 50 MHzDecenas de cmVarios, con su CSTFT, tarjetas SD, ADC
1-Wire1~16 kbit/s~100 m con cuidadoMuchos (identificador de 64 bits)DS18B20
RS-4852 diferenciales100 kbit/s a 1200 m; 10 Mbit/s a 12 mHasta 1200 m32 (o más)Industria, Modbus
CAN2 diferenciales1 Mbit/s a 40 m; 125 kbit/s a 500 m; 50 kbit/s a 1 kmHasta 1 kmMuchos nodosAutomoción, robótica

El presupuesto de un bus es una cuenta de bytes: el tiempo que cuesta un mensaje por la cantidad de mensajes por segundo es la ocupación del bus, y no debería pasar de un 50 a 60 %. Con un UART a 115 200 baudios (10 bits por byte), la capacidad útil es de 11 520 B/s; un I2C cuesta 20 tiempos de bit por transacción más 9 por byte; un SPI, 8 por byte:

Ocupación del bus según el flujo (100 % es el límite; la carga incluye todos los bytes del mensaje).
FlujoUART 115 200I2C 100 kHzI2C 400 kHzSPI 8 MHz
Invernadero: 30 B cada 10 min0,0 %0,0 %0,0 %0,0 %
Robot: telemetría de 24 B a 50 Hz10,4 %11,8 %3,0 %0,1 %
IMU de 6 ejes: 12 B a 1 kHz104,2 %128,0 %32,0 %1,3 %
OLED completa: 1024 B a 30 cuadros/sno cabeno cabe69,3 %3,1 %

La tabla enseña por qué los datos de pocos bytes y baja frecuencia van por cualquier cosa (el invernadero), y por qué los flujos altos exigen un bus rápido (una IMU a 1 kHz no cabe en un UART de 115 200 baudios ni en un I2C de 100 kHz; una pantalla completa pide SPI). Dos límites físicos merecen atención:

  • I2C: las resistencias de pull-up y la capacidad del bus. La señal sube con una constante R·C: tsubida ≈ 0,8473 · Rp · Cb, y la norma exige menos de 1000 ns a 100 kHz, 300 ns a 400 kHz y 120 ns a 1 MHz, con un máximo de 400 pF. El pull-up tiene un máximo (para que suba a tiempo) y un mínimo (para que el dispositivo pueda bajarla con 3 mA: (VDD − 0,4 V) / 3 mA, 967 Ω con 3,3 V). Con 100 pF a 400 kHz, la ventana es de 967 a 3541 Ω; con 400 pF a 400 kHz, no hay ninguna resistencia que sirva (hay que bajar la velocidad, acortar los cables o usar un amplificador de bus). Con 4,7 kΩ y 100 pF, la subida es de 398 ns; con 10 kΩ y 400 pF, 3389 ns: demasiado lenta para cualquier modo.
  • UART: los baudios no coinciden exactamente. Cada byte se muestrea al medio de cada bit, y el error se acumula a lo largo de los 10 bits de un byte (8N1): el desajuste entre los dos relojes no puede superar 0,5 / 9,5 = 5,26 % (4,76 % con paridad), y en la práctica conviene tener menos de un 2 a 3 %. Un AVR de 16 MHz genera 115 200 baudios con un divisor entero: 111 111 (−3,55 %) o, con U2X, 117 647 (+2,12 %); un AVR sin U2X hablando con otro con U2X tiene un desajuste de −5,6 %, ya fuera de límite. A 9600 baudios, el error es de apenas +0,16 %, por eso es la velocidad «que siempre anda».

10 · Programación

Una trama con CRC y supervisión del enlace

Un enlace serie entrega bytes sueltos, sin límites de mensaje ni garantías. Hay que agregar una trama: un delimitador de inicio, la longitud, la carga útil, una suma de verificación y un delimitador de fin. El receptor la procesa byte a byte con una máquina de estados (sin bloquear, tema 41), recupera la sincronía si se corta una trama, aplica solo las tramas completas con CRC correcto, ignora las repetidas (número de secuencia) y limita lo que recibe antes de usarlo. Si pasan más de 500 ms sin una trama válida, el enlace se da por caído y el robot queda detenido (tema 44).

// ---------- Una trama simple: STX | longitud | carga útil | CRC16 | ETX ----------
constexpr uint8_t STX = 0x02, ETX = 0x03, MAX_CARGA = 32;

uint16_t crc16(const uint8_t *d, uint8_t n) {                    // CRC-16/CCITT-FALSE: polinomio 0x1021, valor inicial 0xFFFF
    uint16_t crc = 0xFFFF;
    while (n--) {
        crc ^= (uint16_t)(*d++) << 8;
        for (uint8_t i = 0; i < 8; i++) crc = (crc & 0x8000) ? (crc << 1) ^ 0x1021 : (crc << 1);
    }
    return crc;
}

void enviar(const uint8_t *carga, uint8_t n) {                   // telemetría: unos 2 ms para 24 bytes a 115 200 baudios
    uint16_t crc = crc16(carga, n);
    Serial.write(STX); Serial.write(n); Serial.write(carga, n);
    Serial.write((uint8_t)(crc >> 8)); Serial.write((uint8_t)(crc & 0xFF)); Serial.write(ETX);
}

// ---------- Recepción sin bloqueos: una máquina de estados que consume byte a byte ----------
enum class Rx : uint8_t { ESPERA_STX, LONGITUD, CARGA, CRC_ALTO, CRC_BAJO, ESPERA_ETX };
Rx rx = Rx::ESPERA_STX;
uint8_t carga[MAX_CARGA], largo = 0, indice = 0;
uint16_t crcRecibido = 0;
uint32_t ultimoByteMs = 0, ultimaTramaValidaMs = 0;

struct Comando { uint8_t secuencia; int16_t vIzq, vDer; };         // lo que llega por el enlace: velocidades en mm/s
uint8_t secuenciaPrevia = 0;

void tramaValida() {
    ultimaTramaValidaMs = millis();
    if (largo != sizeof(Comando)) return;                         // longitud inesperada: se ignora
    Comando c; memcpy(&c, carga, sizeof c);
    if (c.secuencia == secuenciaPrevia) return;                   // repetida: ya se aplicó
    secuenciaPrevia = c.secuencia;
    consignaIzq = constrain(c.vIzq, -400, 400);                   // nunca se confía en un dato remoto: se limita
    consignaDer = constrain(c.vDer, -400, 400);
}

void procesarByte(uint8_t b) {
    switch (rx) {
        case Rx::ESPERA_STX:  if (b == STX) rx = Rx::LONGITUD; break;
        case Rx::LONGITUD:    if (b == 0 || b > MAX_CARGA) rx = Rx::ESPERA_STX; else { largo = b; indice = 0; rx = Rx::CARGA; } break;
        case Rx::CARGA:       carga[indice++] = b; if (indice == largo) rx = Rx::CRC_ALTO; break;
        case Rx::CRC_ALTO:    crcRecibido = (uint16_t)b << 8; rx = Rx::CRC_BAJO; break;
        case Rx::CRC_BAJO:    crcRecibido |= b; rx = Rx::ESPERA_ETX; break;
        case Rx::ESPERA_ETX:
            if (b == ETX && crc16(carga, largo) == crcRecibido) tramaValida();      // solo una trama completa y con CRC correcto
            rx = Rx::ESPERA_STX;
            break;
    }
}

void tareaComunicacion() {                                        // cada vuelta del lazo; lee solo lo que ya llegó
    uint32_t ahora = millis();
    while (Serial.available()) { procesarByte(Serial.read()); ultimoByteMs = ahora; }
    if (rx != Rx::ESPERA_STX && (uint32_t)(ahora - ultimoByteMs) > 50) rx = Rx::ESPERA_STX;   // trama a medias: resincronizar
    if ((uint32_t)(ahora - ultimaTramaValidaMs) > 500) {          // enlace caído: sin órdenes recientes, estado seguro (tema 44)
        consignaIzq = consignaDer = 0;
    }
}

Una suma de verificación detecta los errores de transmisión; no los corrige. Un CRC de 16 bits detecta todos los errores en ráfaga de hasta 16 bits y, en errores aleatorios, deja pasar uno de cada 65 536. Para corregir, hay que retransmitir (con confirmaciones y tiempos límite) o usar códigos correctores, y para que nadie ajeno mande órdenes hace falta autenticación: todo eso es materia del curso de Comunicación.

11 · Analogía con programación

Presupuestos de bus, pull-ups, baudios y CRC

Calculamos los cuatro elementos del puente: la ocupación de cada bus con distintos flujos, las ventanas de resistencias de pull-up del I2C, el error de baudios de un AVR y la probabilidad de que un error de transmisión pase sin detectar según el tamaño del CRC. Al final, algunos de los números del curso.

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

# ---- 1. Presupuesto de un bus: ¿cabe el tráfico? ----
def t_uart(baudios, n):
    return n * 10 / baudios                                # 8N1: 10 bits por byte


def t_i2c(frecuencia, n):
    return (20 + 9 * n) / frecuencia                       # inicio, dirección, parada y 9 tiempos de bit por byte


def t_spi(frecuencia, n):
    return (n + 1) * 8 / frecuencia                        # un byte de comando y los datos


buses = (("UART 115 200", lambda n: t_uart(115200, n)), ("I2C 100 kHz", lambda n: t_i2c(100e3, n)),
         ("I2C 400 kHz", lambda n: t_i2c(400e3, n)), ("SPI 8 MHz", lambda n: t_spi(8e6, n)))
flujos = (("invernadero: 30 B cada 10 min", 30, 1 / 600), ("robot: telemetría de 24 B a 50 Hz", 24, 50),
          ("IMU de 6 ejes: 12 B a 1 kHz", 12, 1000), ("OLED completa: 1024 B a 30 cuadros/s", 1024, 30))
print("flujo                                     " + "".join(f"{nombre:>14s}" for nombre, _ in buses))
for nombre, n, tasa in flujos:
    celdas = []
    for _, tiempo in buses:
        uso = tasa * tiempo(n) * 100
        celdas.append(f"{uso:12.1f} %" if uso < 1000 else "      no cabe")
    print(f"{nombre:40s}" + "".join(f"{c:>14s}" for c in celdas))
print(f"capacidad útil de un UART a 115 200 baudios: {115200 / 10:.0f} B/s; un mensaje de 24 B tarda {t_uart(115200, 24) * 1000:.2f} ms")

# ---- 2. I2C: resistencias de pull-up y capacidad del bus ----
print()
for modo, t_max in (("100 kHz", 1000e-9), ("400 kHz", 300e-9), ("1 MHz", 120e-9)):
    for c_pf in (100, 200, 400):
        for vdd in (3.3, 5.0):
            r_max = t_max / (0.8473 * c_pf * 1e-12)
            r_min = (vdd - 0.4) / 0.003
            estado = f"{r_min:5.0f} a {r_max:6.0f} ohm" if r_max >= r_min else "imposible con una sola resistencia"
            if vdd == 3.3:
                print(f"{modo:8s} con {c_pf:3d} pF a {vdd} V: {estado}")
print("subida con 4,7 kΩ y 100 pF: %.0f ns; con 10 kΩ y 400 pF: %.0f ns" % (0.8473 * 4700 * 100e-12 * 1e9, 0.8473 * 10000 * 400e-12 * 1e9))

# ---- 3. UART: error de baudios ----
print()
print("error del divisor en un AVR (8N1):")
for f_mcu in (16e6, 8e6):
    for baudios in (9600, 57600, 115200, 230400):
        fila = []
        for u2x in (False, True):
            ubrr = round(f_mcu / ((8 if u2x else 16) * baudios) - 1)
            real = f_mcu / ((8 if u2x else 16) * (ubrr + 1))
            fila.append(f"{'U2X' if u2x else 'normal'}: {real:9.0f} baud ({(real / baudios - 1) * 100:+5.2f} %)")
        print(f"{f_mcu / 1e6:2.0f} MHz, {baudios:6d} baudios -> " + "   ".join(fila))
for nombre, bits in (("8N1", 10), ("8E1", 11)):
    print(f"desajuste máximo entre extremos con {nombre}: {0.5 / (bits - 0.5) * 100:.2f} % (en la práctica, menos del 2 al 3 %)")

# ---- 4. Mensajes con errores: la suma de verificación ----
print()
n, tasa = 24, 10                                           # bytes por mensaje, mensajes por segundo
for ber in (1e-5, 1e-6):
    p_mal = 1 - (1 - ber) ** (8 * n)
    for crc in (0, 8, 16):
        sin_detectar = p_mal * (2.0 ** -crc)
        por_hora = tasa * 3600 * sin_detectar
        print(f"BER {ber:.0e}, {n} B, {tasa} mensajes/s, CRC de {crc:2d} bits: {p_mal * 100:6.3f} % de mensajes con errores; sin detectar por hora: {por_hora:10.4f}")

# ---- 5. Algunos números del curso ----
print()
print(f"ADC de 10 bits con 5 V: {5 / 1024 * 1000:.2f} mV por cuenta; de 12 bits con 3,3 V: {3.3 / 4096 * 1000:.3f} mV")
print(f"millis() da la vuelta a los {2 ** 32 / 86_400_000:.2f} días; micros(), a los {2 ** 32 / 1e6 / 60:.1f} minutos")
print(f"PWM de 8 bits: paso de {100 / 255:.2f} %; LED rojo a 5 V y 10 mA: {(5 - 2.0) / 0.010:.0f} Ω (normalizada: 330 Ω)")
print(f"relé de 100 000 ciclos con una ventana de 10 s: {100_000 / (3600 / 10):.0f} h; con 600 s: {100_000 / (3600 / 600) / 24 / 365:.2f} años")
print(f"300 LEDs WS2812: {(300 * 24 * 1.25e-6 + 300e-6) * 1000:.1f} ms por trama; a blanco pleno, {300 * 0.060 + 0.3:.1f} A")

Resultado: una IMU de 6 ejes a 1 kHz ocupa el 104,2 % de un UART de 115 200 baudios, el 128,0 % de un I2C de 100 kHz y el 32,0 % de uno de 400 kHz; una OLED completa a 30 cuadros por segundo no cabe en los dos primeros y ocupa el 69,3 % del I2C rápido y el 3,1 % del SPI. Con 100 pF a 400 kHz y 3,3 V, el pull-up debe estar entre 967 y 3541 Ω; con 400 pF, no hay ninguno. Un AVR de 16 MHz a 115 200 baudios tiene un error de −3,55 % sin U2X y de +2,12 % con U2X; el desajuste máximo es del 5,26 % con 8N1. Con 24 bytes por mensaje, una tasa de error de bit de 10−5 y 10 mensajes por segundo, el 0,192 % de los mensajes llega con errores: sin CRC pasan 69 por hora; con CRC de 8 bits, 0,27; con CRC de 16 bits, 0,0011 por hora (uno cada 40 días).

12 · Exploración interactiva

Bus, I2C, UART y errores

El primer instrumento calcula la ocupación de un bus para un flujo de mensajes. El segundo, la ventana de resistencias de pull-up de un bus I2C. El tercero, el error de baudios entre dos extremos de un enlace UART. El cuarto, cuántos mensajes llegan con errores y cuántos pasan sin que se detecten según el CRC.

Instrumento 1: presupuesto de un bus

Tiempo por mensaje—
Tráfico · capacidad útil—
Ocupación del bus—
Mensajes por segundo como máximo—
Estado
—

Instrumento 2: resistencias de pull-up del I2C

Tiempo de subida—
Corriente que debe absorber el dispositivo—
Ventana de pull-up posible—
Estado
—

Instrumento 3: baudios del UART

Baudios reales del AVR · error—
Desajuste entre extremos · máximo teórico—
Desplazamiento al muestrear el último bit—
Estado
—

Instrumento 4: errores de transmisión y CRC

Mensajes con errores—
Con errores, por hora—
Sin detectar, por hora—
Tiempo medio entre errores sin detectar—
Estado
—

Recorrido guiado

  1. Con UART a 115 200 baudios, 24 bytes y 50 mensajes por segundo: 2,08 ms por mensaje y un 10,4 % de ocupación. Subí a 500 mensajes por segundo: no cabe, y el estado lo avisa.
  2. Con 12 bytes a 1000 mensajes por segundo (una IMU): 104 % por UART a 115 200 y 128 % por I2C de 100 kHz; con I2C de 400 kHz, 32 %; con SPI de 8 MHz, 1,3 %.
  3. Con 1024 bytes a 30 mensajes por segundo (una pantalla): por UART no cabe; por I2C de 400 kHz, 69 %; por SPI de 8 MHz, 3,1 %. (Con las transacciones cortas de las bibliotecas del tema 38, el I2C es algo más lento.)
  4. En el I2C, con 100 pF, 4,7 kΩ, 100 kHz y 3,3 V: subida de 398 ns y ventana de 967 a 11 802 Ω: correcto. Pasá a 400 kHz: 398 ns superan los 300 ns, y el estado avisa; la ventana es de 967 a 3541 Ω y 2,2 kΩ sirve.
  5. Con 400 pF y 400 kHz: la ventana no existe (el máximo, 885 Ω, es menor que el mínimo, 967 Ω): ningún pull-up alcanza. Hay que bajar la velocidad, acortar el bus o aislarlo con un amplificador de bus.
  6. En el UART, a 16 MHz y 115 200 baudios sin U2X: el AVR genera 111 111 baudios (−3,55 %), con margen bajo. Activá U2X: 117 647 (+2,12 %). Poné el otro extremo en +2,1 % con U2X desactivado: el desajuste (−5,6 %) pasa el límite del 5,26 % y hay errores de trama.
  7. A 9600 baudios el error es de +0,16 % con 8 o 16 MHz: es la velocidad que casi siempre funciona.
  8. En los errores de transmisión, con 24 bytes, tasa de error 10⁻⁵, 10 mensajes por segundo: 0,192 % de mensajes con errores (6,9 por hora). Sin CRC pasan todos sin detectar (69 por hora); con CRC de 8 bits, 0,27 por hora; con 16 bits, uno cada 40 días.
Desafío: telemetría de la flota de robots por RS-485

Diez robots como el del tema 46 mandan cada uno 24 bytes a 10 Hz a una central por un bus RS-485 compartido a 115 200 baudios (más una orden de la central, también de 24 bytes a 10 Hz a cada uno). ¿Cabe? Tráfico: 10 robots × 10 Hz × 24 B = 2400 B/s de telemetría y otros 2400 B/s de órdenes: 4800 B/s en total, contra 11 520 B/s: 41,7 %. Pero RS-485 es un bus compartido de un solo par: solo uno habla a la vez, y las colisiones se evitan con un protocolo (consulta y respuesta con la central como maestra, como Modbus). Con la consulta (≈ 8 bytes) y las respuestas, el tiempo total sube a quizá un 60 %, en el límite recomendado. Latencia: una vuelta completa a los diez robots son unos 100 ms; no sirve para un lazo de control, solo para supervisión: el control de cada robot sigue siendo local. Fallas: cada robot debe detenerse si no recibe una trama válida en 500 ms (como en el código de esta sección); la central debe marcar como «caído» a un robot que no responde, con reintentos limitados. El cableado: terminadores de 120 Ω en los extremos y topología de línea, no de estrella. La seguridad: una parada de emergencia que no dependa del bus (hardware). Es el curso de Comunicación en miniatura.

13 · Próximos pasos

Cómo seguir

  1. Construí los dos proyectos (el invernadero y el robot), aunque sea en versión reducida: nada reemplaza ver oscilar un lazo mal ajustado o un relé pegado en una prueba segura.
  2. Usá la lista de verificación en cada proyecto nuevo, antes de encenderlo, y guardá un registro de lo que falló: es el mejor material de aprendizaje.
  3. Armá tu propia biblioteca de drivers con las interfaces del tema 40, probados con sensores simulados; en unos pocos proyectos, rinde más que cualquier biblioteca de terceros que no conozcas.
  4. Medí antes de optimizar: el máximo del lazo, la ocupación de los buses, la corriente real, la temperatura de los transistores.
  5. Experimentá con las fallas (sensor desconectado, batería baja, programa colgado) mientras es barato y seguro hacerlo.
  6. Pasá al curso de Comunicación, donde se estudian en profundidad los buses y los protocolos: UART, I2C y SPI a fondo, RS-485 y CAN, Bluetooth, Wi-Fi y redes, y cómo proteger, confirmar y sincronizar los datos.
  7. Después, Sistemas Embebidos (el ciclo de vida de un producto), IoT (conectar todo a la red) y Robótica (el siguiente paso del robot móvil).

Si algo no anda, recorré la cadena (sección 2) etapa por etapa; si un proyecto crece, separá en capas; si no estás seguro de que es seguro, probá la falla.

14 · Comprensión

Confusiones frecuentes

«Con tantos sensores y actuadores, lo difícil es el programa»

Lo difícil casi siempre es la física: corrientes, picos, ruido, tiempos y límites. El programa más elegante falla si el pin se sobrecarga o el sensor cambia con la temperatura.

«Si funciona en la mesa, está terminado»

En la mesa no hay ruido real, batería baja, humedad, cables largos ni fallas. Un proyecto termina cuando pasó un ensayo largo con fallas inyectadas.

«La comunicación solo es un tema de protocolos»

También es de cuentas (ancho de banda, retardo, errores de baudios, capacidad del cable), de robustez (enlaces que se caen, mensajes repetidos o viejos) y de seguridad, los mismos principios del curso aplicados a un canal.

«Un CRC protege contra cualquier error»

Detecta, con una probabilidad alta pero no del 100 %, los errores de transmisión; no los corrige ni protege de un mensaje válido pero malicioso o desactualizado. Para eso hacen falta retransmisión, secuencia y autenticación.

«Con la red conectada, el control puede ser remoto»

Un lazo rápido depende de que el retardo y los cortes sean pequeños: el control crítico es local y la red solo supervisa y ajusta consignas. Sin enlace, el sistema debe ser seguro por sí mismo.

«Un bus más rápido siempre es mejor»

Más velocidad exige mejor cableado (la capacidad y la subida en I2C, el ruido, el error de baudios) y menos distancia. Se elige la velocidad que alcanza con margen, no la máxima.

15 · Práctica guiada

Predecí antes de comprobar

1. Ocupación

Un sensor manda 16 bytes a 200 Hz por un UART a 57 600 baudios. ¿Qué ocupación tiene el enlace?

Ver solución

Tiempo por mensaje = 16 × 10 / 57 600 = 2,78 ms; × 200 = 55,6 %: dentro del 60 % recomendado, pero con poco margen.

2. Pull-up

Un bus I2C de 5 V a 100 kHz tiene 250 pF. ¿Entre qué valores debe estar el pull-up?

Ver solución

Máximo = 1000 ns / (0,8473 × 250 pF) = 4,72 kΩ; mínimo = (5 − 0,4) / 3 mA = 1,53 kΩ. Sirve 2,2 kΩ o 3,3 kΩ.

3. Baudios

Un AVR de 16 MHz genera 115 200 baudios con el divisor entero 8 (sin U2X): 16 000 000 / (16 × (8 + 1)). ¿Qué error tiene y se comunica con una PC exacta?

Ver solución

16 000 000 / 144 = 111 111 baudios: error de −3,55 %. Con una PC exacta, el desajuste es de 3,55 %, menor que el 5,26 % máximo: funciona, pero con poco margen frente al ruido.

4. CRC

Un mensaje de 32 bytes sobre un enlace con tasa de error de bit de 10⁻⁶, a 20 mensajes por segundo, con CRC de 16 bits. ¿Cuántos mensajes llegan con errores por hora y cuántos pasan sin detectar?

Ver solución

P(error) = 1 − (1 − 10⁻⁶)256 ≈ 2,56 × 10⁻⁴; por hora, 20 × 3600 × 2,56 × 10−4 ≈ 18,4 con errores; sin detectar: 18,4 / 65 536 ≈ 0,00028 por hora (uno cada 150 días).

5. Diseño

Un nodo manda una temperatura y una humedad (4 bytes) cada 30 s por un bus de 1 km. ¿Qué bus elegís y qué protecciones agregás?

Ver solución

El flujo es mínimo (0,13 B/s): lo que manda es la distancia, así que RS-485 (o CAN a baja velocidad), con terminadores. Protecciones: trama con longitud y CRC, número de secuencia, edad máxima del dato en el receptor y un tiempo límite sin mensajes que lo marque como «sensor caído».

6. Diagnóstico

Un robot comandado por Bluetooth sigue avanzando unos segundos después de que se apaga el teléfono. ¿Qué principio del curso falta y cómo se corrige?

Ver solución

Falta el estado seguro ante un enlace caído (tema 44) y la supervisión con tiempo límite: sin latido ni tramas válidas durante un tiempo corto (por ejemplo 500 ms), el robot debe detener los motores por sí mismo. Se agrega el tiempo límite de recepción y se verifica apagando el teléfono a propósito.

16 · Síntesis

Ideas para recordar

  • La cadena es: fenómeno, transductor, acondicionamiento, conversión, software de medición, decisión, potencia, actuador y efecto; cada etapa tiene un límite que se calcula antes de soldar.
  • Tres cosas atraviesan todo: el tiempo (tareas sin bloqueos), la arquitectura (interfaces y drivers) y la seguridad (validación, límites independientes, perro guardián, estado seguro).
  • Los errores más caros: cargas sin driver, inductivas sin diodo, delay(), vuelta de millis(), valores centinela, windup, relé sin histéresis, límites que dependen de lo que protegen, pines flotantes y no probar las fallas.
  • Una lista de verificación (eléctrica, señal, sensores, tiempo, control, seguridad, arranque, prueba) se repasa antes de encender cualquier proyecto.
  • Con la comunicación, los principios se trasladan: mensajes con secuencia y edad, validación y CRC, latidos con tiempo límite, estado seguro ante un enlace caído; la red es un extra, no una dependencia de la seguridad.
  • El presupuesto de un bus es una cuenta de bytes: ocupación = mensajes por segundo × tiempo por mensaje, con menos del 50 a 60 %; una IMU a 1 kHz no cabe en UART de 115 200 ni en I2C de 100 kHz.
  • Los buses tienen límites físicos: el pull-up del I2C (t = 0,8473·R·C, ventana de 967 a 3541 Ω con 100 pF a 400 kHz) y el error de baudios del UART (máximo del 5,26 % entre extremos con 8N1, en la práctica menos del 2 al 3 %).
  • Un CRC de 16 bits deja pasar un error aleatorio de cada 65 536: detecta, no corrige; para corregir hay que retransmitir, y para impedir órdenes ajenas, autenticar.

¿Listo para el curso 9?

Antes de cerrar, comprobá que podés justificar tres cosas: por qué un límite de seguridad por software con el mismo sensor no protege del sensor, cuántos bytes por segundo ocupa una IMU de 12 bytes a 1 kHz y por qué un robot por Bluetooth debe detenerse solo si se corta el enlace. Si podés, ya sabés percibir y actuar sobre el mundo con un programa, y estás listo para hacer que esos dispositivos se hablen.

El siguiente paso del camino es el curso 9, Comunicación: buses y protocolos entre microcontroladores y periféricos, redes inalámbricas y cableadas, y cómo hacer que los datos lleguen completos, a tiempo y seguros. Gracias por llegar hasta aquí.