iiOTESP32 Brasil
Modo de contingência: páginas públicas e downloads seguem disponíveis; login, comunidade e dados do servidor podem ficar indisponíveis.
Voltar para catálogo de tutoriais
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
AvançadoIIoTLeitura: 18 min

Monitoramento de Temperatura e Vibração de Motores com ESP32

Nó de manutenção preditiva com MPU6050 e termopar Tipo K: RMS de vibração, telemetria por MQTT e uma tendência mecânica virando alarme útil no SCADA.

Tecnologias:#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 ligar: este não é um instrumento de segurança

Um ESP32 com MPU6050 e MAX31855 é um excelente nó de aquisição e tendência para laboratório, protótipo e manutenção preditiva. Ele ajuda a descobrir que um motor está aquecendo ou vibrando mais do que a própria linha de base.

Ele não substitui relé térmico, proteção contra sobrecorrente, sensor industrial certificado, monitor de vibração dedicado ou qualquer intertravamento de segurança. Não instale, ajuste ou abra uma caixa próxima a um motor energizado sem qualificação elétrica e sem o procedimento de bloqueio e etiquetagem da planta.

O objetivo deste tutorial é específico: medir de forma repetível, preservar o contexto da leitura e publicar uma tendência que alguém consiga interpretar antes da falha.

O que o nó mede

O MPU6050 mede aceleração em três eixos. Em uma carcaça de motor, a vibração pode aparecer como aumento do valor RMS, mudança na distribuição de energia ou surgimento de componentes periódicos no espectro. O sensor é barato e útil para experimentar, mas sua montagem mecânica, faixa e banda não equivalem às de um acelerômetro industrial.

O MAX31855 converte o sinal de um termopar Tipo K e informa a temperatura da junta quente e possíveis falhas do termopar. Ele usa SPI e não deve ser confundido com um sensor digital de temperatura ambiente: o termopar precisa estar montado em um ponto definido da carcaça, com contato mecânico e isolamento elétrico adequados.

O ESP32 coleta os dois sinais, calcula indicadores simples e envia uma carga MQTT parecida com 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}

O instante é o da leitura, não o momento em que o broker recebeu a mensagem. A qualidade informa se o valor é confiável. Sem esses dois campos, o gráfico pode parecer preciso e ainda assim induzir uma decisão errada.

A montagem importa mais que o dashboard

Cole o MPU6050 com fita dupla-face e o sensor passa a medir a fita, a caixa e qualquer folga. Para uma comparação de tendência, use uma fixação rígida e repetível, preferencialmente um parafuso ou base metálica projetada para o ponto de medição.

Marque a posição e a orientação dos eixos. Se cada visita de manutenção trocar o lado da carcaça, o valor RMS deixa de ser comparável. Não misture medições feitas no mancal, na tampa do motor e na base como se fossem o mesmo ponto.

O termopar também precisa de uma posição definida. A temperatura da carcaça depende de carga, ventilação, temperatura ambiente e tempo de operação. Registre pelo menos o estado do motor e o tempo desde a partida quando quiser comparar dias diferentes.

Ligações elétricas

O MPU6050 usa I2C. Este exemplo usa SDA no GPIO 21 e SCL no GPIO 22. O endereço mais comum é 0x68; se AD0 estiver em nível alto, ele passa a ser 0x69.

O MAX31855 usa SPI: GPIO 18 para SCK, GPIO 19 para MISO e GPIO 5 para CS. O pino MOSI não é necessário para a leitura deste conversor. Confira a pinagem do seu módulo: placas de fabricantes diferentes podem mudar a serigrafia e o regulador de alimentação.

Todos os módulos precisam compartilhar o GND do ESP32. O barramento de baixa tensão deve ficar fisicamente separado de condutores de potência e de cabos do inversor de frequência. Ruído elétrico não é resolvido apenas trocando a biblioteca.

Fixe o ambiente antes de medir

Crie o projeto no PlatformIO e fixe as bibliotecas. O objetivo é evitar que duas compilações instalem APIs diferentes sem que ninguém perceba.

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

Comece com o ESP32 na bancada, sem o motor e sem MQTT. Primeiro confirme que o MPU6050 responde no I2C, depois confira a leitura do MAX31855 e só então ligue a aquisição contínua.

Leitura do MPU6050: o número bruto não é o diagnóstico

O acelerômetro entrega aceleração nos eixos X, Y e Z. A gravidade aparece como componente contínua, então uma placa parada sobre a bancada ainda mostra aproximadamente 1 g em um eixo. Para estudar vibração, remova a média de cada janela antes de calcular RMS.

Uma janela de 128 amostras a 1 kHz dura cerca de 128 ms, que é a janela usada no firmware do kit. Isso serve para acompanhar tendência lenta, mas não transforma o MPU6050 em analisador de vibração de alta frequência: janela curta significa resolução grosseira em frequência, e é o primeiro parâmetro a aumentar quando a RAM permitir.

code.cpp
cpp
1// Remove a media da janela antes do RMS: a media carrega a
2// gravidade, que e componente continua e nao e vibracao.
3float rmsSemGravidade(const float* amostras, 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 += amostras[i];
7 media /= static_cast<float>(n);
8 float somaQuadrados = 0.0f;
9 for (size_t i = 0; i < n; ++i) {
10 const float ac = amostras[i] - media;
11 somaQuadrados += ac * ac;
12 }
13 return sqrtf(somaQuadrados / static_cast<float>(n));
14}

O valor RMS é uma medida de energia média da janela. Ele não diz sozinho qual é a causa. Um desalinhamento, um rolamento danificado, uma base frouxa e uma mudança de carga podem aumentar o mesmo indicador.

Pico e fator de crista

Guarde também o maior valor absoluto da janela. A relação entre pico e RMS é o fator de crista:

code.cpp
cpp
1fator de crista = pico / RMS

Um RMS crescendo lentamente pode indicar desgaste ou desequilíbrio. Um fator de crista alto com RMS ainda baixo pode revelar impactos curtos, folga ou início de dano em rolamento. Não use um número universal para separar normal e falha: faça a linha de base da sua máquina, na sua fixação, com carga conhecida.

Onde a FFT ajuda

O RMS responde quanto de energia existe na janela. A FFT ajuda a responder onde essa energia está. O resultado pode mostrar uma componente próxima da rotação, harmônicas e bandas que merecem investigação.

Para uma primeira versão, não faça a FFT dentro do mesmo laço que precisa manter a rede e os alarmes responsivos. Colete a janela, sinalize que ela está pronta, processe em uma etapa controlada e publique o resumo. O dashboard deve receber indicadores úteis, não milhares de amostras sem contexto.

A resolução da FFT é aproximadamente taxa de amostragem dividida pelo número de pontos. Com 1 kHz e as 128 amostras do kit, cada bin cobre cerca de 7,8 Hz — grosseiro demais para separar rotação de harmônica em um motor de 1750 rpm, que gira a 29 Hz. Para chegar perto de 1 Hz por bin você precisa de 1024 pontos na mesma taxa. E nenhuma resolução corrige uma montagem ruim nem remove ruído do inversor.

Temperatura: trate falhas como qualidade ruim

O MAX31855 pode informar circuito aberto, curto ou erro de conversão. Em qualquer uma dessas condições, não publique zero como se fosse temperatura válida. Zero é um valor possível; o campo de qualidade existe justamente para distinguir valor de falha.

Uma convenção simples para este projeto:

code.cpp
cpp
1192 boa termopar válido, relógio sincronizado, leitura normal
2 64 incerta relógio ainda sem NTP ou valor fora da faixa esperada
3 0 ruim termopar aberto, curto ou sensor sem resposta

Se a temperatura sair de uma faixa plausível, registre a causa e publique qualidade incerta ou ruim conforme o caso. Não esconda o diagnóstico substituindo a leitura por 0, 999 ou pelo último valor sem marcar que ele está velho.

Alarmes devem ter histerese

Um limite simples comuta o alarme a cada leitura quando o valor fica perto da fronteira. Use dois limites: um para ligar e outro para desligar.

Por exemplo, uma política provisória pode ligar o alerta térmico acima de 80 °C e só desligá-lo quando cair abaixo de 75 °C. Os valores são apenas exemplo; o limite real depende do motor, da classe de isolamento, da carga, do fabricante e do método de medição.

Para vibração, prefira avaliar a tendência e a mudança relativa sobre a linha de base. Um limite absoluto tirado de uma tabela genérica pode gerar alarme falso em uma máquina e deixar outra passar. A ISO 10816/ISO 20816 deve orientar a engenharia da aplicação, não ser usada como selo automático para um MPU6050 montado em uma placa de desenvolvimento.

Publicação MQTT: o contrato do SCADA

Use um tópico estável por grandeza e deixe os valores na carga. Um exemplo de hierarquia:

code.cpp
cpp
1usina1/linha2/motor03/telemetria
2usina1/linha2/motor03/status
3usina1/linha2/motor03/alarmes

Retenha o último estado de telemetria e o status do gateway, mas não retenha comando nem alarme momentâneo. Um comando retido pode ser reexecutado quando o SCADA reconectar. O status deve conter uptime, RSSI, versão do firmware e motivo do último reset.

O Last Will do MQTT deve publicar offline se o gateway perder a conexão sem despedida. Ao conectar, publique online com retenção. Assim o SCADA diferencia motor estável de gateway morto.

Código de aquisição e publicação

O trecho abaixo é uma base de integração. Ele mostra a ordem dos cuidados, não um certificado de desempenho industrial. O restante do firmware precisa cuidar de Wi-Fi, NTP, reconexão MQTT sem laço bloqueante, watchdog e armazenamento de configuração.

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>
7// --- sensores e transporte --------------------------------------------
8Adafruit_MPU6050 mpu;
9Adafruit_MAX31855 termopar(18, 5, 19);
10WiFiClient wifiClient;
11PubSubClient mqtt(wifiClient);
12// --- janela de aquisicao ----------------------------------------------
13constexpr size_t JANELA = 128;
14constexpr uint32_t INTERVALO_AMOSTRA_US = 1000;
15float magnitude[JANELA];
16// A cadencia sai de um prazo acumulado, nao de um delay depois da leitura.
17// Com delay, o tempo da transacao I2C soma a cada volta e a taxa real cai
18// abaixo de 1 kHz, invalidando qualquer conta de frequencia feita depois.
19void coletarJanela() {
20 uint32_t proxima = micros();
21 for (size_t i = 0; i < JANELA; ++i) {
22 while ((int32_t)(micros() - proxima) < 0) yield();
23 proxima += INTERVALO_AMOSTRA_US;
24 sensors_event_t aceleracao, giro, temperatura;
25 mpu.getEvent(&aceleracao, &giro, &temperatura);
26 const float ax = aceleracao.acceleration.x / 9.80665f;
27 const float ay = aceleracao.acceleration.y / 9.80665f;
28 const float az = aceleracao.acceleration.z / 9.80665f;
29 magnitude[i] = sqrtf(ax * ax + ay * ay + az * az);
30 }
31}
32bool relogioSincronizado() {
33 return time(nullptr) > 1700000000;
34}
35void publicarResumo(float rms, float pico, float temperaturaC, int qualidade) {
36 JsonDocument doc;
37 doc["ts"] = relogioSincronizado() ? (uint32_t)time(nullptr) : 0;
38 doc["temperature_c"] = temperaturaC;
39 doc["vibration_rms_g"] = rms;
40 doc["vibration_peak_g"] = pico;
41 doc["crest_factor"] = rms > 0.001f ? pico / rms : 0.0f;
42 doc["quality"] = qualidade;
43 doc["sample_count"] = JANELA;
44 char payload[384];
45 serializeJson(doc, payload, sizeof(payload));
46 mqtt.publish("usina1/linha2/motor03/telemetria", payload, true);
47}

O trecho reduz cada volta a um número só, a magnitude do vetor de aceleração, e é sobre ela que o RMS é calculado — o mesmo que o firmware do kit faz, para que os valores do artigo e do pacote sejam comparáveis. A magnitude é prática para tendência, mas reduz as três direções a um escalar e perde a informação de eixo; quando quiser diagnosticar em vez de só acompanhar, guarde o RMS de cada eixo separadamente. Para análise espectral, aumente a janela conforme a RAM disponível, aplique uma janela matemática antes da FFT e valide a taxa de amostragem real com um sinal conhecido. Não use delay() longo enquanto pretende manter heartbeat, MQTT e watchdog funcionando.

Ordem de validação na bancada

Passo 1: confirmar alimentação e barramentos

Com o motor desligado e o conjunto fora da área de risco, rode um scanner I2C. O MPU6050 precisa aparecer em 0x68 ou 0x69. Depois leia o MAX31855 com o termopar em temperatura ambiente e confirme que não há flag de circuito aberto.

Passo 2: validar a gravidade

Com o sensor parado, gire a placa lentamente em cada eixo. A aceleração resultante deve permanecer próxima de 1 g, descontando tolerância e ruído. Se o valor variar muito parado, revise alimentação, fixação e configuração da faixa do acelerômetro.

Passo 3: criar a linha de base

Registre alguns minutos com o motor em vazio, depois em uma condição de carga conhecida. Guarde RMS, pico, fator de crista, temperatura, rotação e horário. Uma linha de base sem o contexto de carga não é linha de base; é apenas um número.

Passo 4: comparar orientação e posição

Faça uma segunda medição no mesmo motor, no mesmo ponto e com a mesma orientação. Se a repetição variar mais que a tendência que você quer detectar, o problema ainda é mecânico ou de aquisição, não de MQTT.

Passo 5: testar uma falha simulada com segurança

Não afrouxe parafuso, remova proteção ou introduza defeito em uma máquina energizada. Para testar o pipeline, publique valores de teste em um tópico separado ou use um gerador de carga controlado pela engenharia. O alarme deve aparecer, permanecer enquanto a condição existir e desaparecer apenas depois da histerese.

Passo 6: testar a rede caindo

Derrube o broker por alguns minutos com o sensor lendo. O firmware deve continuar coletando ou sinalizar explicitamente que não consegue preservar a janela, sem travar o laço inteiro. Quando a rede voltar, publique o timestamp da leitura e não o horário da reconexão.

Passo 7: testar reinício e qualidade

Desligue o gateway de propósito. O SCADA precisa marcar o status como offline pelo Last Will ou pela ausência do heartbeat. Desconecte o termopar em bancada e confirme que a temperatura não vira zero com qualidade boa.

Erros que parecem problema de sensor

O RMS sobe quando alguém toca no gabinete. A fixação está medindo a própria caixa ou há cabo solto. Reforce a montagem e repita a linha de base.

A temperatura fica em 0 °C depois de uma falha. O firmware está escondendo erro de termopar. Separe valor e qualidade e trate a flag do MAX31855.

O gráfico muda quando o motor troca de carga. Isso pode ser comportamento normal do processo. Publique carga, rotação ou estado operacional junto com a telemetria.

O alarme oscila perto do limite. Falta histerese, tempo mínimo de permanência ou uma janela de avaliação.

O SCADA mostra tudo no mesmo horário. O timestamp está sendo criado no broker ou no consumidor. Carimbe a leitura no ESP32 depois de sincronizar o relógio.

A FFT mostra picos que mudam a cada leitura. A janela é curta demais, o sensor está frouxo, a taxa de amostragem não é estável ou há aliasing. Valide a aquisição antes de interpretar o espectro.

O gateway reinicia quando publica. Verifique fonte, heap, tamanho do JSON e o custo do TLS. Logue o motivo de reset e observe a memória livre antes e depois da conexão.

O projeto diz que atende ISO só porque calculou RMS. RMS é um indicador; conformidade depende de sensor, montagem, banda, calibração, procedimento e avaliação da máquina.

O resultado esperado deste projeto é uma tendência confiável o suficiente para orientar uma inspeção: temperatura, vibração, qualidade e contexto no mesmo histórico. A decisão de parar ou liberar um motor continua sendo da engenharia responsável pela máquina.

Ver mais tutoriais técnicosIIoT ESP32 Brasil — Documentação Prática