Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

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

Garanta Aquecimento Seguro de Água: Monitor de Tensão do Termopar para Chama Piloto

O termopar envia tensão ao termostato via fio coaxial. O externo é positivo.

  1. Corte o fio ~13 cm antes do termostato.
  2. Recue a blindagem externa para acessar o fio central. Não destrua o isolamento do fio central – evitar curto com a blindagem.
Garanta Aquecimento Seguro de Água: Monitor de Tensão do Termopar para Chama Piloto

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.

Garanta Aquecimento Seguro de Água: Monitor de Tensão do Termopar para Chama Piloto

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.

Garanta Aquecimento Seguro de Água: Monitor de Tensão do Termopar para Chama Piloto

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

Garanta Aquecimento Seguro de Água: Monitor de Tensão do Termopar para Chama Piloto

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

Garanta Aquecimento Seguro de Água: Monitor de Tensão do Termopar para Chama Piloto

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

Garanta Aquecimento Seguro de Água: Monitor de Tensão do Termopar para Chama Piloto

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

  1. Home Energy Centre: Monitoramento Solar PV, Painéis Térmicos e Temperaturas de Ambientes com Raspberry Pi e Moteino
  2. Crie um Sistema Ambilight Impressionante para Monitor com Arduino
  3. Monitoramento em Tempo Real de Painel Solar com Arduino: Sistema de Aquisição de Dados de Baixo Custo
  4. Capture Gotas d'Água em Ação com Arduino Nano – Fotografia de Alta Velocidade DIY
  5. Monitore e Registre Energia com Arduino – Guia Passo a Passo (Dr. Wattson)
  6. Monitor de Frequência Cardíaca IoT em Tempo Real com Arduino e MAX30100
  7. Monitor de Temperatura e Relógio Tempo Real com Arduino Due e Display TFT 3.2"
  8. Aquecedor de Água por Bomba de Calor Ideal: Soluções Eficientes de Água Quente
  9. Como Escolher a Melhor Bomba de Água Quente Doméstica – Dicas e Guia de Especialista
  10. Bombas de Água Quente: Como Funcionam e Por Que São Importantes