← Índice del curso

Internet de las Cosas · Tema 18

Reconexión y fallas de red

La red se va a caer. No es una posibilidad: es una certeza, y el único dato abierto es cuándo y por cuánto tiempo. Un dispositivo bien diseñado no se pregunta si falla la red, sino qué hace mientras tanto, qué guarda, qué descarta y cómo se pone al día al volver. Este tema cierra el bloque de redes con esa pregunta.

01 · Punto de partida

La red se va a caer

En el tema 5 aprendiste la parte inmediata del problema: reconectar sin quedarse esperando para siempre, con espera creciente y retardo aleatorio. Esa es la primera línea de defensa y alcanza para cortes breves. Pero hay cortes que duran horas o días: un router apagado en un fin de semana, una antena celular en mantenimiento, un cable cortado, un servidor caído. Durante ese tiempo el dispositivo sigue midiendo, y lo que mide tiene valor.

La pregunta del tema es qué ocurre con esas lecturas. Si el firmware solo sabe enviar «en vivo», todo lo medido durante el corte se pierde, y quien analice los datos verá un hueco que no puede distinguir de una falla del sensor. Si el firmware sabe guardar y reenviar (store and forward), al volver la conexión entrega lo acumulado y el hueco desaparece. La diferencia entre ambos diseños es pequeña en código y enorme en confiabilidad.

Los números de memoria y de tiempo del tema salen del código de Python y del laboratorio. Los valores de desgaste de flash son didácticos; consultá la hoja de datos de tu memoria.

02 · Diagnóstico

Qué puede fallar y cuánto dura

«No hay red» no es un diagnóstico. Detrás hay fallas en capas distintas, con duraciones y remedios distintos. Cada una pide una reacción diferente.

Fallas de red típicas, su duración habitual y la reacción adecuada.
FallaCausa típicaDuraciónCómo se manifiestaReacción
Señal débil o interferenciaDistancia, obstáculos, canal saturadoSegundos a minutos, intermitentePaquetes perdidos, reintentos, conexiones lentasReintentar; registrar el RSSI; si es permanente, reubicar
Punto de acceso apagadoCorte de luz, reinicio del routerMinutos a horasNo se asocia a la redReintento con espera creciente; guardar datos
Sin dirección IPServidor DHCP caído o llenoMinutosAsociado pero sin IPReintentar el DHCP; plan B con IP estática
Sin salida a InternetFalla del proveedor, cable cortadoMinutos a díasHay IP y router, pero nada llega afueraComprobar con un destino público; guardar datos
DNS que no resuelveServidor DNS caído o mal configuradoMinutos a horasFalla por nombre, funciona por IPUsar la IP guardada; probar otro DNS
Servidor caído o saturadoMantenimiento, avalancha de reconexionesMinutos a horasConecta pero no responde, o rechazaEspera creciente con retardo aleatorio
Certificado o reloj incorrectoCertificado vencido, hora desajustadaPermanente hasta corregirFalla el apretón de manos de TLSSincronizar la hora; alarmar; actualización remota
Credenciales rechazadasClave cambiada, dispositivo dado de bajaPermanente hasta intervenirEl servidor rechaza al dispositivoNo reintentar sin parar; reportar y reducir la frecuencia

Hay una distinción que ordena el diseño: las fallas transitorias (se arreglan solas, a veces en segundos) y las permanentes (no se arreglan sin intervención, como una clave cambiada). Para las primeras conviene insistir con paciencia; para las segundas, insistir solo gasta batería y satura al servidor. El firmware no siempre puede distinguirlas a la primera, pero sí puede ir aumentando la espera y dejar de intentar con frecuencia cuando el patrón sugiere que no se va a resolver.

03 · Detección

Detectar una falla

Las fallas más peligrosas son las silenciosas: el enlace parece sano y nada llega. Hay cuatro herramientas para atraparlas:

  • Tiempos máximos en cada operación. Conectar, resolver, enviar y leer la respuesta tienen un plazo (tema 17). Lo que no responde a tiempo se da por fallido.
  • Confirmaciones. Un envío no terminó hasta que el servidor confirmó que lo recibió (el ACK de TCP no alcanza: confirma el transporte, no que la aplicación lo procesó). Un mensaje sin confirmación se considera pendiente y se conserva.
  • Mensajes de «sigo vivo». Un keepalive periódico detecta una conexión rota antes de que haga falta usarla, y mantiene abierto el NAT.
  • Comprobación de extremo a extremo. «Conectado al Wi-Fi» no significa «conectado al servidor». La salud de la comunicación se mide por la última confirmación recibida del destino final, no por el estado de la radio.

Con eso, el firmware mantiene un concepto simple y útil: el momento de la última confirmación exitosa. Si pasó más de cierto tiempo sin ninguna, el dispositivo está «sin conexión efectiva», sin importar lo que diga la radio. De ese concepto cuelgan las decisiones de guardar, de reducir la frecuencia y de intentar medidas más fuertes.

04 · Recuperación

Recuperarse sin empeorar las cosas

Sobre el reintento con espera creciente del tema 5 se agregan dos mecanismos que evitan que una falla larga se convierta en un problema mayor.

El disyuntor

Si el envío falla muchas veces seguidas, seguir intentando con la misma frecuencia es inútil. Un disyuntor (circuit breaker) cuenta los fallos consecutivos y, al pasar un límite, abre el circuito: el dispositivo deja de intentar enviar en cada ciclo y pasa a un modo de sondeo espaciado (por ejemplo, un intento por hora), con todos los datos yendo al buffer local. Cuando un sondeo tiene éxito, el circuito se cierra y se reanuda el reenvío. Ahorra batería y evita saturar un servidor que intenta recuperarse.

Recuperación escalonada y watchdog de conectividad

A veces la falla no está afuera sino adentro: la pila de red del chip se cuelga, el módem queda en un estado raro, una fuga de memoria agota los sockets. Para esos casos conviene una escalera de medidas, de la más suave a la más drástica:

  1. Reintentar la operación con espera creciente.
  2. Reiniciar la conexión (desconectar y volver a asociar el Wi-Fi).
  3. Reiniciar la pila de red o el módem (el módulo celular se apaga y enciende).
  4. Reiniciar el dispositivo, guardando antes los datos pendientes en memoria no volátil.

Cada escalón se alcanza tras un número de fallos o un tiempo sin conexión efectiva, y el último tiene una regla clave: limitar la cantidad de reinicios (por ejemplo, uno por hora como máximo, y backoff creciente entre ellos). Un dispositivo que se reinicia sin pausa cada vez que no tiene red agota la batería y no logra nunca estabilizarse. Es la versión de red del watchdog que ya vimos en Sistemas Embebidos.

05 · Memoria durante el corte

Modo sin conexión: guardar y reenviar

Mientras no hay conexión efectiva, el dispositivo sigue midiendo y guarda cada lectura en un buffer local. Cuando vuelve la red, lo vacía hacia el servidor. Tres decisiones de diseño definen su calidad.

Dónde guardar

Dónde almacenar las lecturas pendientes.
LugarCapacidad típicaSobrevive a un reinicioDesgasteUso
RAMDecenas de KBNoNingunoCortes breves; lecturas muy recientes
RAM del reloj (memoria que sobrevive al sueño profundo)Unos pocos KBAl sueño profundo, no a la pérdida de energíaNingunoDispositivos que duermen entre lecturas
Flash interna (con un sistema de archivos)Cientos de KB a MBSíLimitado: cada sector admite un número finito de borradosCortes de horas a días
Tarjeta SD o memoria externaMB a GBSíModeradoRegistro de gran volumen o cortes de días

La flash merece un cuidado especial. Cada sector soporta del orden de decenas a cientos de miles de ciclos de borrado, y para escribir un dato hay que borrar antes el sector entero (unos 4 KB). Si el firmware reescribe el mismo sector con cada lectura, puede gastar la memoria en semanas. La solución habitual es un registro circular con agregado (append-only): se escriben las lecturas una detrás de otra en el sector, y solo se borra cuando se llena, y los sistemas de archivos pensados para flash (como LittleFS) reparten además el desgaste entre sectores. También conviene escribir en bloques cuando sea posible, y no en cada lectura, balanceando el riesgo de perder lo que está en RAM.

Qué hacer cuando se llena

Un corte puede durar más de lo que alcanza la memoria. Hay que decidir de antemano qué se sacrifica:

Políticas cuando el buffer se llena.
PolíticaQué conservaQué pierdeCuándo conviene
Descartar las nuevasEl comienzo del corteLo más recienteCasi nunca: se pierde lo que más interesa
Sobrescribir las más viejasEl final del corte, la actualidadEl comienzoCuando importa el estado reciente más que el historial
Resumir (fusionar puntos)Todo el corte, con menos detalleEl detalle finoCuando importa la continuidad y la tendencia del historial

La opción de resumir es la más cuidadosa: cada vez que el buffer se llena, se fusionan los puntos de a pares (por ejemplo, promediándolos y guardando su mínimo y máximo), con lo que el buffer vuelve a tener lugar a costa de duplicar el período de cada punto. Así, un buffer fijo cubre cualquier duración de corte, con una resolución que se degrada de forma gradual. Y una regla independiente de la política: las alarmas y los eventos tienen prioridad. Nunca se descartan ni se resumen; si hace falta espacio, se sacrifica telemetría rutinaria.

06 · Ponerse al día

Reenviar al volver

Cuando la conexión efectiva vuelve, el dispositivo tiene un atraso que entregar, y hacerlo mal puede causar problemas nuevos.

  • En lotes. Enviar las lecturas acumuladas una por una multiplica el costo de cada mensaje (encabezados, confirmaciones). Agruparlas en lotes (tema 12) reduce el tiempo y la energía en un orden de magnitud.
  • Con las marcas de tiempo originales. Cada lectura conserva el instante en que se midió, no el de envío. De lo contrario, el servidor vería cientos de lecturas «simultáneas».
  • Sin ahogar al servidor. Después de un corte general, miles de dispositivos reenvían a la vez. El reenvío tiene un ritmo máximo y un retardo aleatorio de arranque, igual que la reconexión.
  • Lo urgente primero. Las alarmas pendientes salen antes que el historial. Y la lectura actual no debe esperar a que termine el atraso.
  • Con confirmación por lote. Un lote solo se borra del buffer cuando el servidor confirma que lo recibió. Si la confirmación se pierde, el lote se reenvía.
  • Con deduplicación. Ese reenvío puede producir duplicados (el servidor lo había recibido, pero la confirmación se perdió). Cada lectura lleva un identificador que no se repite (el del dispositivo y un número de secuencia o la marca de tiempo) y el servidor descarta las que ya tiene. Es la misma idempotencia del tema 11, aplicada a los datos.

Un detalle del reloj: mientras no hay red, el dispositivo no puede sincronizar la hora. Un reloj interno sin corrección se desvía segundos por día; para cortes largos, esas marcas de tiempo pierden precisión. Un reloj de tiempo real externo y una sincronización con el servidor al reconectarse permiten corregir las marcas de tiempo retroactivamente. El servidor, que sabe cuándo recibió el lote, puede acotar el error.

07 · Visibilidad

Informar lo que pasó

Un corte deja una huella que el servidor no puede ver por sí mismo. El dispositivo, al volver, debería contarla: es el material con el que se diagnostica una flota.

  • Contadores: número de reconexiones, de reinicios y de mensajes reenviados desde el último reporte.
  • Duración del último corte y de la peor racha, para distinguir cortes breves de largos.
  • Motivo de cada desconexión y de cada fallo de envío (tema 14).
  • Lecturas descartadas o resumidas, de modo que quien analice los datos sepa que hay un hueco o una pérdida de detalle, y su causa.
  • Estado del buffer: cuántas lecturas hay pendientes y qué fracción de su capacidad.

Y el complemento en el servidor: un dispositivo que no puede informar tampoco puede avisar que está caído. Por eso la plataforma vigila los latidos y marca como «sin contacto» a los equipos que callan más allá de su intervalo esperado, que es la alarma que atrapa el caso en que ni el buffer ni el reenvío pudieron hacer nada.

08 · Analogía con programación

Simular un corte largo en Python

El programa simula un corte durante el cual el dispositivo sigue midiendo una lectura por minuto. Cada lectura guardada ocupa 6 bytes (desfase de tiempo y valor). La función guardar implementa las tres políticas; en resumir, cada vez que se supera la capacidad, se fusionan los puntos de a pares y se duplica el tiempo que representa cada uno. La función evaluar calcula los puntos guardados, las lecturas perdidas, la cobertura, la resolución, la memoria y el tiempo de reenvío al volver la conexión, enviando en lotes (de 1 o de 50 lecturas, 0,5 s por mensaje).

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

BYTES_POR_LECTURA = 6        # desfase de tiempo y valor de cada lectura guardada
SEGUNDOS_POR_MENSAJE = 0.5   # enviar un mensaje con la conexión ya establecida
CORRIENTE_MA = 100           # corriente con la radio activa


def guardar(minutos_sin_red, capacidad, politica):
    """Una lectura por minuto durante el corte. Devuelve (puntos guardados, minutos por punto)."""
    if politica in ("descartar nuevas", "sobrescribir viejas"):
        return min(minutos_sin_red, capacidad), 1
    puntos, ancho, acumulado = [], 1, 0          # "resumir": al llenarse, se promedian pares de puntos
    for _ in range(minutos_sin_red):
        acumulado += 1
        if acumulado == ancho:
            puntos.append(ancho)
            acumulado = 0
            if len(puntos) > capacidad:
                resto = [puntos[-1]] if len(puntos) % 2 else []
                puntos = [puntos[i] + puntos[i + 1] for i in range(0, len(puntos) - 1, 2)] + resto
                ancho *= 2
    if acumulado:
        puntos.append(acumulado)
    return len(puntos), ancho


def evaluar(minutos_sin_red, capacidad, politica, lote):
    guardados, resolucion = guardar(minutos_sin_red, capacidad, politica)
    perdidas = minutos_sin_red - guardados if resolucion == 1 else 0
    cobertura = 100 * guardados / minutos_sin_red if resolucion == 1 else 100.0
    mensajes = -(-guardados // lote)                      # división hacia arriba
    segundos = mensajes * SEGUNDOS_POR_MENSAJE
    mah = CORRIENTE_MA * segundos / 3600
    return guardados, perdidas, cobertura, resolucion, guardados * BYTES_POR_LECTURA, segundos, mah


print("corte    buffer  política              guardadas  cobertura  resolución  memoria   reenvío (lote 50)")
for minutos, nombre in ((360, "6 h"), (1440, "24 h"), (4320, "72 h")):
    for capacidad in (100, 2000):
        for politica in ("descartar nuevas", "sobrescribir viejas", "resumir"):
            g, p, cob, res, mem, seg, mah = evaluar(minutos, capacidad, politica, 50)
            print(f"{nombre:<6} {capacidad:>7}  {politica:<20} {g:>9} {cob:>9.0f} % {res:>8} min {mem / 1024:>7.1f} KB {seg:>6.0f} s")

print()
g1 = evaluar(1440, 2000, "resumir", 1)
g50 = evaluar(1440, 2000, "resumir", 50)
print(f"Vaciar 1440 lecturas guardadas: una por una {g1[5]:.0f} s ({g1[6]:.3f} mAh); en lotes de 50, {g50[5]:.0f} s ({g50[6]:.4f} mAh)")

Resultado con los valores iniciales. Con un corte de 6 horas y un buffer de 100 lecturas, descartar las nuevas o sobrescribir las viejas conserva solo el 28 % (100 de 360); resumir conserva el 100 % con puntos de 4 minutos. Con un corte de 24 horas y el mismo buffer, descartar o sobrescribir conserva el 7 %, y resumir cubre todo con puntos de 16 minutos (91 puntos, 546 bytes). Con un buffer de 2000 lecturas, 6 y 24 horas se guardan completas (360 lecturas en 2,1 KB y 1440 en 8,4 KB). Con 72 horas y 2000 lecturas, descartar o sobrescribir conserva el 46 % (2000 de 4320); resumir mantiene todo con puntos de 4 minutos (1081 puntos, 6,3 KB). Vaciar las 1440 lecturas de un día de corte, una por una, lleva 720 s y gasta 20 mAh (el 1 % de una batería de 2000 mAh); en lotes de 50, unos 14 s y 0,40 mAh.

Tres lecciones. Una: sin política, un buffer chico pierde casi todo en un corte largo; con la política de resumir, un buffer de 100 lecturas cubre desde 6 horas hasta 72 sin huecos. Otra: la memoria necesaria es modesta: un día de lecturas por minuto son 8,4 KB. Y la tercera: reenviar en lotes cuesta 50 veces menos energía que hacerlo de a una, que es la diferencia entre una recuperación inadvertida y un gasto del 1 % de la batería.

09 · Exploración interactiva

¿Qué se conserva de un corte?, de extremo a extremo

Este laboratorio ejecuta el mismo modelo del código anterior. Elegí la duración del corte, la capacidad del buffer, la política cuando se llena y la forma de reenviar. La franja representa el corte de principio a fin: celeste, lo conservado; celeste claro, lo conservado con menos detalle; rojo, lo perdido. Los tamaños y tiempos de reenvío son valores didácticos.

Guardar y reenviar durante un corte

Puntos guardados (de las lecturas del corte)—
Cobertura del corte—
Resolución de lo guardado—
Memoria usada—
Tiempo y energía del reenvío—
Resultado—

Elegí los parámetros y presioná «Simular el corte».

Recorrido guiado

  1. Con los valores iniciales (24 horas, 100 lecturas, resumir, lotes de 50), simulá. 91 puntos de 16 minutos cubren el 100 % del corte con 546 bytes y 1 s de reenvío: «Completo, con menos detalle».
  2. Cambiá la política a Descartar las nuevas: se guardan 100 lecturas y la cobertura es del 7 %. La franja se ve casi toda roja: se conservaron los primeros 100 minutos y se perdió el resto.
  3. Pasá a Sobrescribir las más viejas: misma cobertura del 7 %, pero la parte celeste queda al final. Se conserva lo más reciente, que suele ser lo más útil, pero igual faltan unas 22 horas.
  4. Subí el buffer a 2000 lecturas: las 1440 lecturas del día entran completas (8,4 KB) con cualquier política. Con el corte en 72 horas, descartar o sobrescribir conservan el 46 % y resumir el 100 % con puntos de 4 minutos.
  5. Con 7 días y 2000 lecturas, resumir cubre todo con puntos de 8 minutos (1261 puntos, 7,4 KB). Con 20.000 lecturas, las 10.080 caben completas (59,1 KB) y con lotes de 50 el reenvío lleva unos 100 s y 2,8 mAh.
  6. Con 24 horas y 2000 lecturas, cambiá el reenvío a Una lectura por mensaje: 720 s y 20 mAh, el 1 % de la batería para ponerse al día. En lotes de 50 son unos 15 s y 0,4 mAh.
Desafío: el desgaste de la flash

Un firmware guarda en flash una lectura por minuto. Si cada vez que guarda reescribe el mismo sector de 4096 bytes (borrar y escribir), y el sector soporta 100.000 borrados, se agota en 100.000 minutos: unos 69 días. En cambio, con un registro con agregado, cada lectura de 6 bytes se escribe a continuación de la anterior y el sector solo se borra cuando se llena: una vez cada 4096 / 6 ≈ 682 lecturas. El mismo sector dura 100.000 × 682 minutos, unos 130 años; y repartido entre varios sectores, aún más. Es una diferencia de unas 680 veces solo por la forma de escribir. En flash, el diseño de la escritura importa tanto como la capacidad.

10 · Método de trabajo

Lista de verificación de la robustez de red

  1. Todo con tiempo máximo: conectar, resolver, enviar y leer la respuesta.
  2. Conexión efectiva: el estado se define por la última confirmación del servidor, no por la radio.
  3. Espera creciente con retardo aleatorio y un disyuntor que espacia los intentos tras muchos fallos.
  4. Escalera de recuperación con reinicio limitado en frecuencia.
  5. Buffer local dimensionado para el corte más largo que querés cubrir, con la cuenta hecha (bytes por lectura × lecturas).
  6. Política de desborde elegida a conciencia, con prioridad para alarmas y eventos.
  7. Escritura en flash pensada para no gastarla: registro circular con agregado, bloques, sistema de archivos con nivelación.
  8. Reenvío en lotes, con marcas de tiempo originales, confirmación por lote, ritmo limitado y deduplicación en el servidor.
  9. Informe del corte: contadores, duración y causas, para diagnosticar.
  10. Pruebas de corte reales: apagar el router una hora, desconectar Internet un día, cortar la luz durante un reenvío, llenar el buffer.

La última prueba es la decisiva. Un firmware que nunca experimentó un corte largo en el laboratorio no sabe lo que hace cuando ocurre en el campo. Simulalo: es lo más barato y lo más revelador que podés hacer por la confiabilidad.

11 · Comprensión

Confusiones frecuentes

«Si no hay red, no hay nada que hacer: espero a que vuelva»

El dispositivo sigue midiendo y esos datos tienen valor. Esperar sin guardar convierte un corte en un hueco permanente. Guardar y reenviar cuesta unos pocos kilobytes y unas pocas líneas de código.

«Con más reintentos me recupero antes»

Reintentar sin pausa gasta batería y satura al servidor que intenta recuperarse. Después de varios fallos, es mejor espaciar los intentos y dejar los datos en el buffer.

«Un buffer circular que sobrescribe lo viejo es lo más seguro»

Conserva lo reciente, pero pierde el comienzo del corte. Si importa la continuidad, resumir mantiene todo con menos detalle. Y en ningún caso se deben sobrescribir las alarmas.

«Escribir en flash es como escribir en RAM»

La flash tiene un número finito de borrados por sector y exige borrar sectores completos. Reescribir el mismo sector con cada lectura puede agotarla en semanas. Se usan registros con agregado y sistemas de archivos pensados para flash.

«Reenviar todo de golpe al reconectar es lo más rápido»

Enviar en lotes es más eficiente que de a una, pero soltar todo sin control, con muchos dispositivos a la vez, puede saturar el servidor. Hace falta un ritmo máximo y un retardo aleatorio de arranque.

«Si el servidor recibió el dato, la confirmación siempre llega»

No: puede perderse. Por eso el dispositivo conserva el lote hasta recibir la confirmación y lo reenvía si no llega, lo que produce duplicados. El servidor debe descartarlos con un identificador.

12 · Práctica guiada

Predecí antes de comprobar

1. Dimensionar el buffer

Un dispositivo guarda una lectura por minuto, de 6 bytes cada una. ¿Cuánta memoria necesita para cubrir un corte de 24 horas? ¿Y de 7 días?

Ver solución

24 horas: 1440 lecturas × 6 bytes = 8640 bytes, unos 8,4 KB. 7 días: 10.080 × 6 = 60.480 bytes, unos 59 KB. En RAM es mucho para un microcontrolador chico; en flash o en una SD es poco.

2. Elegir la política

Elegí la política para: (a) un sensor de nivel de un tanque cuyo estado reciente es lo que importa; (b) un registro de temperatura de una cadena de frío que debe mostrar continuidad total; (c) un medidor con alarmas de seguridad.

Ver solución

(a) Sobrescribir las más viejas: interesa el estado actual. (b) Resumir (guardando mínimo y máximo de cada punto): se pierde detalle pero no continuidad ni los extremos. (c) Las alarmas se guardan aparte y nunca se descartan ni se resumen; la telemetría rutinaria sí.

3. Costo del reenvío

1440 lecturas pendientes. Cada mensaje tarda 0,5 s con la radio a 100 mA. ¿Cuánto tarda y cuánta energía gasta enviarlas una por una y en lotes de 50?

Ver solución

Una por una: 1440 mensajes × 0,5 s = 720 s; 100 mA × 720 s / 3600 = 20 mAh. En lotes de 50: 29 mensajes × 0,5 s = 14,5 s; 0,40 mAh. El lote gasta 50 veces menos energía.

4. Duplicados

Se envía un lote, el servidor lo recibe, pero la confirmación se pierde y el dispositivo lo reenvía. ¿Qué pasa y cómo se evita el daño?

Ver solución

El servidor recibe el mismo lote dos veces y, sin protección, guardaría lecturas duplicadas. Se evita dándole a cada lectura un identificador único (dispositivo y número de secuencia, o marca de tiempo): el servidor ignora las que ya tiene. Es una escritura idempotente.

5. Vida de la flash

Un sector soporta 100.000 borrados. Reescribirlo con cada lectura por minuto, ¿cuánto dura? ¿Y con un registro con agregado de lecturas de 6 bytes en sectores de 4096 bytes?

Ver solución

Reescritura: 100.000 minutos ≈ 69 días. Con agregado: un borrado cada 4096 / 6 ≈ 682 minutos; 100.000 × 682 ≈ 68 millones de minutos, unos 130 años en un solo sector. Unas 680 veces de diferencia por la forma de escribir.

6. El bucle de reinicios

Un firmware reinicia el dispositivo cada vez que pierde la red por más de 2 minutos. Un corte de 6 horas del router ¿qué provoca? ¿Cómo se corrige?

Ver solución

El equipo se reinicia unas 180 veces durante el corte, gasta batería en cada arranque y pierde las lecturas en RAM. Se corrige con una escalera de recuperación y un límite de reinicios (por ejemplo, uno por hora con espera creciente), y guardando los datos en memoria no volátil antes de cualquier reinicio.

13 · Síntesis

Ideas para recordar

  • La red se va a caer: el diseño parte de preguntar qué hace el dispositivo mientras tanto, qué guarda y cómo se pone al día.
  • Las fallas son de capas distintas y duran desde segundos hasta días; se distinguen las transitorias, que se reintentan, de las permanentes, que no.
  • Se detectan con tiempos máximos, confirmaciones de la aplicación, keepalives y una comprobación de extremo a extremo; «conectado al Wi-Fi» no es «conectado al servidor».
  • El disyuntor espacia los intentos tras muchos fallos, y la recuperación escalonada llega al reinicio solo con límites de frecuencia.
  • El modo sin conexión guarda cada lectura en un buffer local dimensionado para el corte más largo que se quiere cubrir; un día de lecturas por minuto son unos 8,4 KB.
  • Cuando el buffer se llena hay que elegir: descartar las nuevas pierde lo actual, sobrescribir las viejas pierde el comienzo, resumir conserva todo con menos detalle.
  • Las alarmas y eventos tienen prioridad y nunca se descartan ni se resumen.
  • La flash se desgasta: se escribe con registros de agregado y sistemas de archivos con nivelación.
  • Reenviar en lotes, con marcas de tiempo originales, confirmación por lote, ritmo limitado y deduplicación, cuesta 50 veces menos energía que de a una lectura.
  • El dispositivo informa al volver (contadores, duración, causas, descartes) y el servidor vigila los latidos para detectar a los que callan.

¿Listo para el bloque 4?

Antes de avanzar, probá el peor caso: apagá el router durante una hora con tu dispositivo midiendo, volvelo a encender y comprobá si las lecturas del corte llegaron al servidor con sus horas originales y sin duplicados. Calculá cuánto de tu buffer se usó y qué pasaría con un corte diez veces más largo. Si podés responder con números, tu dispositivo está listo para el campo.

Con este tema terminan las redes. En el próximo bloque subimos a la capa de aplicación con HTTP desde un dispositivo: cómo se arma una petición, qué significan los códigos de respuesta y cómo se comporta un cliente HTTP en un microcontrolador.