iiOTESP32 Brasil
Modo de contingencia: las páginas públicas y las descargas siguen disponibles; el inicio de sesión, la comunidad y los datos del servidor pueden no estar disponibles.
Volver al catálogo de tutoriales
Ilustração: motor elétrico com sensores ligados a uma placa ESP32, ao lado de um monitor com gráficos de temperatura e vibração
Imagem ilustrativa gerada por IA
AvanzadoIIoTLectura: 18 min

Monitorización de temperatura y vibración de motores con ESP32

Nodo de mantenimiento predictivo con MPU6050 y termopar Tipo K: RMS de vibración, telemetría MQTT y una tendencia mecánica convertida en una alarma útil para SCADA.

Tecnologías:#ESP32#MPU6050#MAX31855#Termopar Tipo K#RMS#FFT#MQTT#SCADA

Requisitos de hardware:

  • Placa ESP32-WROOM-32 ou ESP32-S3
  • Acelerômetro triaxial MPU6050
  • Módulo MAX31855 compatível com termopar Tipo K
  • Termopar Tipo K instalado por profissional habilitado
  • Fonte regulada de 5 V e gabinete protegido para o nó sensor

Antes de encender: esto no es un instrumento de seguridad

Un ESP32 con MPU6050 y MAX31855 es un excelente nodo de adquisición y tendencia para laboratorio, prototipos y mantenimiento predictivo. Ayuda a descubrir que un motor se está calentando o vibrando más que su propia línea de base.

No sustituye un relé térmico, protección contra sobrecorriente, sensor industrial certificado, monitor de vibración dedicado ni ningún enclavamiento de seguridad. No instales, ajustes ni abras una caja cerca de un motor energizado sin capacitación eléctrica y sin el procedimiento de bloqueo y etiquetado de la planta.

El objetivo de este tutorial es concreto: medir de forma repetible, conservar el contexto de cada lectura y publicar una tendencia que alguien pueda interpretar antes de una falla.

Qué mide el nodo

El MPU6050 mide aceleración en tres ejes. En la carcasa de un motor, la vibración puede aparecer como aumento del RMS, cambio en la distribución de energía o aparición de componentes periódicos en el espectro. El sensor es barato y útil para experimentar, pero su montaje mecánico, rango y ancho de banda no equivalen a los de un acelerómetro industrial.

El MAX31855 convierte la señal de un termopar Tipo K e informa la temperatura de la unión caliente y posibles fallas del termopar. Utiliza SPI y no debe confundirse con un sensor digital de temperatura ambiente: el termopar necesita un punto definido de montaje en la carcasa, con contacto mecánico y aislamiento eléctrico adecuados.

El ESP32 recoge ambas señales, calcula indicadores simples y envía una carga MQTT parecida a esta:

code.cpp
cpp
1{
2 "ts": 1755990000,
3 "temperature_c": 67.4,
4 "vibration_rms_g": 0.082,
5 "vibration_peak_g": 0.31,
6 "crest_factor": 3.78,
7 "quality": 192,
8 "sample_count": 128
9}

La marca de tiempo es la de la lectura, no el momento en que el broker recibió el mensaje. La calidad indica si el valor es confiable. Sin esos dos campos, el gráfico puede parecer preciso y aun así llevar a una decisión equivocada.

El montaje importa más que el dashboard

Pega el MPU6050 con cinta de doble cara y el sensor empezará a medir la cinta, la caja y cualquier holgura. Para comparar tendencias, usa una fijación rígida y repetible, preferiblemente un tornillo o una base metálica diseñada para el punto de medición.

Marca la posición y la orientación de los ejes. Si cada visita de mantenimiento cambia el lado de la carcasa, el RMS deja de ser comparable. No mezcles mediciones del rodamiento, la tapa del motor y la base como si fueran el mismo punto.

El termopar también necesita una posición definida. La temperatura de la carcasa depende de la carga, ventilación, temperatura ambiente y tiempo de operación. Registra al menos el estado del motor y el tiempo desde el arranque cuando compares días distintos.

Conexiones eléctricas

El MPU6050 usa I2C. Este ejemplo usa SDA en GPIO 21 y SCL en GPIO 22. La dirección más común es 0x68; si AD0 está en nivel alto, pasa a ser 0x69.

El MAX31855 usa SPI: GPIO 18 para SCK, GPIO 19 para MISO y GPIO 5 para CS. El pin MOSI no es necesario para leer este conversor. Comprueba el pinout de tu módulo: placas de fabricantes diferentes pueden cambiar la serigrafía y el regulador de alimentación.

Todos los módulos deben compartir el GND del ESP32. Mantén el bus de baja tensión separado físicamente de conductores de potencia y cables del variador de frecuencia. El ruido eléctrico no se resuelve solo cambiando la biblioteca.

Fija el entorno antes de medir

Crea el proyecto en PlatformIO y fija las bibliotecas. El objetivo es evitar que dos compilaciones instalen APIs diferentes sin que nadie lo note.

code.cpp
cpp
1[env:esp32-motor-monitor]
2platform = espressif32
3board = esp32dev
4framework = arduino
5monitor_speed = 115200
6lib_deps =
7 adafruit/Adafruit MPU6050@^2.2.6
8 adafruit/Adafruit BusIO@^1.16.2
9 adafruit/Adafruit MAX31855 library@^1.4.2
10 knolleary/PubSubClient@^2.8
11 bblanchon/ArduinoJson@^7.2.1

Empieza con el ESP32 en el banco, sin motor y sin MQTT. Primero confirma que el MPU6050 responde por I2C, después comprueba la lectura del MAX31855 y solo entonces activa la adquisición continua.

Lectura del MPU6050: el número bruto no es el diagnóstico

El acelerómetro entrega aceleración en los ejes X, Y y Z. La gravedad aparece como componente continua, por lo que una placa quieta en el banco todavía muestra aproximadamente 1 g en un eje. Para estudiar vibración, elimina la media de cada ventana antes de calcular el RMS.

Una ventana de 128 muestras a 1 kHz dura unos 128 ms, la ventana que utiliza el firmware del kit. Sirve para seguir una tendencia lenta, pero no convierte el MPU6050 en un analizador de vibración de alta frecuencia: una ventana corta significa una resolución frecuencial gruesa y es el primer parámetro que debes aumentar cuando la RAM lo permita.

code.cpp
cpp
1// Elimina la media de la ventana antes del RMS: la media lleva
2// la gravedad, que es continua y no es vibracion.
3float rmsSinGravedad(const float* muestras, size_t n) {
4 if (n == 0) return 0.0f;
5 float media = 0.0f;
6 for (size_t i = 0; i < n; ++i) media += muestras[i];
7 media /= static_cast<float>(n);
8 float sumaCuadrados = 0.0f;
9 for (size_t i = 0; i < n; ++i) {
10 const float ac = muestras[i] - media;
11 sumaCuadrados += ac * ac;
12 }
13 return sqrtf(sumaCuadrados / static_cast<float>(n));
14}

El RMS mide la energía media de la ventana. No identifica por sí solo la causa. Un desalineamiento, un rodamiento dañado, una base floja y un cambio de carga pueden aumentar el mismo indicador.

Pico y factor de cresta

Guarda también el mayor valor absoluto de la ventana. La relación entre pico y RMS es el factor de cresta:

code.cpp
cpp
1factor de cresta = pico / RMS

Un RMS que crece lentamente puede indicar desgaste o desequilibrio. Un factor de cresta alto con RMS todavía bajo puede revelar impactos breves, holgura o el inicio de daño en un rodamiento. No uses un número universal para separar normal y falla: crea la línea de base de tu máquina, montaje y carga conocida.

Dónde ayuda la FFT

El RMS responde cuánta energía hay en la ventana. La FFT ayuda a responder dónde está esa energía. El resultado puede mostrar un componente cercano a la rotación, armónicos y bandas que merecen investigación.

En una primera versión, no ejecutes la FFT dentro del mismo bucle que debe mantener responsivas la red y las alarmas. Recoge la ventana, indica que está lista, procesa en una etapa controlada y publica el resumen. El dashboard debe recibir indicadores útiles, no miles de muestras sin contexto.

La resolución de la FFT es aproximadamente la tasa de muestreo dividida por el número de puntos. Con 1 kHz y las 128 muestras del kit, cada bin cubre unos 7,8 Hz, demasiado grueso para separar la rotación de un armónico en un motor de 1.750 rpm, que gira a 29 Hz. Para acercarte a 1 Hz por bin necesitas 1.024 puntos a la misma tasa. Ninguna resolución corrige un mal montaje ni elimina el ruido del variador.

Temperatura: trata las fallas como mala calidad

El MAX31855 puede informar circuito abierto, cortocircuito o error de conversión. En cualquiera de esas condiciones, no publiques cero como si fuera una temperatura válida. Cero es un valor posible; el campo de calidad existe precisamente para distinguir valor de falla.

Una convención sencilla para este proyecto:

code.cpp
cpp
1192 buena termopar válido, reloj sincronizado, lectura normal
2 64 incierta reloj todavía sin NTP o valor fuera del rango esperado
3 0 mala termopar abierto, corto o sensor sin respuesta

Si la temperatura sale de un rango plausible, registra la causa y publica calidad incierta o mala según el caso. No ocultes el diagnóstico sustituyendo la lectura por 0, 999 o el último valor sin marcar que está desactualizado.

Las alarmas necesitan histéresis

Un único límite conmuta la alarma en cada lectura cuando el valor está cerca de la frontera. Usa dos límites: uno para activar y otro para desactivar.

Por ejemplo, una política provisional puede activar la alerta térmica por encima de 80 °C y desactivarla solo cuando baje de 75 °C. Son valores de ejemplo; el límite real depende del motor, clase de aislamiento, carga, fabricante y método de medición.

Para vibración, prefiere evaluar la tendencia y el cambio relativo respecto de la línea de base. Un límite absoluto tomado de una tabla genérica puede producir una falsa alarma en una máquina y dejar pasar otra. ISO 10816/ISO 20816 debe orientar la ingeniería de la aplicación, no funcionar como sello automático para un MPU6050 montado en una placa de desarrollo.

Publicación MQTT: el contrato del SCADA

Usa un tópico estable por magnitud y deja los valores en la carga. Un ejemplo de jerarquía:

code.cpp
cpp
1planta1/linea2/motor03/telemetria
2planta1/linea2/motor03/estado
3planta1/linea2/motor03/alarmas

Retén el último estado de telemetría y el estado del gateway, pero no retengas comandos ni alarmas momentáneas. Un comando retenido puede ejecutarse otra vez cuando el SCADA se reconecte. El estado debe incluir uptime, RSSI, versión de firmware y motivo del último reinicio.

El Last Will de MQTT debe publicar offline si el gateway pierde la conexión sin despedirse. Al conectar, publica online con retención. Así el SCADA diferencia un motor estable de un gateway muerto.

Código de adquisición y publicación

El fragmento siguiente es una base de integración. Muestra el orden de los cuidados, no un certificado de desempeño industrial. El resto del firmware debe ocuparse de Wi-Fi, NTP, reconexión MQTT sin bucle bloqueante, watchdog y almacenamiento de configuración.

code.cpp
cpp
1#include <WiFi.h>
2#include <PubSubClient.h>
3#include <Adafruit_MPU6050.h>
4#include <Adafruit_MAX31855.h>
5#include <ArduinoJson.h>
6#include <time.h>
7Adafruit_MPU6050 mpu;
8Adafruit_MAX31855 termopar(18, 5, 19);
9WiFiClient wifiClient;
10PubSubClient mqtt(wifiClient);
11constexpr size_t VENTANA = 128;
12constexpr uint32_t INTERVALO_MUESTRA_US = 1000;
13float magnitud[VENTANA];
14// La cadencia sale de un plazo acumulado, no de un delay despues de leer.
15void recogerVentana() {
16 uint32_t siguiente = micros();
17 for (size_t i = 0; i < VENTANA; ++i) {
18 while ((int32_t)(micros() - siguiente) < 0) yield();
19 siguiente += INTERVALO_MUESTRA_US;
20 sensors_event_t aceleracion, giro, temperatura;
21 mpu.getEvent(&aceleracion, &giro, &temperatura);
22 const float ax = aceleracion.acceleration.x / 9.80665f;
23 const float ay = aceleracion.acceleration.y / 9.80665f;
24 const float az = aceleracion.acceleration.z / 9.80665f;
25 magnitud[i] = sqrtf(ax * ax + ay * ay + az * az);
26 }
27}
28bool relojSincronizado() {
29 return time(nullptr) > 1700000000;
30}
31void publicarResumen(float rms, float pico, float temperaturaC, int calidad) {
32 JsonDocument doc;
33 doc["ts"] = relojSincronizado() ? (uint32_t)time(nullptr) : 0;
34 doc["temperature_c"] = temperaturaC;
35 doc["vibration_rms_g"] = rms;
36 doc["vibration_peak_g"] = pico;
37 doc["crest_factor"] = rms > 0.001f ? pico / rms : 0.0f;
38 doc["quality"] = calidad;
39 doc["sample_count"] = VENTANA;
40 char payload[384];
41 serializeJson(doc, payload, sizeof(payload));
42 mqtt.publish("planta1/linea2/motor03/telemetria", payload, true);
43}

El fragmento reduce cada vuelta a un único número, la magnitud del vector de aceleración, y calcula el RMS sobre ella, igual que el firmware del kit para que los valores del artículo y del paquete sean comparables. La magnitud es práctica para tendencias, pero comprime las tres direcciones en un escalar y pierde la información de eje; para diagnosticar, guarda el RMS de cada eje por separado. Para análisis espectral, aumenta la ventana según la RAM, aplica una ventana matemática antes de la FFT y valida la tasa real con una señal conocida. No uses un delay() largo mientras intentas mantener vivo el heartbeat, MQTT y watchdog.

Orden de validación en el banco

Paso 1: confirmar alimentación y buses

Con el motor apagado y el conjunto fuera del área de riesgo, ejecuta un escáner I2C. El MPU6050 debe aparecer en 0x68 o 0x69. Después lee el MAX31855 con el termopar a temperatura ambiente y confirma que no hay bandera de circuito abierto.

Paso 2: validar la gravedad

Con el sensor quieto, gira la placa lentamente en cada eje. La aceleración resultante debe permanecer cerca de 1 g, descontando tolerancia y ruido. Si el valor cambia mucho estando quieto, revisa alimentación, montaje y configuración del rango del acelerómetro.

Paso 3: crear la línea de base

Registra algunos minutos con el motor sin carga y después en una condición de carga conocida. Guarda RMS, pico, factor de cresta, temperatura, velocidad y hora. Una línea de base sin contexto de carga no es una línea de base: es solo un número.

Paso 4: comparar orientación y posición

Haz una segunda medición en el mismo motor, en el mismo punto y con la misma orientación. Si la repetición varía más que la tendencia que quieres detectar, el problema sigue siendo mecánico o de adquisición, no de MQTT.

Paso 5: probar una falla simulada con seguridad

No aflojes tornillos, retires protecciones ni introduzcas una falla en una máquina energizada. Para probar el pipeline, publica valores de prueba en un tópico separado o utiliza un generador de carga controlado por ingeniería. La alarma debe aparecer, permanecer mientras exista la condición y desaparecer solo después de la histéresis.

Paso 6: probar una caída de red

Detén el broker durante algunos minutos mientras el sensor lee. El firmware debe continuar recogiendo datos o indicar explícitamente que no puede conservar la ventana, sin bloquear todo el bucle. Cuando vuelva la red, publica la marca de tiempo de la lectura y no la hora de reconexión.

Paso 7: probar reinicio y calidad

Apaga el gateway deliberadamente. El SCADA debe marcar el estado offline por Last Will o por ausencia de heartbeat. Desconecta el termopar en el banco y confirma que la temperatura no se convierte en cero con calidad buena.

Errores que parecen problemas del sensor

El RMS sube cuando alguien toca la caja. El montaje está midiendo la propia caja o hay un cable flojo. Refuerza el montaje y repite la línea de base.

La temperatura queda en 0 °C después de una falla. El firmware está ocultando el error del termopar. Separa valor y calidad y trata la bandera del MAX31855.

El gráfico cambia cuando el motor cambia de carga. Puede ser un comportamiento normal del proceso. Publica carga, velocidad o estado operativo junto con la telemetría.

La alarma oscila cerca del límite. Falta histéresis, tiempo mínimo de permanencia o una ventana de evaluación.

El SCADA muestra todo a la misma hora. La marca de tiempo se está creando en el broker o consumidor. Marca la lectura en el ESP32 después de sincronizar el reloj.

La FFT muestra picos diferentes en cada lectura. La ventana es demasiado corta, el sensor está flojo, la tasa no es estable o hay aliasing. Valida la adquisición antes de interpretar el espectro.

El gateway se reinicia al publicar. Comprueba alimentación, heap, tamaño del JSON y costo de TLS. Registra el motivo de reinicio y observa la memoria libre antes y después de la conexión.

El proyecto dice cumplir ISO solo porque calculó RMS. RMS es un indicador; la conformidad depende del sensor, montaje, banda, calibración, procedimiento y evaluación de la máquina.

El resultado esperado es una tendencia suficientemente confiable para orientar una inspección: temperatura, vibración, calidad y contexto en el mismo histórico. La decisión de detener o liberar un motor sigue siendo de la ingeniería responsable de la máquina.

Ver más tutoriales técnicosIIoT ESP32 Brasil — Documentación práctica