O monitoramento de temperatura de câmara fria protege alimentos, ingredientes, medicamentos e amostras que podem ser perdidos em poucas horas quando um freezer ou uma câmara fria falha. Este caso de uso mostra como instalar sensores MQTT em freezers e câmaras frias, distinguir excursões reais de temperatura de aberturas de porta inofensivas, detectar sensores que ficam offline e manter um log de excursões que você pode mostrar a um auditor.
O que pode dar errado em uma câmara fria
A maioria das perdas em câmaras frias não vem de quebras dramáticas. Vem de eventos comuns que ninguém percebe a tempo:
- Uma porta deixada entreaberta depois de uma entrega noturna.
- Um compressor que desarma em uma tarde quente e não volta a partir.
- Um evaporador que congela, fazendo a câmara esquentar lentamente ao longo de horas.
- Uma queda de energia durante o fim de semana.
- Um ciclo de degelo que dura demais depois de uma mudança no controlador.
Um registro manual de temperatura, preenchido duas vezes por turno, não pega nenhum desses eventos entre as leituras. O monitoramento contínuo com alertas fecha essa lacuna. Os mesmos princípios se aplicam ao transporte refrigerado, tratado no artigo de monitoramento da cadeia do frio; este aqui se concentra em freezers e câmaras frias fixos em uma planta, armazém, frigorífico ou cozinha.
A configuração
| Componente | Função | Exemplo de escolha |
|---|---|---|
| Sonda de temperatura | Mede a temperatura do ar ou do produto | DS18B20 à prova d'água em cabo chato passando pela vedação da porta |
| Contato de porta | Explica elevações curtas de temperatura | Sensor reed no batente da porta |
| Nó sensor | Lê sonda e porta, publica | ESP32 montado fora do freezer, alimentado pela rede elétrica |
| Broker MQTT | Recebe leituras e alertas | Broker MQTT gerenciado da ConnectMQ |
| Lógica de alerta | Detecção de excursões e de sensores offline | Regras de limite do portal mais um serviço em Python |
| Log de excursões | Evidência para auditorias e reclamações | Banco de dados gravado pelo serviço de alertas |
Mantenha o ESP32 fora do espaço refrigerado. Eletrônicos e baterias sofrem em temperaturas de freezer, e sinais Wi-Fi não atravessam as paredes metálicas de uma câmara fria. Só o cabo da sonda vai para dentro.
Onde colocar a sonda
A temperatura do ar perto do evaporador muda rápido e exagera cada abertura de porta. A temperatura do produto muda devagar e reflete o que realmente importa. Um meio-termo comum é colocar a sonda na parte mais quente da câmara, longe da saída do evaporador, e opcionalmente dentro de um pequeno frasco de glicol ou de um simulador de produto que a amortece, para que as leituras acompanhem a temperatura do produto e não as rajadas de ar. Mapeie a câmara uma vez com algumas sondas para encontrar o ponto quente antes de escolher a posição definitiva.
Firmware do sensor
O sketch abaixo publica a temperatura e o estado da porta a cada 30 segundos, e imediatamente quando a porta muda. Ele define uma mensagem Last Will, para que o broker anuncie o sensor como offline se ele desaparecer. Instale PubSubClient, OneWire e DallasTemperature. Para detalhes de ligação do sensor, veja o tutorial ESP32 DS18B20 MQTT.
#include <WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* CLIENT_ID = "freezer2-6c0f3b";
const char* BASE = "connectmq/demo/6c0f3b/warehouse/freezer2";
const int PROBE_PIN = 4;
const int DOOR_PIN = 27; // sensor reed para GND, porta fechada = LOW
const uint32_t PERIOD_MS = 30000;
OneWire oneWire(PROBE_PIN);
DallasTemperature probe(&oneWire);
WiFiClient net;
PubSubClient mqtt(net);
char topicTelemetry[96], topicStatus[96];
int lastDoor = -1;
uint32_t lastPub = 0;
void connectAll() {
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(250);
}
while (!mqtt.connected()) {
if (mqtt.connect(CLIENT_ID, topicStatus, 1, true, "offline")) {
mqtt.publish(topicStatus, "online", true);
} else {
delay(3000);
}
}
}
void publishReading(bool doorOpen) {
probe.requestTemperatures();
float t = probe.getTempCByIndex(0);
char payload[128];
if (t == DEVICE_DISCONNECTED_C) {
snprintf(payload, sizeof(payload), "{\"temp_c\":null,\"door_open\":%s,\"fault\":\"probe\"}",
doorOpen ? "true" : "false");
} else {
snprintf(payload, sizeof(payload), "{\"temp_c\":%.2f,\"door_open\":%s,\"rssi\":%d}",
t, doorOpen ? "true" : "false", WiFi.RSSI());
}
mqtt.publish(topicTelemetry, payload, true);
}
void setup() {
pinMode(DOOR_PIN, INPUT_PULLUP);
snprintf(topicTelemetry, sizeof(topicTelemetry), "%s/telemetry", BASE);
snprintf(topicStatus, sizeof(topicStatus), "%s/status", BASE);
probe.begin();
WiFi.mode(WIFI_STA);
mqtt.setServer("broker.connectmq.com", 1883);
connectAll();
}
void loop() {
connectAll();
mqtt.loop();
int door = digitalRead(DOOR_PIN) == HIGH; // HIGH = ímã afastado = aberta
if (door != lastDoor || millis() - lastPub >= PERIOD_MS) {
publishReading(door);
lastDoor = door;
lastPub = millis();
}
delay(200);
}
O Last Will é a rede de segurança que um registro manual nunca teve: se o nó perde energia ou Wi-Fi, o broker publica offline no topic de status depois do timeout de keepalive. O guia Last Will MQTT no ESP32 explica o mecanismo.
Lógica de excursão sem alarmes incômodos
A abordagem ingênua, alarmar sempre que a temperatura passa do limite, fracassa em um dia. Cada entrega abre a porta, a temperatura do ar dispara e a equipe aprende a ignorar o alarme. Um bom monitoramento de temperatura de câmara fria usa algumas regras em conjunto:
- Limite mais atraso. Abra uma excursão apenas se a temperatura ficar acima do limite por um tempo definido, por exemplo 15 minutos para um freezer.
- Atraso sensível à porta. Com a porta aberta, permita um período de tolerância maior, mas gere um alerta separado de porta aberta se ela ficar aberta tempo demais.
- Limite crítico. Uma temperatura muito mais alta dispara imediatamente, independentemente do atraso.
- Sensores offline e falhas de sonda. Um sensor silencioso ou uma sonda desconectada é um alerta por si só.
- Registro de excursão. Cada excursão recebe hora de início, hora de fim, temperatura de pico e duração.
Os limites em si vêm dos seus produtos e do seu plano de segurança de alimentos ou de qualidade. Use esses documentos em vez de números genéricos.
Serviço de excursões em Python
import json
import sqlite3
import time
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/6c0f3b/warehouse"
LIMIT_C = -15.0 # a partir dos requisitos do seu produto
HARD_LIMIT_C = -5.0
DELAY_S = 15 * 60
DOOR_MAX_S = 5 * 60
STALE_S = 3 * 60
db = sqlite3.connect("excursions.db", check_same_thread=False)
db.execute("""CREATE TABLE IF NOT EXISTS excursions (
unit TEXT, start_ts INTEGER, end_ts INTEGER, peak_c REAL, reason TEXT)""")
units = {}
def alert(client, unit, kind, detail):
msg = {"ts": int(time.time()), "unit": unit, "kind": kind, **detail}
client.publish(f"{PREFIX}/{unit}/alert", json.dumps(msg), qos=1, retain=True)
print("ALERT", msg)
def on_connect(client, userdata, flags, reason_code, properties):
client.subscribe(f"{PREFIX}/+/telemetry", qos=1)
client.subscribe(f"{PREFIX}/+/status", qos=1)
def on_message(client, userdata, msg):
unit = msg.topic.split("/")[4]
now = time.time()
u = units.setdefault(unit, {"above_since": None, "door_since": None,
"excursion": None, "seen": now})
if msg.topic.endswith("/status"):
if msg.payload == b"offline":
alert(client, unit, "offline", {})
return
d = json.loads(msg.payload)
u["seen"] = now
if d.get("temp_c") is None:
alert(client, unit, "probe_fault", {})
return
t = d["temp_c"]
u["door_since"] = (u["door_since"] or now) if d["door_open"] else None
if u["door_since"] and now - u["door_since"] > DOOR_MAX_S:
alert(client, unit, "door_open_too_long", {"seconds": int(now - u["door_since"])})
u["door_since"] = now
if t > LIMIT_C:
u["above_since"] = u["above_since"] or now
delay = DELAY_S * (2 if d["door_open"] else 1)
exc = u["excursion"]
if exc:
exc["peak"] = max(exc["peak"], t)
elif t > HARD_LIMIT_C or now - u["above_since"] > delay:
u["excursion"] = {"start": u["above_since"], "peak": t}
alert(client, unit, "excursion_start", {"temp_c": t, "limit_c": LIMIT_C})
else:
exc = u["excursion"]
if exc:
db.execute("INSERT INTO excursions VALUES (?,?,?,?,?)",
(unit, int(exc["start"]), int(now), exc["peak"], "above_limit"))
db.commit()
alert(client, unit, "excursion_end",
{"duration_min": round((now - exc["start"]) / 60, 1), "peak_c": exc["peak"]})
u["above_since"] = None
u["excursion"] = None
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="cold-alerts-6c0f3b")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
while True:
time.sleep(30)
for unit, u in units.items():
if time.time() - u["seen"] > STALE_S:
alert(client, unit, "stale", {"seconds_silent": int(time.time() - u["seen"])})
u["seen"] = time.time()
A hora de início da excursão é registrada como o momento em que a temperatura cruzou o limite pela primeira vez, e não quando o atraso expirou, para que o log mostre a duração real. Nos casos mais simples, você também pode criar regras de alerta por limite no campo temp_c diretamente no portal da ConnectMQ e revisar cada cruzamento no log de alertas, deixando o serviço em Python para a lógica de atraso e de porta.
Fazendo os alertas chegarem às pessoas
O serviço publica os alertas no MQTT; ainda é preciso que algo chegue a um celular às 3 da manhã. Como a ConnectMQ não envia e-mails nem SMS por conta própria, o padrão honesto é uma ferramenta externa que assina os topics de alerta: um fluxo do Node-RED com um nó de e-mail ou de mensagens, notificações do Home Assistant para sites menores ou algumas linhas extras no serviço em Python que chamam o seu provedor de notificações. Defina um caminho de escalonamento: primeiro o líder de turno, depois o plantão da manutenção e, por fim, o gerente do site se ninguém reconhecer o alerta.
Lidando com ciclos de degelo
O degelo automático é a outra fonte frequente de alarmes falsos. Durante o degelo, o evaporador esquenta e a temperatura do ar perto dele sobe por pouco tempo, o que é normal. Três medidas evitam que ele dispare excursões. Primeiro, mantenha a sonda longe do evaporador, como descrito acima. Segundo, garanta que o atraso de excursão seja maior do que um degelo normal naquela unidade, algo que você vê claramente em um dia de dados registrados. Terceiro, se o controlador de refrigeração expõe um sinal de degelo, publique-o junto com a temperatura e estenda o atraso enquanto o degelo estiver ativo, exatamente como o serviço faz para as aberturas de porta. Um degelo que dura muito mais do que o normal merece um alerta por si só, porque muitas vezes indica uma resistência, um sensor ou uma configuração de controlador com problema.
Checklist de implantação
- Mapeie cada câmara com várias sondas durante um dia para encontrar o ponto quente.
- Instale um nó por unidade, com os eletrônicos do lado de fora e a sonda no ponto quente.
- Defina limites e atrasos a partir dos requisitos do produto e do plano de qualidade.
- Teste os alarmes: abra a porta, desligue um nó, desconecte uma sonda e confirme que cada alerta chega.
- Calibre as sondas contra um termômetro de referência e registre a verificação.
- Revise o log de excursões semanalmente e atue nos reincidentes, como uma porta que vive sendo deixada aberta.
- Migre para um broker privado com credenciais do portal e TLS na porta 8883 antes de entrar em operação.
Da demonstração à produção
O tutorial roda no servidor MQTT público, onde todos os topics ficam visíveis para qualquer pessoa, o que serve para testes, mas não para dados operacionais. Para produção, um broker MQTT na nuvem dá a cada nó de freezer uma conexão criptografada e autenticada e permite que o serviço de alertas, os dashboards e a equipe de qualidade assinem de qualquer lugar. Os registros de temperatura também complementam o controle de qualidade com IoT na manufatura e a rastreabilidade na manufatura por lote, já que as janelas de excursão podem ser vinculadas aos lotes armazenados naquele momento. O guia de manufatura inteligente coloca tudo isso em uma arquitetura para a planta inteira.
Monitore sua câmara fria na ConnectMQ
A ConnectMQ oferece um broker MQTT gerenciado privado com TLS, suporte a Last Will, retained messages, dashboard ao vivo e regras de alerta por limite no portal. Crie um broker no plano Serverless gratuito em app.connectmq.com, sem cartão de crédito, e conecte hoje seu primeiro freezer.
Perguntas frequentes
Com que frequência a temperatura da câmara fria deve ser registrada?
A cada 30 segundos a 5 minutos é o típico para monitoramento contínuo. Relatórios mais frequentes geram alertas mais rápidos, enquanto o atraso de excursão evita alarmes incômodos.
Como evito alarmes toda vez que a porta é aberta?
Exija que a temperatura fique acima do limite durante um período de atraso antes de alertar, estenda esse atraso enquanto a porta estiver aberta e alerte separadamente se a porta ficar aberta por tempo demais.
O que acontece se um sensor perder energia?
Com uma mensagem Last Will, o broker publica um status offline depois do timeout de keepalive, e o serviço de alertas trata isso como um alarme.
A sonda deve medir a temperatura do ar ou do produto?
A temperatura do produto é a que mais importa. Colocar a sonda em um amortecedor, como um frasco de glicol, no ponto mais quente gera leituras que acompanham a temperatura do produto e ignoram picos breves do ar.



