Fabricación inteligente

SPC en tiempo real con MQTT: gráficos de control en vivo y alertas de fuera de control

Transmite mediciones por MQTT, calcula los límites de control X-barra y R en Python, aplica las reglas de Western Electric a cada nuevo subgrupo y muestra los puntos fuera de control en un dashboard en vivo en cuestión de segundos.

Gráfico de control SPC en tiempo real con límites de control superior e inferior y puntos fuera de control resaltados transmitidos por MQTT
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

El SPC en tiempo real convierte el control estadístico de procesos, que antes era un ejercicio semanal en una hoja de cálculo, en una señal en vivo en la planta. En este tutorial transmitirás mediciones por MQTT, calcularás los límites de control X-barra y R en Python, comprobarás cada nuevo subgrupo frente a las reglas de Western Electric y mostrarás los puntos fuera de control en un dashboard en vivo pocos segundos después de la medición.

Por qué el SPC debe ser en tiempo real

El control estadístico de procesos separa la variación normal, de causa común, de las causas especiales, como una herramienta desgastada, un nuevo lote de material o un cambio de temperatura. Su propósito es reaccionar antes de que las piezas salgan de especificación. Ese propósito se pierde si los gráficos se actualizan al final del turno con valores tecleados a mano: para entonces, el proceso puede llevar horas derivando.

Cuando las mediciones ya fluyen desde calibres en línea, como se describe en control de calidad con IoT en manufactura, no hay motivo para esperar. Un pequeño servicio puede mantener el gráfico de control de forma continua y avisar al operario en la primera violación de una regla.

Fundamentos de SPC en cinco minutos

Este tutorial usa el clásico gráfico X-barra y R, adecuado para mediciones tomadas en subgrupos pequeños (aquí, cinco piezas consecutivas).

Para cada subgrupo se calcula:

  • X-barra: la media de los cinco valores. Sigue el centro del proceso.
  • R: el rango (máximo menos mínimo). Sigue la variación a corto plazo.

A partir de un conjunto inicial de subgrupos bajo control (normalmente de 20 a 25) se calcula la gran media (X-doble-barra) y el rango medio (R-barra), y después los límites de control con las constantes estándar para un tamaño de subgrupo de 5:

Gráfico Línea central Límite de control superior Límite de control inferior
X-barra X-doble-barra X-doble-barra + A2 x R-barra X-doble-barra - A2 x R-barra
R R-barra D4 x R-barra D3 x R-barra

Para n = 5 las constantes son A2 = 0.577, D3 = 0 y D4 = 2.114.

Los límites de control provienen del propio proceso, no de la especificación. Un proceso puede estar bajo control y aun así producir piezas fuera de especificación si no es capaz, y puede estar fuera de control mientras todas las piezas siguen dentro de tolerancia. Ese segundo caso es exactamente donde el SPC en tiempo real resulta rentable.

Reglas para señales de fuera de control

Regla Señal Causa típica
1 Un punto más allá de un límite de control Causa especial repentina: ajuste incorrecto, herramienta rota
2 Dos de tres puntos consecutivos más allá de 2 sigma en el mismo lado Inicio de un desplazamiento
3 Cuatro de cinco puntos consecutivos más allá de 1 sigma en el mismo lado Desplazamiento sostenido más pequeño
4 Ocho puntos consecutivos en el mismo lado de la línea central La media del proceso se ha movido

Estas son las reglas de Western Electric. Aplicar las cuatro aumenta la sensibilidad, pero también la tasa de falsas alarmas, por lo que muchas plantas empiezan con las reglas 1 y 4.

Arquitectura

gauge / simulator --> .../station40/measurement --> MQTT broker
                                                       |
                                    SPC service (Python) subscribes
                                                       |
             .../station40/spc/limits (retained)  +  .../station40/spc/point
                                                       |
                                       live dashboard subscribes (WSS)

Para el tutorial todo se ejecuta en el servidor MQTT público gratuito en broker.connectmq.com, pensado para pruebas y no para datos de producción. Elige un ID aleatorio y úsalo en todos los topics para que tus datos no se mezclen con los de nadie más.

Paso 1: simular una estación de medición

Si todavía no tienes un calibre conectado, este simulador publica el diámetro de un agujero dos veces por segundo. Tras 200 piezas introduce una deriva lenta hacia arriba, del tipo que causan el desgaste de la herramienta o la dilatación térmica.

import json
import random
import time
from datetime import datetime, timezone
import paho.mqtt.client as mqtt

TOPIC = "connectmq/demo/3d9c57/line3/station40/measurement"
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="spc-sim-3d9c57")
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()

part = 0
while True:
    part += 1
    drift = max(0, part - 200) * 0.00004
    value = random.gauss(22.000 + drift, 0.003)
    msg = {"ts": datetime.now(timezone.utc).isoformat(timespec="milliseconds"),
           "serial": f"A3-{part:06d}", "value": round(value, 4)}
    client.publish(TOPIC, json.dumps(msg), qos=1)
    time.sleep(0.5)

Paso 2: el servicio de SPC en tiempo real

El servicio agrupa las mediciones en subgrupos de cinco, usa los primeros 25 subgrupos para calcular los límites de control (Fase I), publica los límites como mensaje retained y después evalúa cada nuevo subgrupo frente a las reglas (Fase II). Cada subgrupo evaluado se publica como un punto con las violaciones que tenga.

import json
import statistics
from collections import deque
import paho.mqtt.client as mqtt

BASE = "connectmq/demo/3d9c57/line3/station40"
N = 5
PHASE1_SUBGROUPS = 25
A2, D3, D4 = 0.577, 0.0, 2.114

buffer = []
phase1 = []
limits = None
history = deque(maxlen=8)  # valores X-barra recientes

def zone(x):
    sigma = (limits["ucl_x"] - limits["cl_x"]) / 3
    return (x - limits["cl_x"]) / sigma

def check_rules(xbar, r):
    v = []
    if not limits["lcl_x"] <= xbar <= limits["ucl_x"]:
        v.append("rule1_xbar")
    if r > limits["ucl_r"]:
        v.append("rule1_range")
    z = [zone(x) for x in history]
    for side in (1, -1):
        if len(z) >= 3 and sum(1 for s in z[-3:] if s * side > 2) >= 2:
            v.append("rule2")
        if len(z) >= 5 and sum(1 for s in z[-5:] if s * side > 1) >= 4:
            v.append("rule3")
        if len(z) == 8 and all(s * side > 0 for s in z):
            v.append("rule4")
    return sorted(set(v))

def on_connect(client, userdata, flags, reason_code, properties):
    client.subscribe(f"{BASE}/measurement", qos=1)

def on_message(client, userdata, msg):
    global limits
    buffer.append(json.loads(msg.payload))
    if len(buffer) < N:
        return
    values = [m["value"] for m in buffer]
    serials = [buffer[0]["serial"], buffer[-1]["serial"]]
    buffer.clear()
    xbar, r = statistics.fmean(values), max(values) - min(values)

    if limits is None:
        phase1.append((xbar, r))
        if len(phase1) == PHASE1_SUBGROUPS:
            xbb = statistics.fmean(x for x, _ in phase1)
            rbar = statistics.fmean(rr for _, rr in phase1)
            limits = {"cl_x": xbb, "ucl_x": xbb + A2 * rbar, "lcl_x": xbb - A2 * rbar,
                      "cl_r": rbar, "ucl_r": D4 * rbar, "lcl_r": D3 * rbar, "n": N}
            client.publish(f"{BASE}/spc/limits", json.dumps(limits), qos=1, retain=True)
            print("limits", limits)
        return

    history.append(xbar)
    violations = check_rules(xbar, r)
    point = {"xbar": round(xbar, 5), "range": round(r, 5),
             "serials": serials, "violations": violations,
             "in_control": not violations}
    client.publish(f"{BASE}/spc/point", json.dumps(point), qos=1)
    if violations:
        client.publish(f"{BASE}/spc/alarm", json.dumps(point), qos=1, retain=True)
        print("OUT OF CONTROL", point)

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="spc-service-3d9c57")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_forever()

Ejecuta el simulador y el servicio en dos terminales. Tras 125 piezas (aproximadamente un minuto) aparecen los límites. Poco después de la pieza 200 empieza la deriva y, en unas cien piezas, normalmente verás violaciones de la regla 4, la regla 3 o la regla 2, mientras cada pieza individual sigue holgadamente dentro de una especificación típica. Esa es la alerta temprana para la que está diseñado el SPC.

Paso 3: un dashboard de SPC en vivo

Cualquier dashboard compatible con MQTT puede suscribirse a spc/limits y spc/point. El siguiente script con MQTT.js es una vista en vivo mínima que se conecta por Secure WebSocket, exactamente como lo haría un dashboard en el navegador, e imprime cada subgrupo como una posición entre los límites de control, marcando las violaciones. Instálalo con npm install mqtt y ejecútalo con Node.js 18 o posterior.

const mqtt = require("mqtt");

const BASE = "connectmq/demo/3d9c57/line3/station40/spc";
const client = mqtt.connect("wss://broker.connectmq.com:8084/mqtt", {
  clientId: "spc-dash-3d9c57",
  protocolVersion: 5,
});

let limits = null;

client.on("connect", () => {
  client.subscribe([`${BASE}/limits`, `${BASE}/point`], { qos: 1 });
  console.log("connected, waiting for limits...");
});

client.on("message", (topic, payload) => {
  const data = JSON.parse(payload.toString());
  if (topic.endsWith("/limits")) {
    limits = data;
    console.log(`LCL ${data.lcl_x.toFixed(4)}  CL ${data.cl_x.toFixed(4)}  UCL ${data.ucl_x.toFixed(4)}`);
    return;
  }
  if (!limits) return;
  const width = 41;
  const span = limits.ucl_x - limits.lcl_x;
  let pos = Math.round(((data.xbar - limits.lcl_x) / span) * (width - 1));
  const outside = pos < 0 || pos > width - 1;
  pos = Math.min(Math.max(pos, 0), width - 1);
  const line = Array(width).fill(" ");
  line[Math.floor(width / 2)] = "|";
  line[pos] = outside ? "X" : data.in_control ? "o" : "!";
  const flags = data.violations.length ? data.violations.join(",") : "";
  console.log(`[${line.join("")}] ${data.xbar.toFixed(4)} R=${data.range.toFixed(4)} ${flags}`);
});

Como los límites son retained, el dashboard se dibuja correctamente aunque arranque mucho después que el servicio de SPC. En una página web, el mismo código funciona con la versión para navegador de MQTT.js y alimenta una librería de gráficos en lugar de la consola. El explorador de topics en vivo del portal de ConnectMQ también es útil para observar spc/point y spc/alarm mientras ajustas las reglas.

Reaccionar a las señales del SPC en tiempo real

Un gráfico sobre el que nadie actúa es pura decoración. Antes de activar las alarmas, acuerda con el equipo de línea qué significa cada señal y qué pasa después. Una violación de la regla 1 en el gráfico X-barra suele exigir una revisión inmediata de las últimas piezas y del ajuste de la máquina. Una racha de la regla 4, con puntos a un lado de la línea central, apunta a un desplazamiento gradual, como el desgaste de la herramienta o la dilatación térmica, por lo que la reacción podría ser un ajuste del offset de la herramienta o un cambio de herramienta anticipado. Una violación de la regla 1 en el gráfico R significa que la variación ha aumentado, lo que a menudo indica una sujeción floja, un filo dañado o un material irregular.

Redacta estas reacciones en un breve plan de acción ante fuera de control por característica y muéstralo junto al gráfico. Correlacionar las señales de SPC con los datos del husillo procedentes de la monitorización del desgaste de herramientas es una buena forma de confirmar si un desplazamiento se debe a la herramienta antes de que nadie toque la máquina. Con el tiempo, las causas y reacciones registradas se convierten en la parte más valiosa del sistema, porque muestran qué causas especiales se repiten y qué mejoras de proceso las eliminarían definitivamente.

Prepararlo para producción

  1. Persiste los límites. Guarda los límites calculados en una base de datos o un archivo de configuración y recalcúlalos solo de forma deliberada tras un cambio de proceso, nunca automáticamente durante una deriva.
  2. Excluye las causas especiales conocidas de los datos de la Fase I. Si una herramienta se rompió durante el periodo de referencia, elimina esos subgrupos antes de calcular los límites.
  3. Un gráfico por característica y receta. Productos distintos necesitan límites distintos; incluye la receta en el topic o en el payload.
  4. Registra la reacción. Cuando salte una alarma, anota qué encontró e hizo el operario. Un SPC sin plan de reacción es solo un gráfico.
  5. Usa un broker privado. Los datos de calidad son confidenciales. Pasa a un broker MQTT gestionado con credenciales del portal y TLS en el puerto 8883 o WSS en el 8084.
  6. Usa QoS 1 para las mediciones, de modo que no se formen subgrupos con datos incompletos tras un corte de red.

El SPC en tiempo real también se vincula de forma natural con la trazabilidad: como cada punto lleva el rango de números de serie de su subgrupo, sabes exactamente qué piezas se produjeron mientras el proceso estaba fuera de control. La guía del sistema de trazabilidad en manufactura muestra cómo almacenar esa relación. Para una visión más amplia de la arquitectura de datos de planta, consulta la guía de manufactura inteligente.

Transmite tus datos de SPC a través de ConnectMQ

ConnectMQ ofrece a tus calibres, tu servicio de SPC y tus dashboards una única columna vertebral MQTT 5 segura, con TLS, acceso por WebSocket para dashboards en el navegador, mensajes retained y un explorador de topics en vivo. Empieza con el plan gratuito Serverless en app.connectmq.com, sin tarjeta de crédito.

Preguntas frecuentes

¿Qué es el SPC en tiempo real?

Es el control estadístico de procesos en el que los gráficos de control y la comprobación de reglas se actualizan automáticamente con la llegada de cada medición, de modo que las condiciones de fuera de control se señalan en segundos y no al final del turno.

¿Cuántos subgrupos necesito para calcular los límites de control?

La pauta habitual es de 20 a 25 subgrupos de un proceso estable. Elimina los subgrupos afectados por causas especiales conocidas antes de calcular.

¿Los límites de control son lo mismo que los límites de especificación?

No. Los límites de control describen lo que el proceso hace realmente, mientras que los límites de especificación describen lo que exige el cliente. Se calculan y se usan de forma diferente.

¿Qué reglas de Western Electric debo activar primero?

Empieza con un punto fuera de los límites y ocho puntos en un lado de la línea central. Añade las reglas de zona cuando los operarios confíen en las alarmas.

Artículos relacionados

OEE vs TEEP vs OOE: ¿qué indicador deberías usar?

OEE, OOE y TEEP comparten los mismos factores de rendimiento y calidad, pero se miden frente a bases de tiempo distintas. Esta comparativa resuelve un único ejemplo y enumera las señales MQTT que necesita cada indicador.

8 min de lectura

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.