La monitorización de máquinas CNC responde a la pregunta sobre la que discute todo taller de mecanizado: ¿cuánto tiempo del día están cortando realmente los husillos? En este tutorial recogerás el estado de ejecución, el programa activo, la carga del husillo y el contador de piezas de un control CNC, los publicarás por MQTT y calcularás una utilización en la que puedas confiar. Los ejemplos usan MTConnect, con notas sobre otros controles y una alternativa con sensor de corriente para máquinas antiguas.
Por qué compensa la monitorización de máquinas CNC
La mayoría de los talleres sobrestiman la utilización. Una máquina que parece ocupada puede estar esperando la verificación de primera pieza, una herramienta, una edición del programa o a un operario que atiende otras dos máquinas. Sin datos, estos huecos se esconden dentro del turno. En cuanto el estado de ejecución se registra segundo a segundo, el patrón de pérdidas se hace visible: preparaciones largas en ciertos trabajos, ciclos de calentamiento demasiado largos o una máquina que se queda parada todas las tardes porque el material llega tarde.
Una buena monitorización CNC también ayuda más allá de la utilización. Las tendencias de carga del husillo revelan el desgaste de las herramientas, los contadores de piezas alimentan los presupuestos y la planificación, y los nombres de programa vinculan el tiempo de máquina con trabajos concretos.
Qué señales recoger
| Señal | Fuente habitual | Por qué importa |
|---|---|---|
| Estado de ejecución (ACTIVE, READY, STOPPED, INTERRUPTED, FEED_HOLD) | Control | Núcleo de la utilización y las paradas |
| Modo del control (AUTOMATIC, MANUAL, MDI, EDIT) | Control | Separa producción de preparación y prueba |
| Nombre del programa activo | Control | Vincula el tiempo con trabajos y piezas |
| Carga del husillo (%) | Control | Distingue corte real de corte en vacío, desgaste de herramienta |
| Velocidad del husillo y override de avance | Control | Muestra si los operarios ralentizan los programas |
| Contador de piezas | Control o variable de macro | Conteo de producción y tiempo de ciclo |
| Código y mensaje de alarma | Control | Motivos de parada sin intervención del operario |
| Corriente del motor del husillo | Sensor CT externo | Alternativa para máquinas sin puerto de datos |
Empieza por ejecución, modo, programa y contador de piezas. Esas cuatro señales dan la utilización por trabajo. Añade la carga del husillo y las alarmas cuando lo básico sea estable.
Sacar los datos del control
Cómo leas el control depende de la marca y la antigüedad:
- MTConnect. Muchas máquinas modernas incluyen un adaptador MTConnect, o se puede añadir uno. Un agente MTConnect expone el estado actual de la máquina por HTTP en XML, fácil de consultar e independiente del fabricante. La guía de MTConnect a MQTT cubre en detalle la configuración del agente.
- OPC UA. Varios controles ofrecen un servidor OPC UA opcional. Un cliente OPC UA en el edge lee los mismos valores.
- Librerías del fabricante. Algunas familias de controles proporcionan su propio protocolo o librería para leer el estado. Funcionan, pero atan el código de tu gateway a una marca.
- E/S discretas y sensores de corriente. En máquinas antiguas sin puerto de red, cablea la lámpara de inicio de ciclo o coloca un transformador de corriente en el cable del motor del husillo. Pierdes los nombres de programa, pero sigues obteniendo una señal de marcha fiable.
Sea cual sea la fuente, el patrón después del edge es el mismo: normaliza los valores en un único esquema JSON y publícalos en un broker MQTT. Así los dashboards, los calculadores de OEE y las herramientas de mantenimiento quedan independientes de las marcas de control.
Diseño de topics y payloads
Usa un topic por máquina para el estado y otro para los datos de trabajo que cambian más despacio:
connectmq/demo/<your-id>/plant1/machining/cnc01/state
connectmq/demo/<your-id>/plant1/machining/cnc01/job
{
"execution": "ACTIVE",
"mode": "AUTOMATIC",
"spindle_load": 42.5,
"spindle_speed": 8000,
"part_count": 117,
"alarm": null,
"ts": "2026-10-16T09:14:05Z"
}
Publica el mensaje de estado como retenido para que cualquier suscriptor nuevo conozca de inmediato la condición actual de cada máquina. Si ya usas Sparkplug B en planta, ConnectMQ puede decodificar esos payloads y republicarlos en topics ISA-95 como connectmq/factory1/production/line1/cnc1/telemetry, de modo que ambas convenciones pueden convivir.
Construir el gateway de MTConnect a MQTT
Este gateway en Python consulta cada segundo el endpoint /current de un agente MTConnect, extrae los data items que configures y publica un mensaje solo cuando algo cambia, además de un heartbeat cada 30 segundos. Encuentra los ID de tus data items abriendo http://<agent>:5000/probe en un navegador.
import json
import time
import urllib.request
import xml.etree.ElementTree as ET
from datetime import datetime, timezone
import paho.mqtt.client as mqtt
AGENT_URL = "http://192.168.10.50:5000/current"
TOPIC = "connectmq/demo/k2m8q4/plant1/machining/cnc01/state"
# Map JSON field names to the dataItemId values from /probe
DATA_ITEMS = {
"execution": "exec",
"mode": "mode",
"program": "pgm",
"spindle_load": "Sload",
"spindle_speed": "Srpm",
"part_count": "pc",
}
NUMERIC = {"spindle_load", "spindle_speed", "part_count"}
def read_agent():
with urllib.request.urlopen(AGENT_URL, timeout=3) as resp:
root = ET.fromstring(resp.read())
by_id = {el.get("dataItemId"): el.text for el in root.iter() if el.get("dataItemId")}
result = {}
for field, item_id in DATA_ITEMS.items():
value = by_id.get(item_id)
if value in (None, "UNAVAILABLE"):
result[field] = None
elif field in NUMERIC:
result[field] = float(value)
else:
result[field] = value
return result
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="cnc01-gw-k2m8q4")
client.on_connect = on_connect
client.will_set(TOPIC, json.dumps({"execution": "OFFLINE"}), qos=1, retain=True)
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_start()
def fingerprint(data):
# Ignore fields that change constantly so we only publish real state changes
return {k: v for k, v in data.items() if k not in ("spindle_load", "spindle_speed")}
last_fp, last_time = None, 0.0
while True:
try:
data = read_agent()
except Exception as exc: # agent down or network issue
data = {"execution": "UNAVAILABLE", "error": str(exc)}
fp = fingerprint(data)
if fp != last_fp or time.time() - last_time > 30:
data["ts"] = datetime.now(timezone.utc).isoformat()
client.publish(TOPIC, json.dumps(data), qos=1, retain=True)
last_fp, last_time = fp, time.time()
time.sleep(1)
Hay dos detalles importantes. Primero, la carga y la velocidad del husillo se excluyen de la detección de cambios porque fluctúan constantemente; aun así viajan con cada cambio de estado y cada heartbeat. Si necesitas una tendencia de carga para el desgaste de herramientas, publícala en un topic load independiente a una tasa fija. Segundo, el mensaje Last Will marca la máquina como OFFLINE si el gateway cae, para que un gateway muerto nunca se confunda con una máquina en marcha.
Observa la salida desde cualquier terminal:
mosquitto_sub -h broker.connectmq.com -p 1883 -i cnc-viewer-k2m8q4 -t "connectmq/demo/k2m8q4/plant1/machining/+/state" -v
Convertir el estado en utilización
La utilización es el tiempo en estado productivo dividido entre el tiempo disponible. Define los estados de forma explícita, porque "en marcha" significa cosas distintas para distintas personas:
- Cortando: ejecución ACTIVE, modo AUTOMATIC. Es tiempo productivo.
- Prueba o preparación: ejecución ACTIVE en MANUAL o MDI, o un nombre de programa que coincida con tu convención de nombres de preparación.
- Lista pero parada: ejecución READY o STOPPED sin alarma. Normalmente esperando a un operario, material o inspección.
- Feed hold o interrumpida: el operario ha pausado el ciclo. A menudo por un control de calidad o un problema de virutas.
- Alarma: una alarma activa. Se planifica para el seguimiento de mantenimiento.
- Offline: sin datos. Trátalo como desconocido, no como parada.
Un suscriptor que guarde cada transición de estado con su marca de tiempo puede sumar las duraciones por estado y turno. Ese mismo flujo de eventos alimenta el seguimiento de paradas de máquinas, y cuando añades contadores de piezas y tiempos de ciclo ideales se convierte en OEE. El patrón general para cualquier tipo de máquina se describe en la monitorización del estado de las máquinas.
Errores habituales en la captura de datos CNC
- Tratar READY como en marcha. Una máquina con un programa cargado y la puerta cerrada no está produciendo. Solo ACTIVE en AUTOMATIC cuenta como corte.
- Reinicios del contador de piezas. Los operarios suelen reiniciar el contador al cambiar de trabajo. Registra el nombre del programa con cada conteo para que los reinicios sean explicables, y calcula la producción a partir de incrementos, no de valores absolutos.
- Deriva del reloj. Pon la marca de tiempo en el gateway con un reloj sincronizado (NTP), no en el dashboard, o las duraciones de estado serán incorrectas entre máquinas.
- Consultar demasiado rápido. Consultar
/currentcada segundo basta para el estado. Consultar más rápido añade carga al agente sin mejorar la precisión de la utilización. - Segmentación de red. Las redes de máquinas suelen estar aisladas. Ejecuta el gateway en un PC con una pata en la red de máquinas y una conexión solo saliente hacia el broker en el puerto 8883, para que nada en internet pueda llegar a los controles.
De una máquina a todo el taller
Empieza por las dos o tres máquinas que provocan más discusiones de planificación. Cuando las cifras coincidan con lo que ven los operarios, extiéndelo al resto del taller con el mismo esquema de payload. Como todas las máquinas publican en un único árbol de topics, una sola suscripción con un comodín como plant1/machining/+/state alimenta el dashboard del taller; el tutorial del dashboard de monitorización de líneas de producción muestra cómo construirlo con Grafana, y el mismo árbol de topics puede animar un gemelo digital 3D del taller.
Para producción, abandona el broker público y pasa a uno privado. Un broker MQTT gestionado como ConnectMQ da a cada gateway sus propias credenciales sobre TLS en el puerto 8883, y la vista de dispositivos del portal agrupa las máquinas por nivel ISA-95 para que veas de un vistazo qué gateways están conectados. Las reglas de alerta por umbral del portal pueden señalar, por ejemplo, una carga del husillo por encima de un límite. Si quieres entender primero las piezas, lee qué es un broker MQTT, y para la visión de conjunto consulta la guía de fabricación inteligente.
Empieza a monitorizar tus máquinas CNC con ConnectMQ
Regístrate en app.connectmq.com, crea un broker con el plan gratuito Serverless sin tarjeta de crédito y sustituye el host, el puerto y las credenciales en el gateway anterior. Tu primera máquina puede estar enviando datos de utilización en menos de una hora.
Preguntas frecuentes
¿Necesito MTConnect para monitorizar una máquina CNC?
No. MTConnect es práctico e independiente del fabricante, pero OPC UA, las librerías del fabricante o un simple sensor de corriente en el motor del husillo también funcionan. El lado MQTT sigue siendo el mismo.
¿Qué precisión tiene la utilización obtenida con un sensor de corriente?
Indica de forma fiable cuándo gira el husillo, lo que es una buena aproximación del corte. No puede decirte el programa ni el modo, así que la preparación y el corte en vacío pueden parecer producción.
¿Cuánto ancho de banda consume la monitorización CNC?
Muy poco. Los mensajes de estado ocupan unos cientos de bytes y se envían ante cambios más un heartbeat, así que incluso un taller grande genera una tasa de mensajes modesta.
¿Puedo monitorizar máquinas antiguas sin puerto de red?
Sí. Cablea la lámpara de inicio de ciclo o de ciclo en curso a una entrada digital de un ESP32 o de un PLC pequeño, o usa un transformador de corriente, y publica el estado de marcha por MQTT.



