Garanta Aquecimento Seguro de Água: Monitor de Tensão do Termopar para Chama Piloto
Componentes e Materiais
| Adafruit Raspberry Pi Zero WH | × | 1 |
| Arduino Nano R3 | × | 1 |
Sobre o Projeto
Sistema de Monitoramento da Chama Piloto do Aquecedor a Gás
Aquecedores a gás tradicionais mantêm uma chama piloto acesa 24/7. Ela aquece um termopar que gera pequena tensão (até 30 mV). Essa tensão mantém a válvula de gás aberta no termostato. Se a chama apaga, a tensão cai a zero e a válvula fecha automaticamente – sem risco de vazamento.
No meu aquecedor, a chama apaga ocasionalmente (~3 vezes/ano). Não vale trocar o aparelho caro. Trocar o termopar não resolveu. Minha solução: monitorar a tensão do termopar. Se cair a zero, enviar SMS e e-mail para eu religar a chama.
Visão Geral
Um Raspberry Pi Zero WH envia e-mails/SMS quando a chama apaga. Como o Pi não mede tensão, uso um Arduino Nano para ler a tensão do termopar.
Arduinos têm ADC (conversor analógico-digital) que lê tensão e converte em 0–1023. O Arduino lê a tensão do termopar e envia ao Raspberry Pi. O Pi interpreta: se valor muito baixo, assume chama apagada e notifica.
Passo 1: Preparar o Raspberry Pi
Coloque o Pi na rede (veja meu outro projeto para instruções). Crie um programa Python que receba leituras do Arduino em loop e envie notificações quando tensão baixa. Código-fonte anexo.
Passo 2: Preparar o Arduino
Usei Nanos baratos (chineses); levou tentativa/erro para funcionar no Windows 10.
Carregue sketch que mede tensão no pino de entrada a cada 30 s. O Arduino mede 0–Vref. Pode-se escolher 1,1 V ou 5 V como referência. Como termopar gera no máx. 30 mV, use referência interna 1,1 V para maior resolução. ADC: 0 = 0 V, 1023 = 1,1 V. Leitura máx. esperada ≈ 28.
Passo 3: Conectar Arduino à Fonte de Tensão

O termopar envia tensão ao termostato via fio coaxial. O externo é positivo.
- Corte o fio ~13 cm antes do termostato.
- Recue a blindagem externa para acessar o fio central. Não destrua o isolamento do fio central – evitar curto com a blindagem.

Conecte de forma que a tensão positiva alimente o termostato e o pino de entrada do Arduino (usei A0). O negativo da fonte vai ao GND do Arduino e ao negativo do termostato. Usei fios 30 cm com jacarés.

Passo 4: Conectar Arduino ao Raspberry Pi
O sketch no Arduino transmite o valor do ADC pelo pino digital 9.
Arduino = 5 V lógica; Raspberry Pi = 3,3 V entrada. Precisa divisor de tensão para reduzir 5 V → ~2,8 V.

Fórmula: Vout = Vin × R2 / (R1 + R2).

Um único resistor não funciona: sem corrente, ambos lados ficam em Vin (5 V). O divisor reduz tensão mesmo sem corrente. Todos GNDs devem ser comuns. Veja diagrama de conexão.
Passo 5: Arduino Transmite Medição
A cada 30 s, o sketch lê ADC e transmite o número ao Pi via sinalização de fio único do pino 9 (Arduino) → pino 16 (Pi).
Passo 6: Raspberry Pi Recebe Medição
Programa Python com loop infinito escuta bordas de subida (rising edge) no pino 16. Ao detectar, assume início de transmissão.
Sistema de Sinalização
Transmite número de dois dígitos (ex: "12"). Cada dígito precedido por pulso positivo no pino 16. Pulsos subsequentes separados por < 20 ms incrementam o dígito. Pausa > 40 ms indica fim do dígito; próxima pausa > 40 ms indica fim do número de dois dígitos.
No Python, o número recebido é retornado pelo método interpretador. Outro código decide se notifica. Depois volta a aguardar próxima borda de subida no pino 16.
Passo 7: Enviar Notificação
Se tensão muito baixa, incrementa contador low_count (evita falsos alarmes). Se atingir 5 (5 leituras × 30 s = 2,5 min), envia notificação e zera contador. Próxima notificação só após 6 horas.
Notificações via smtplib + conta Gmail. Para SMS, usei gateway de operadoras: ex. Verizon 5555555555@vtext.com.
Gmail: Criei conta dedicada. Inicialmente usei "acesso a apps menos seguros", mas depois de meses o Gmail desativa. Melhor: App Password – configuração.
Passo 8: Conectar Tudo

Conecte Arduino ao fio do termopar e ao Pi via divisor de tensão. (Meu divisor superior usa dois resistores somando 550 Ω – o que tinha à mão.) Alimente o Arduino; ele medirá e sinalizará a cada 30 s.
Passo 9: Rodar Programa Python
- Crie script que inicie o programa Python.
- Edite crontab root para rodar no boot:
sudo crontab -e - Adicione linha:
@reboot sh /home/pi/hotwater/run_HotWaterNotifier.sh >> /home/pi/hotwater/logs/HotWaterNotifier.log 2>&1 - Para rodar manualmente: execute script, Ctrl+Z,
bg,disown. - Verificar se roda:
ps aux | grep -i HotWater

Código
Código Arduino
Lê tensão a cada 30 s e envia sinais ao Raspberry Pi.
/****************************************************************************** HotWaterHeater
Mede tensão do termopar do aquecedor. Usa sinalização para enviar leitura ao Raspberry Pi.
****************************************************************************/
double ReferenceVoltage = 1.1;
int OUTPUT_PIN = 9;
int INTRA_DIGIT_WAIT = 20;
int BETWEEN_DIGIT_WAIT = 50;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(OUTPUT_PIN, OUTPUT);
analogReference(INTERNAL);
Serial.begin(9600);
}
void loop() {
int pinInput = analogRead(A0);
double voltage = (pinInput * ReferenceVoltage) / 1023.0;
Serial.print("PinInputA0="); Serial.print(pinInput);
Serial.print(", voltageA0="); Serial.println(voltage);
// leitura 5 = 5,38 mV
sendNumberSignal(pinInput, OUTPUT_PIN, INTRA_DIGIT_WAIT, BETWEEN_DIGIT_WAIT);
delay(30000);
}
void sendNumberSignal(int number, int pin, int intraDigitWait, int betweenDigitWait) {
int tens = number / 10;
int ones = number % 10;
Serial.print("Signaling: "); Serial.println(number);
sendPulse(pin, intraDigitWait);
for (int i = 0; i < tens; i++) sendPulse(pin, intraDigitWait);
delay(betweenDigitWait);
sendPulse(pin, intraDigitWait);
for (int i = 0; i < ones; i++) sendPulse(pin, intraDigitWait);
delay(betweenDigitWait);
}
void sendPulse(int pin, int intraDigitWait) {
digitalWrite(pin, HIGH);
delay(intraDigitWait);
digitalWrite(pin, LOW);
delay(intraDigitWait);
}
Código Python
Recebe sinais do Arduino, interpreta tensão, decide se envia alerta.
###############################################################################
# HotWaterNotifier.py
# Monitora pino de entrada e recebe sinais do Arduino.
# Decodifica sinais em leituras numéricas de tensão.
# Se leitura muito baixa → chama piloto apagado. Após 5 leituras seguidas, envia e-mail/SMS.
# Só envia a cada 6 horas.
# Python 2.7 (pequenas mudanças para Python 3).
###############################################################################
import smtplib, RPi.GPIO as GPIO, os, time, datetime, string, logging, sys
GPIO_Alert = 16
emailWaitHours = 6
lowSensorReading = 1
maxLowVoltageCount = 5
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_Alert, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
lastEmailSentTime = datetime.datetime(2000,1,1,0,0,0,0)
def setup_custom_logger(name):
formatter = logging.Formatter(fmt='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
handler = logging.FileHandler('HotWaterLog.txt', mode='a')
handler.setFormatter(formatter)
screen_handler = logging.StreamHandler(stream=sys.stdout)
screen_handler.setFormatter(formatter)
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
logger.addHandler(screen_handler)
return logger
logger = setup_custom_logger('HotWaterNotifier')
def send_email_alert():
global lastEmailSentTime
nowTime = datetime.datetime.now()
if lastEmailSentTime is None or (nowTime - datetime.timedelta(hours=emailWaitHours)) > lastEmailSentTime:
logger.info('Sending email alert...')
HOST, PORT = "smtp.gmail.com", 587
SUBJECT = "Hot Water Heater Alert"
TO = ["XXXXXXXXXXXXXX@gmail.com", "5555555555@vtext.com"]
FROM = "XXXXXXXXXXXXXX@gmail.com"
PWD = "XXXXXXXXXXXXXX"
text = "Low Voltage Measured on the Hot Water Heater"
BODY = "\r\n".join(["from: %s" % FROM, "to: %s" % ", ".join(TO), "Subject: %s" % SUBJECT, "", text])
try:
s = smtplib.SMTP(HOST, PORT)
s.set_debuglevel(1)
s.ehlo()
s.starttls()
s.login(FROM, PWD)
s.sendmail(FROM, TO, BODY)
s.quit()
except Exception as e:
logger.exception('Exception caught file sending email. Trying again in 6 hours')
lastEmailSentTime = nowTime
else:
logger.info('Not sending email. Last email sent at: ' + lastEmailSentTime.strftime("%Y-%m-%d %H:%M:%S"))
def waitReceiveNumber(GPIO_Alert):
lastSignalTime = datetime.datetime(2000,1,1,0,0,0,0)
isTens = True
isFirstIteration = True
tensValue = 0
onesValue = 0
receivedEdge = None
singleDigitMilliseconds = datetime.timedelta(milliseconds=70)
wholeNumberWaitTime = 200
while True:
if isFirstIteration:
receivedEdge = GPIO.wait_for_edge(GPIO_Alert, GPIO.RISING, timeout=-1)
else:
receivedEdge = GPIO.wait_for_edge(GPIO_Alert, GPIO.RISING, timeout=wholeNumberWaitTime)
signalTime = datetime.datetime.now()
signalInterval = signalTime - lastSignalTime
lastSignalTime = signalTime
logger.info('signalInterval: ' + str(signalInterval.total_seconds() * 1000))
if (signalInterval < singleDigitMilliseconds) or isFirstIteration:
isFirstIteration = False
if isTens: tensValue += 1
else: onesValue += 1
elif receivedEdge is not None:
if isTens:
isTens = False
onesValue += 1
else:
return ((tensValue - 1) * 10) + (onesValue - 1)
else:
return ((tensValue - 1) * 10) + (onesValue - 1)
def main():
logger.info('Starting HotWaterNotifier')
referenceVoltage = 1.1
lowVoltageCount = 0
try:
while True:
sensorReading = waitReceiveNumber(GPIO_Alert)
voltage = (sensorReading * referenceVoltage) / 1023.0
logger.info('sensorReading: ' + str(sensorReading) + ', voltage: ' + str(voltage))
if sensorReading <= lowSensorReading:
lowVoltageCount += 1
if lowVoltageCount >= maxLowVoltageCount:
logger.info('Low voltage alert')
send_email_alert()
lowVoltageCount = 0
else:
lowVoltageCount = 0
except KeyboardInterrupt:
logger.info('Keyboard interrupt received')
GPIO.cleanup()
if __name__ == "__main__":
main()
Script para Iniciar Código Python
#!/bin/bash # run_HotWaterNotifier.sh cd /home/pi/hotwater sudo python HotWaterNotifier.py
Processo de manufatura
- Home Energy Centre: Monitoramento Solar PV, Painéis Térmicos e Temperaturas de Ambientes com Raspberry Pi e Moteino
- Crie um Sistema Ambilight Impressionante para Monitor com Arduino
- Monitoramento em Tempo Real de Painel Solar com Arduino: Sistema de Aquisição de Dados de Baixo Custo
- Capture Gotas d'Água em Ação com Arduino Nano – Fotografia de Alta Velocidade DIY
- Monitore e Registre Energia com Arduino – Guia Passo a Passo (Dr. Wattson)
- Monitor de Frequência Cardíaca IoT em Tempo Real com Arduino e MAX30100
- Monitor de Temperatura e Relógio Tempo Real com Arduino Due e Display TFT 3.2"
- Aquecedor de Água por Bomba de Calor Ideal: Soluções Eficientes de Água Quente
- Como Escolher a Melhor Bomba de Água Quente Doméstica – Dicas e Guia de Especialista
- Bombas de Água Quente: Como Funcionam e Por Que São Importantes