FUXA es un editor SCADA y HMI web y de código abierto que funciona sobre Node.js. En un Raspberry PLC, FUXA no lee las E/S directamente. Node-RED lee y escribe los pines del PLC con los nodos librpiplc de Industrial Shields, y un broker MQTT Mosquitto en el mismo PLC lleva los valores entre Node-RED y FUXA.
El resultado es una pantalla de operador en http://<IP del PLC>:1881 con interruptores para las salidas Q0.0 a Q0.7, una tabla para las entradas digitales, y un indicador y gráficos para las entradas analógicas I0.7 a I0.12 de un Raspberry PLC 21.
Esta guía monta la cadena completa paso a paso: el flujo de Node-RED, los topics MQTT, el dispositivo y los tags de FUXA, el panel y un script. El flujo de Node-RED, el archivo de dispositivos de FUXA y el proyecto de FUXA se pueden descargar, para importarlos y adaptarlos a tu modelo.
¿Qué es FUXA y por qué usarlo en un Raspberry PLC?
FUXA es una herramienta de visualización de procesos para pantallas SCADA, HMI y paneles. Las pantallas se dibujan en un editor web y los operadores las abren en un navegador. Se publica con licencia MIT. Sus drivers incluyen Modbus RTU y TCP, OPC UA, Siemens S7, MQTT, BACnet IP y EtherNet/IP, y tiene un histórico de datos integrado (DAQ) con SQLite o InfluxDB. Fuente: el repositorio de FUXA.
FUXA también tiene un driver GPIO para la Raspberry Pi, pero no llega a la mayoría de las E/S de un Raspberry PLC. En un Raspberry PLC 21, las entradas digitales I0.0 a I0.4 están en un expansor MCP23008, las entradas analógicas I0.7 a I0.12 en ADC LTC2309 y las salidas Q0.0 a Q0.7 en un driver PCA9685, todos por I2C. Solo I0.5 e I0.6 son GPIO directos (ver el mapa de pines de librpiplc). La librería librpiplc conoce este mapa, y Node-RED la usa a través de sus nodos. Por eso esta guía pone Node-RED entre los pines del PLC y FUXA.
Si solo necesitas unos pocos indicadores, el Dashboard de Node-RED puede ser suficiente (ver un ejemplo de dashboard de Node-RED con un Raspberry PLC). FUXA encaja mejor cuando necesitas pantallas de tipo SCADA:
| Necesidad | Dashboard de Node-RED | FUXA |
|---|---|---|
| Cómo se hacen las pantallas | Widgets colocados en grupos, creados desde los flujos | Dibujo libre en un editor web: formas, SVG, imágenes, texto |
| Fuentes de datos | Cualquier nodo de Node-RED (MQTT, Modbus, HTTP, bases de datos) | Drivers propios: MQTT, Modbus, OPC UA, S7, BACnet, EtherNet/IP |
| Histórico | Necesita nodos extra y una base de datos | DAQ integrado con SQLite o InfluxDB |
| Lógica | En los flujos | Scripts y eventos en los objetos de la pantalla |
| Uso típico | Supervisión rápida, pantallas de prueba | HMI de operador, sinópticos de proceso, SCADA pequeño |
FUXA es una capa de HMI y supervisión. La lógica de control y los enclavamientos se quedan en el programa del PLC, así la máquina sigue funcionando si la HMI se detiene.
FUXA, Node-RED y Mosquitto: cómo se conectan las piezas
Los tres programas funcionan en el mismo Raspberry PLC y hablan por MQTT en localhost. Cada uno tiene su puerto:
- 1 · CampoE/S del PLCQ0.0 a Q0.7, I0.0 a I0.12 (Raspberry PLC 21)
- 2 · Puente de E/SNode-REDLos nodos librpiplc leen y escriben los pines. Puerto 1880
- 3 · MensajesBroker MosquittoTopics MQTT Q/... e I/... Puerto 1883
- 4 · OperadorFUXAHMI en el navegador. Puerto 1881, editor en /editor
Los topics MQTT son el contrato entre Node-RED y FUXA. El payload es un JSON con la zona, el índice del pin dentro de esa zona y el valor:
| Sentido | Topic | Ejemplo de payload | Publica | Se suscribe |
|---|---|---|---|---|
| Orden a una salida | Q/Q0.0 | {"zone":0,"index":0,"value":1} | FUXA | Node-RED (topic Q/#) |
| Estado de una entrada | I/I0.7 | {"value":2048,"index":7,"zone":0} | Node-RED | FUXA (topic I/#) |
Las entradas y salidas digitales usan 0 y 1. Las entradas analógicas de un Raspberry PLC son de 12 bits, por lo que devuelven de 0 a 4095 para 0 a 10 V (fuente: documentación de node-red-librpiplc).
Hardware y software para la HMI con FUXA
| Elemento | Lo que usa esta guía |
|---|---|
| PLC | Un PLC de la familia Raspberry PLC. El ejemplo usa el Raspberry PLC 21 (modelo RPIPLC_21 en Node-RED). La lista de pines cambia según el modelo: consulta las características técnicas. |
| Almacenamiento | Tarjeta micro SD en el PLC |
| Cableado de prueba | Cables y una fuente de 0 a 10 V para probar entradas y salidas |
| Sistema operativo | Raspberry Pi OS. Las imágenes de Industrial Shields vienen con la mayoría de ajustes hechos. |
| Librería de E/S | librpiplc, si aún no está instalada |
| Broker MQTT | Mosquitto |
| Puente de E/S | Node-RED con @industrial-shields/node-red-librpiplc |
| HMI | FUXA desde npm (@frangoteam/fuxa-min) |
Instalar Mosquitto
El broker, y los clientes de línea de comandos para las pruebas del final:
sudo apt install mosquitto mosquitto-clients
Desde Mosquitto 2.0, un broker sin archivo de configuración solo acepta conexiones de la misma máquina. Aquí es suficiente, porque Node-RED y FUXA funcionan en el PLC. Más opciones en cómo instalar Mosquitto en un Raspberry PLC.
Instalar Node-RED
Si Node-RED no está instalado, ejecuta el script oficial con el usuario normal (ver también cómo instalar Node-RED en un Raspberry PLC):
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
Instalar FUXA
Instala FUXA de forma global con npm. El paquete fuxa-min no incluye la librería de Siemens S7 (node-snap7). La documentación de FUXA avisa de que la instalación en Linux puede ser complicada y propone fuxa-min si no necesitas S7. Hay otras opciones de instalación en la documentación de FUXA.
sudo npm install -g --unsafe-perm @frangoteam/fuxa-min
La documentación de FUXA recomienda Node.js 18 LTS. Si la instalación falla con la versión de Node.js que instaló Node-RED, consulta allí las versiones compatibles.
Flujo de Node-RED: de las E/S del PLC a topics MQTT
Paso 1: abrir Node-RED e instalar los nodos del PLC
Abre Node-RED en un navegador:
http://<IP del PLC>:1880
Instala el paquete node-red-librpiplc con los nodos del PLC, que necesitan librpiplc en el PLC.
- Ve a Menú de Node-RED > Manage palette > Install.
- Busca @industrial-shields/node-red-librpiplc e instálalo.
Un solo nodo de configuración del PLC. Los nodos de lectura y escritura comparten un nodo de configuración con la versión y el modelo del PLC. Mantén uno solo en toda la instancia de Node-RED: dos nodos de configuración pueden interferir entre ellos.
Paso 2: salidas, de MQTT a los pines del PLC
Añade un nodo MQTT in conectado al broker en localhost:1883 (el puerto MQTT por defecto).
Suscríbete al topic comodín Q/#. Recibe las órdenes de todas las salidas.

Añade un nodo JSON para interpretar el mensaje y un nodo Debug para verlo.
Añade nodos Switch para encaminar cada mensaje por zona y por índice (en el RPIPLC_21: Q0.0 a Q0.7).


Añade un nodo Change por salida que asigne msg.payload.value a msg.payload.

Añade un nodo Digital Write por salida. En el Raspberry PLC 21, Q0.5, Q0.6 y Q0.7 también pueden funcionar como salidas analógicas (0 a 10 V, 12 bits). Para usar una de ellas como salida analógica, usa Analog Write, con valores de 0 a 4095.

Conecta los nodos como en la imagen.

Paso 3: entradas, de los pines del PLC a MQTT
Añade un nodo Inject por entrada, con el topic I/<nombre del pin> (por ejemplo I/I0.0). Configúralo para que se repita cada 0,1 segundos, así las entradas se refrescan rápido.

Añade un nodo Digital Read o Analog Read por entrada. En el RPIPLC_21, I0.0 a I0.6 son digitales e I0.7 a I0.12 son analógicas. Selecciona el modelo y la versión de tu PLC, y después el pin de cada nodo.

Añade nodos Change para construir el payload JSON de cada entrada:
- En la primera regla, asigna a msg.payload el JSON {"value":payload}.
- Añade una segunda regla que asigne a msg.payload.index el índice de la entrada.
- Copia este nodo para cada entrada y cambia el índice.
Añade otro nodo Change que asigne msg.payload.zone al grupo de entradas, y conecta a él todos los nodos Change de las entradas.


Añade un nodo JSON y un nodo Debug después del último nodo Change.
Añade un nodo MQTT out en localhost:1883 y deja su topic vacío. Así el nodo publica cada mensaje en el topic que fija el nodo Inject (I/I0.0, I/I0.1...).

Conecta todos los nodos con el mismo patrón.

Flujo de Node-RED completo
Con salidas y entradas, el flujo queda así:

Flujo de Node-RED (JSON). Impórtalo desde Menú de Node-RED > Import > select a file to import y después selecciona el modelo de PLC en el nodo de configuración.
Frecuencia de mensajes. Con 13 entradas cada 0,1 segundos, el flujo publica 130 mensajes por segundo, aunque nada cambie. En localhost no es un problema. Para reducir el tráfico, añade un nodo filter (envío por excepción) después de cada nodo de lectura, así solo sale un mensaje cuando el valor cambia. Para las entradas analógicas, usa una banda muerta.
Dispositivo MQTT y tags de FUXA para cada pin del PLC
Paso 1: arrancar FUXA
sudo fuxa
Después abre el editor de FUXA:
http://<IP del PLC>:1881/editor
Paso 2: conectar FUXA al broker MQTT
Abre el menú Setup (Edit Project) con el botón del engranaje, arriba a la izquierda.

Selecciona Connections.

En la página Device settings, pulsa el botón más (+) para añadir un dispositivo. Pon el tipo MQTTclient y la dirección mqtt://127.0.0.1:1883, como en la imagen.

Cuando la conexión funciona, aparece un círculo verde junto al dispositivo MQTT.

Paso 3: añadir los tags de las salidas
Pulsa Edit device tags junto al dispositivo MQTT (el botón al lado del lápiz). Aquí se añaden los pines que quieres usar. Este ejemplo usa los mismos pines que el flujo de Node-RED: Q0.0 a Q0.7 e I0.0 a I0.12.

Pulsa el botón más (+) abajo a la derecha. En Broker Topics to subscribe and publish, selecciona Publish y escribe Q0.0_value como nombre y ruta del topic. Pulsa Publish y después Close. Este tag guarda el valor que escribirá el interruptor.

Añade una segunda conexión Publish con el nombre de topic Q0.0 y la ruta Q/Q0.0. Pulsa Add attribute to payload tres veces y después JSON. En la columna Key escribe zone, index y value. Pon el tipo de las dos primeras en Static con el valor 0 (zona 0, índice 0), y deja la tercera como Tag con el tag Q0.0_value.

Repite para Q0.1 a Q0.7, con el índice de cada salida. El resultado es como el de la imagen.

Paso 4: añadir los tags de las entradas
Crea una nueva conexión y deja la opción Subscribe. Escribe I/# en la barra de búsqueda y pulsa la lupa. FUXA muestra los topics que publica el flujo de Node-RED.

Selecciona I/I0.0 y pulsa JSON para ver los campos. Desmarca index y zone, que esta HMI no necesita. En la columna Name escribe I0.0 (si no, el nombre es I/I0.0[value]). Pulsa Subscribe y después Close.

Repite para el resto de entradas. El resultado es como el de la imagen.

Configuración de dispositivos de FUXA (JSON), con el dispositivo y todos los tags. Para importarla, abre Device settings, pulsa el menú de tres puntos y selecciona Import devices.

Panel de FUXA para las E/S del PLC: interruptores, tabla, indicador y gráficos
Con el dispositivo y los tags listos, el siguiente paso es dibujar la pantalla y enlazar cada objeto con un tag.
Paso 1: preparar la vista
Abre el editor en http://<IP del PLC>:1881/editor, o ve a Views en el menú Setup.
Usa la vista por defecto o crea una nueva: pulsa el botón más (+) de la lista Views, escribe un nombre y pulsa OK.


Abre las propiedades de la vista con el menú de tres puntos. Puedes fijar el ancho y el alto, elegir un tamaño predefinido y cambiar el color de fondo.


En Setup > User Interface > Layout, selecciona la vista por defecto (la primera que se muestra) y elige si se muestra el menú de navegación y si se pide inicio de sesión al arrancar.

Paso 2: interruptores para las salidas digitales
Añade los títulos Outputs e Inputs con la herramienta Text Tool.


Añade un interruptor. Haz clic en él y abre Property en la ventana emergente de la izquierda.


Configura los colores, los valores y el texto del interruptor.

En el campo Tag, selecciona el dispositivo MQTT y el tag Q0.0_value.

Copia el interruptor para el resto de salidas y cambia el tag de cada copia. Etiqueta cada interruptor con su pin (Q0.0, Q0.1...) con la herramienta Text Tool.

Guarda el proyecto con el botón Save de arriba a la izquierda. Abre http://<IP del PLC>:1881 y prueba los interruptores.
Paso 3: una tabla para las entradas digitales
Añade una tabla con el botón Table.


Haz clic en la tabla y después en Property, a la derecha. Configura los colores y el tamaño de letra antes de añadir las entradas.


Abre el Table customizer con el botón del lápiz.

Con el botón de tres puntos de cada columna, llama Pin a la primera columna y Value a la segunda. Pon el tipo de las dos en Label.

Añade una fila por entrada digital con el botón más (+) de abajo a la izquierda.

Escribe el nombre del pin (I0.0, I0.1...) en la columna izquierda. En la columna derecha, cambia el tipo de celda a Variable y selecciona el tag de la entrada.


Pulsa OK, guarda el proyecto y prueba las entradas en la página principal.

Paso 4: indicador y gráficos para las entradas analógicas
Una entrada analógica es un rango de valores, no 0 o 1, así que necesita otros objetos. Este ejemplo usa tres.
Indicador circular
Añade un indicador circular.


Abre Property y selecciona el tag de la entrada, por ejemplo I0.7.

Elige uno de los tres diseños. Pon el mínimo en 0 y el máximo en 4095, el fondo de escala de la entrada de 12 bits (10 V). La imagen muestra 4096: la diferencia es de una unidad.

Guarda y prueba. Con 10 V en la entrada el indicador está lleno, con 5 V está a la mitad y con 3,3 V a un tercio.

Gráfico de líneas
Un gráfico de líneas muestra cómo cambia el valor analógico en el tiempo. Primero configúralo en Setup > Line Charts.

Añade una configuración con el botón más (+) y ponle nombre. En su menú de tres puntos, selecciona Add Line y elige el tag de la entrada. Cambia el color si hace falta.

Añade un gráfico de líneas a la vista con el botón Chart.


En Property, selecciona la configuración que acabas de crear. Puedes ocultar la leyenda o cambiar otras opciones.

Guarda el proyecto y comprueba el gráfico de líneas en la página principal.

Gráfico de barras
Un gráfico de barras muestra todas las entradas analógicas juntas.

Como con el gráfico de líneas, crea una configuración de gráfico con el botón más (+). En el menú de tres puntos, añade como fuentes los tags de las entradas analógicas. Configura los colores y guarda la configuración.

Añade el gráfico de barras a la vista con el botón Bar Graph.


En Property, selecciona la configuración en Graph to show y configura los colores.

Guarda el proyecto y comprueba el gráfico de barras en la página principal.

Script de FUXA para apagar todas las salidas
Un script de FUXA se puede ejecutar cuando un operador hace clic en un botón o en una imagen. Este ejemplo apaga todas las salidas con un solo clic.
Abre Scripts en el menú Setup.

Pulsa el botón más (+) abajo a la derecha para añadir un script. En su menú de tres puntos, selecciona Edit Script Name y da a la función principal un nombre claro, como resetOutputs().


Pulsa el signo menor que (<) arriba a la derecha de la ventana. En la lista System Functions, selecciona $setTag(TagID, value) y después el tag de la salida que quieres cambiar.


Pon el valor 0 para apagar la salida. Repite para cada tag de salida. Pon estas llamadas dentro de una función: el script se lee mejor cuando crece.

Añade una imagen con el botón Image Tool (embedded) y ajusta su tamaño.


Haz clic en la imagen, abre Property y ve a la pestaña Events. Añade un evento de tipo click, con la acción Run Script y el script resetOutputs().

Un botón en pantalla no es una parada de emergencia. El script "apagar todas las salidas" es una ayuda para el operador. La parada de emergencia de una máquina debe ser cableada e independiente de la HMI, de la red y del broker.
Probar la HMI y dejarla lista para la planta
La pantalla terminada lee y escribe todas las E/S del Raspberry PLC 21. Prueba cada entrada y cada salida antes de usarla en una máquina.

Proyecto completo de FUXA (JSON), con dispositivos, tags, scripts y la pantalla. Impórtalo con el botón Save de arriba a la izquierda del editor.
Comprobar el tráfico MQTT desde la línea de comandos
Si un interruptor o una entrada no responde, mira si el problema está del lado de Node-RED o del lado de FUXA. Observa los topics de entrada:
mosquitto_sub -h localhost -t 'I/#' -v
Publica a mano una orden de salida. Si Q0.0 se activa, el lado de Node-RED funciona y el problema está en los tags de FUXA:
mosquitto_pub -h localhost -t 'Q/Q0.0' -m '{"zone":0,"index":0,"value":1}'
Antes de llevar la HMI a la máquina
- Arranque automático. Ejecuta FUXA como servicio systemd, igual que Node-RED y Mosquitto. Ver el ejemplo de servicios systemd en un Raspberry PLC.
- Control de acceso. Pide inicio de sesión en FUXA, protege el editor de Node-RED (adminAuth en settings.js) y no expongas los puertos 1880, 1881 y 1883 a internet. Si otras máquinas tienen que llegar al broker, configura un listener con usuarios y contraseñas. Ver fundamentos de seguridad MQTT.
- Panel de operador. Abre la HMI a pantalla completa en una pantalla táctil con un navegador en modo kiosco. El ejemplo de modo kiosco usa un dashboard de Node-RED, y el mismo método funciona con la dirección de FUXA.
- Copias de seguridad. Exporta el proyecto de FUXA y el flujo de Node-RED después de cada cambio y guárdalos con la documentación de la máquina.
Más sobre Node-RED, MQTT y HMI en un Raspberry PLC
- Node-RED y los pines del PLC: activar salidas digitales, leer entradas digitales, leer entradas analógicas y trabajar con MQTT.
- Ejemplos probados en la PLC Solution Library: controlar una salida digital desde Node-RED, un broker Mosquitto central para una flota de PLC y un puente de MQTT a SQL Server en Python.
- Otras opciones: Rapid SCADA en un panel PC Raspberry Pi, Modbus TCP y RTU en los Raspberry PLC, y una comparativa de Node-RED, CODESYS y Arduino IDE.
- Mira una pantalla de supervisión terminada con datos MQTT en el simulador Machine Monitor.
Un PLC para el control, los datos y la pantalla del operador. En el caso de automatización logística, un Raspberry PLC lee un lector de códigos de barras, mueve las cintas, tiene su propia base de datos y su propio servidor, y muestra los datos de cada paquete en una pantalla del almacén.
Preguntas frecuentes sobre FUXA en un Raspberry PLC
¿FUXA es gratuito y de código abierto?
Sí. FUXA se publica en GitHub con licencia MIT. Funciona en Linux, Windows y macOS, en Docker y en una Raspberry Pi.
¿Por qué no conectar FUXA directamente a los pines del PLC?
La mayoría de las E/S de un Raspberry PLC están en chips I2C (expansores, ADC y un driver de salidas), no en el conector GPIO. El driver GPIO de FUXA solo llega a los GPIO directos. Node-RED con los nodos librpiplc conoce el mapa de pines de cada modelo.
¿FUXA puede leer equipos Modbus u OPC UA desde el mismo PLC?
Sí. FUXA tiene sus propios drivers Modbus RTU y TCP, OPC UA, BACnet y EtherNet/IP, y S7 en el paquete completo (no en fuxa-min). Una misma pantalla puede mostrar las E/S del PLC por MQTT y, por ejemplo, un analizador de energía por Modbus TCP.
¿Qué rango dan las entradas analógicas en FUXA?
Las entradas analógicas del Raspberry PLC son de 12 bits: de 0 a 4095 para 0 a 10 V. Para mostrar voltios, escala el valor en Node-RED antes de publicarlo, por ejemplo con un nodo range de 0 a 4095 a 0 a 10.
¿FUXA vuelve a arrancar después de un reinicio?
No por sí solo si lo instalas con npm. Crea un servicio systemd para FUXA, como para cualquier programa que deba funcionar en el PLC sin sesión de usuario.
¿Los operadores pueden usar la HMI desde otro ordenador o una tablet?
Sí. Abre http://<IP del PLC>:1881 en un navegador de la misma red. Activa antes el inicio de sesión de FUXA y mantén el puerto 1881 dentro de la red de la planta.