Volver al Blog
Ingeniería 16 de junio de 2025 · 12 min lectura

RS-232, Radio por Paquetes y un SCADA en Lisp: Lo Que los Devs Modernos Pueden Aprender de los 90

GM

Gonzalo Monzón

Fundador & Arquitecto Principal

En 2024, una "función serverless" típica tiene más de 150 dependencias npm, corre en un aislado V8 aprovisionado en 50ms, procesa un payload JSON, consulta una base de datos distribuida y devuelve respuesta en 200ms. Nadie involucrado en este proceso podría explicar cómo funciona TCP a nivel de byte. En 1998, yo mantenía un sistema SCADA para una empresa de aguas donde la lógica de control estaba escrita en Lisp, la interfaz era TCL/TK, los PLCs estaban programados en C con cuatro hilos, y se comunicaban por radio por paquetes. No había dependencias que instalar. No había paso de build. Todo funcionaba.

Estas son historias de guerra de la última década del siglo XX — la era antes de que las abstracciones se lo comieran todo. No como nostalgia, sino como lecciones de ingeniería que el stack moderno ha olvidado sistemáticamente.

El SCADA Que Corría en Lisp

Aguas de Reus (la empresa de aguas de Reus, Tarragona) operaba una red de estaciones de bombeo, plantas de tratamiento y puntos de distribución por toda la región. Necesitaban monitorizar y controlar todo en tiempo real — niveles de agua, presiones, caudales, estado de bombas, posiciones de válvulas, dosificación química.

La arquitectura del sistema:

  • PLCs Sixnet en cada estación remota — programados en C, con solo cuatro hilos de ejecución. Estos PLCs leían sensores (entradas analógicas 4-20mA, entradas digitales), controlaban actuadores (bombas, válvulas) y se comunicaban aguas arriba. Cuatro hilos. Eso es todo. Había que ser quirúrgico con qué se ejecutaba y cuándo
  • Radio por paquetes para comunicación — ni TCP/IP, ni celular, ni satélite. Módems de radio transmitiendo paquetes de datos entre estaciones remotas y la sala de control central. El ancho de banda se medía en kilobits, no megabits. Cada byte importaba
  • Estaciones de trabajo HP-UX en el centro de control — la variante Unix de HP, corriendo sobre hardware PA-RISC que costaba más que la mayoría de coches de la época
  • Software SCADA en C, Lisp y TCL/TK — la adquisición de datos y lógica de control en C y Lisp, la interfaz de operador en TCL/TK

¿Por Qué Lisp para Control Industrial?

Parece raro según los estándares actuales — ¿Lisp en un SCADA? Pero tenía un profundo sentido ingenieril. El SCADA necesitaba un motor de reglas para evaluar condiciones de alarma, calcular valores derivados y tomar decisiones de control basadas en combinaciones complejas de lecturas de sensores. Lisp es, fundamentalmente, un lenguaje para computación simbólica y evaluación de reglas.

Considera una regla de alarma típica: "Si el nivel del depósito baja del 30% Y la bomba A o la bomba B lleva más de 4 horas funcionando Y el caudal de entrada es menor de 50 L/min, disparar alerta de alta prioridad y arrancar la bomba de reserva." En C, esto es un lío anidado de if-else que se vuelve inmantenible a medida que las reglas se multiplican. En Lisp, es una estructura de datos que se puede componer, modificar y evaluar dinámicamente.

La capa TCL/TK era la interfaz de operador — diagramas mímicos en tiempo real mostrando la red de agua, con tuberías codificadas por color (azul para flujo, rojo para alarma, gris para fuera de servicio), gráficos de tendencias, listas de alarmas. TCL/TK era ligero, podía renderizar gráficos eficientemente en la pantalla X11 de HP-UX, y se podía scriptar rápidamente cuando los operadores necesitaban una nueva vista del sistema.

Cuatro Hilos y una Radio

Los PLCs Sixnet merecen su propio reconocimiento. Cada uno tenía cuatro hilos de ejecución y un módem de radio por paquetes. En términos modernos, necesitarías ejecutar toda tu aplicación — lectura de sensores, control de actuadores, lógica local de alarmas y comunicación aguas arriba — en lo que equivale a una Raspberry Pi Zero con un walkie-talkie.

Programar estos PLCs significaba entender el timing a un nivel que la mayoría de desarrolladores modernos nunca encuentran:

  • Hilo 1: Bucle de lectura de sensores — leyendo entradas analógicas cada 100ms, filtrando rebotes en entradas digitales
  • Hilo 2: Bucle de control — ejecutando controladores PID e interlocks de seguridad
  • Hilo 3: Comunicación — ensamblando paquetes de datos, gestionando el protocolo de radio (con lógica de retransmisión, porque la radio por paquetes no es fiable), procesando comandos entrantes del SCADA central
  • Hilo 4: Procesamiento local de alarmas y registro de datos en memoria onboard (porque la radio podía estar caída durante horas)

Cada byte en el protocolo de comunicación estaba cuidadosamente asignado. No había JSON. No había overhead de protocolo. Un paquete de estado típico eran 64 bytes — ID de estación, timestamp, 20 valores de sensores como enteros de 16 bits, 8 bits de estado digital, un checksum. Eso es todo. Compara eso con un payload típico de sensor IoT hoy: 2KB de JSON con claves string, metadatos redundantes y un token JWT más grande que los datos reales.

La Evolución: De Lisp a Vijeo Citect

En 2008, reemplacé el SCADA original de C/Lisp/TCL-TK por Schneider Vijeo Citect — una plataforma SCADA comercial moderna. Pero la migración tenía una restricción: la base de datos subyacente se había migrado de HP-UX con MSM (una base de datos multidimensional basada en MUMPS) a InterSystems Caché, y tenía que preservar el acceso a las mismas estructuras de datos.

La solución: conectores ODBC personalizados que permitían a Vijeo Citect leer y escribir en Caché usando las mismas rutas clave-valor que MSM había usado. Los PLCs, la comunicación por radio, el cableado de campo — nada cambió. Solo se reemplazó la capa supervisora. Mismos datos, mismos dispositivos de campo, nueva interfaz.

Este es un principio que he aplicado en cada migración legacy desde entonces: cambia una capa a la vez. Nunca cambies el modelo de datos y la interfaz y la capa de comunicación simultáneamente. Si algo se rompe, necesitas saber qué capa lo causó.

El Laboratorio Hospitalario: 25 Analizadores en un Bus Serie

Mientras el SCADA operaba en el mundo industrial, yo mantenía simultáneamente sistemas de IT hospitalarios. El laboratorio era donde ambos mundos colisionaban — era pura automatización industrial incrustada en un contexto sanitario.

El Jardín RS-232

Un laboratorio hospitalario en 1998 era una sala llena de máquinas especializadas — analizadores — cada una diseñada para medir cosas específicas en sangre, orina o muestras de tejido. Una tarjeta RS-232/paralelo de 32 puertos instalada en un servidor conectaba aproximadamente 25 analizadores diferentes:

  • Analizadores de hematología — hemogramas completos, diferenciales de glóbulos rojos y blancos
  • Analizadores de bioquímica — glucosa, colesterol, enzimas hepáticas, electrolitos
  • Estaciones de análisis de orina — tiras reactivas automatizadas y microscopía
  • Analizadores de inmunología/serología — anticuerpos, hormonas, marcadores tumorales
  • Analizadores de coagulación — TP, TTPa, fibrinógeno

Cada analizador hablaba su propio protocolo serie — diferentes velocidades de baudios, diferentes formatos de datos, diferentes requisitos de handshaking, diferentes codificaciones de resultados. No había estándar. Cada fabricante tenía su propio dialecto.

Para cada modelo de analizador, alguien había escrito una rutina MUMPS — un parser serie personalizado que:

  1. Abría el puerto RS-232 a la velocidad de baudios correcta (1200, 2400, 9600 o 19200)
  2. Gestionaba el protocolo de handshaking (algunos usaban ETX/ACK, otros secuencias propietarias)
  3. Parseaba el flujo de bytes entrante en resultados discretos
  4. Validaba los resultados contra rangos esperados
  5. Los almacenaba en el global MUMPS apropiado, vinculados al paciente y petición correctos
  6. Marcaba valores críticos para notificación inmediata al clínico

Si un resultado de glucosa volvía a 450 mg/dL (peligrosamente alto), la rutina MUMPS actualizaba inmediatamente la historia del paciente y disparaba una alerta en el terminal del médico. Esto era IoT antes de que existiera IoT — comunicación máquina a máquina con alertas en tiempo real, corriendo sobre líneas serie RS-232 en 1998.

La Realidad de la Depuración

Cuando un analizador de laboratorio dejaba de reportar resultados — algo que pasaba regularmente — el proceso de depuración era pura arqueología hardware-software:

  1. Comprobar el cable RS-232 físico (conectores aflojados, cables mordidos por los carros de limpieza)
  2. Comprobar la asignación de puerto (32 puertos, fácil confundirse durante el mantenimiento)
  3. Conectar un terminal serie o analizador de protocolo al puerto y observar los bytes crudos desfilando
  4. Comparar el patrón de bytes con la documentación del protocolo (si existía — a veces hacías ingeniería inversa desde cero)
  5. Probar si la rutina MUMPS de parseo era correcta alimentándola manualmente con secuencias de bytes conocidas
  6. Si todo fallaba, llamar al fabricante del analizador, describir el patrón de bytes y negociar una solución

Esto era full-stack en el sentido más literal — desde la señal eléctrica en el Pin 2 (TxD) hasta el registro del paciente en la pantalla del médico, eras responsable de cada capa.

El Disquete: Sneakernet como Arquitectura

A finales de los 90, conectar centros de atención primaria a la red del hospital era a menudo imposible. Sin DSL. Sin fibra. A veces ni siquiera una línea telefónica fiable para un módem. La solución era lo que los ingenieros de redes llaman sneakernet — transferencia de datos por transporte físico.

Un técnico conducía una ruta cada mañana, parando en cada CAP (Centre d'Atenció Primària) para copiar las visitas del día a un disquete de 3,5". En el hospital, los datos se cargaban en el sistema central para organizar la logística de historiales de pacientes y la coordinación de derivaciones.

La sneakernet tenía propiedades que los ingenieros de sistemas distribuidos modernos encontrarían familiares:

  • Procesamiento por lotes: Los datos se recogían una vez al día en bloque — el "batch ETL" original
  • Idempotencia: La rutina de carga tenía que gestionar duplicados (¿y si el técnico ejecutaba la exportación dos veces?)
  • Recuperación de errores: Si un disquete estaba corrupto (y los discos de 3,5" se corrompían a menudo), el fallback eran los datos de ayer más una llamada telefónica al centro para los casos críticos
  • Ancho de banda: Andrew Tanenbaum tenía razón — "Nunca subestimes el ancho de banda de un camión lleno de cintas a toda velocidad por la autopista." Un disquete de 1,44 MB contenía más datos de los que ese módem podía transferir en una hora

La sneakernet no era un fallo de la tecnología. Era una decisión arquitectónica pragmática — el mecanismo de transferencia de datos más fiable dadas las restricciones de infraestructura. Los sistemas modernos hacen el mismo trade-off: importaciones masivas a S3, dispositivos Snowball físicos para transferencias de petabytes, USBs para redes aisladas.

Lo Que los 90 Acertaron

1. Cero Dependencias

El código de los PLCs Sixnet era C puro. La lógica del SCADA era Lisp evaluado por un motor personalizado. Las rutinas MUMPS eran programas autocontenidos en un runtime autocontenido. No había árboles de dependencias, ni gestores de paquetes, ni vulnerabilidades en la cadena de suministro.

Cuando actualizabas el código del PLC, sabías exactamente qué había cambiado — porque habías escrito cada línea. Cuando una rutina MUMPS fallaba, el problema estaba en la rutina, no en una dependencia transitiva seis niveles más abajo que algún mantenedor en otro país había abandonado.

Hoy, una función Node.js "simple" para leer un valor de sensor puede arrastrar más de 200 paquetes. Uno estará deprecado el mes que viene. Otro tiene un CVE que nadie ha parcheado. El enfoque de los 90 no era escalable, pero era comprensible — y los sistemas comprensibles son sistemas depurables.

2. Cada Byte se Ganaba

Cuando tu canal de comunicación es una radio por paquetes con ancho de banda en kilobits, no envías {"sensorId": "PUMP_STATION_14_RESERVOIR_LEVEL", "value": 67.5, "unit": "percent", "timestamp": "2024-03-14T10:30:00Z"}. Envías 0x0E 0x43 0x87 — estación 14, valor 675 (decimal implícito), checksum.

Esta disciplina obligaba a los ingenieros a pensar en qué información realmente importa. El resultado: sistemas rápidos, eficientes y resilientes ante degradación de red. Cuando la radio perdía paquetes, perdías 64 bytes. Hoy, cuando una llamada API falla, pierdes 2KB de metadatos JSON que nadie lee de todos modos.

3. La Presencia Física Creaba Comprensión

Íbamos a los hospitales cada semana. Nos sentábamos con los médicos. Veíamos a las enfermeras usar nuestro software. Cuando alguien decía "esta pantalla va lenta", no abríamos un ticket de Jira — nos poníamos detrás y contábamos los segundos. Entendíamos que "lento" en una urgencia significa "un paciente puede estar muriéndose mientras espero a que cargue esta pantalla."

El desarrollo moderno remote-first es eficiente y escalable, pero crea una distancia entre el ingeniero y la consecuencia de su trabajo. Cuando tu deploy es un wrangler deploy a una CDN global, es fácil olvidar que en algún lugar, una enfermera está tocando una pantalla y esperando a que tu código responda.

4. La Simplicidad como Disciplina de Ingeniería

Un PLC Sixnet con cuatro hilos no es simple porque los problemas sean simples — el tratamiento de aguas implica química compleja, interlocks de seguridad y control en tiempo real. Es simple porque las restricciones forzaban la simplicidad. No podías añadir una librería. No podías crear otro hilo. Tenías que resolver el problema dentro de la caja.

Los desarrolladores modernos tienen el problema opuesto: recursos ilimitados fomentan complejidad ilimitada. Cuando puedes añadir cualquier paquete npm, ejecutar cualquier número de microservicios y escalar horizontalmente para siempre, la disciplina del "¿realmente necesito esto?" desaparece. Los ingenieros de los 90 se hacían esa pregunta por cada byte, cada instrucción, cada cable.

El Puente hacia Hoy

No defiendo que volvamos a RS-232 y disquetes. Las herramientas que tenemos hoy — funciones serverless, bases de datos distribuidas globalmente, modelos de IA, streaming en tiempo real — son genuinamente mejores. Pero los principios de ingeniería que hacían fiables a los sistemas de los 90 son exactamente los principios que les faltan a los sistemas modernos:

Principio de los 90Equivalente Moderno (Frecuentemente Ausente)
Entiende cada byte en el cableEntiende tu overhead de protocolo y eficiencia de payload
Cero dependencias = cero riesgo de supply chainMinimiza dependencias, audita lo que incluyes
Diseña para redes no fiablesDiseña para particiones de red y modo degradado
Presencia física con usuariosTelemetría en tiempo real y canales directos de feedback
Cuatro hilos — resuélvelo o noCuestiona cada abstracción: ¿realmente necesito esto?
Una persona es dueña de todo el stackFull-stack ownership reduce el overhead de coordinación

En Cadences Lab, construimos con Cloudflare Workers, SQLite, agentes IA y estándares web modernos. Pero la filosofía viene de RS-232 y Lisp — entiende las primitivas, minimiza las capas, sé dueño de todo el stack, mantente cerca del usuario. Las herramientas cambiaron. La ingeniería no.

Etiquetas

SCADA Automatización Industrial RS-232 Sistemas Legacy Lisp Sistemas en Tiempo Real Historia de la Ingeniería

Sobre el Autor

Gonzalo Monzón

Gonzalo Monzón

Fundador & Arquitecto Principal

Gonzalo Monzón es Arquitecto de Soluciones Senior e Ingeniero IA con más de 26 años construyendo sistemas críticos en Sanidad, Automatización Industrial e IA empresarial. Fundador de Cadences Lab, está especializado en conectar infraestructura legacy con tecnología de vanguardia.

Mantente al día

Recibe notificaciones cuando publiquemos nuevos artículos sobre automatización IA, casos de uso y guías prácticas.

Artículos Relacionados

Ingeniería
11 min lectura

Edge Computing: Por Qué lo Apostamos Todo a Cloudflare (Y Qué Consigues por $65/Mes)

Sin servidores, sin contenedores, sin Kubernetes. Corremos 14+ productos interconectados en 9 productos Cloudflare — Workers, D1, R2, Durable Objects, Pages, KV, Vectorize, Workers AI y WAF. $65/mes por lo que costaría $400-600 en AWS. La arquitectura completa.

GM
25 de agosto de 2025
Leer Artículo →
Ingeniería
9 min lectura

SQLite Es la Base de Datos de Producción Que Ya Conoces (Solo Que Aún No Lo Sabes)

DHH alcanzó 30.000 escritores concurrentes en SQLite. Nosotros ejecutamos 14+ productos en Cloudflare D1 (SQLite en el edge) por 5$/mes. SQLite no es la base de datos de juguete que crees — está impulsando todo, desde ONCE de 37signals hasta toda nuestra plataforma multi-tenant. Así es como la industria está convergiendo en la base de datos más desplegada del mundo.

GM
5 de marzo de 2026
Leer Artículo →
Ingeniería
10 min lectura

Vanilla JS Es el Lenguaje Ensamblador del Navegador (Y Por Eso Lo Usamos)

Gmail envía 20MB de JavaScript. Slack 55MB. Nuestro sistema de cookie consent? 4KB, cero dependencias. Cuando entiendes las primitivas de bajo nivel — vanilla JS, CSS puro, APIs nativas del DOM — no necesitas un framework que te diga lo que el navegador ya sabe. Pero no somos anti-frameworks: usamos Astro para SSG y React islands donde realmente ayudan. La diferencia es que elegimos nuestras herramientas — no nos eligen a nosotros.

GM
13 de marzo de 2026
Leer Artículo →