Sichere Warmwasserbereitung: Thermospannungs-Monitor für Zündflamme (Arduino & Raspberry Pi)
Benötigte Komponenten
- Adafruit Raspberry Pi Zero WH (1×)
- Arduino Nano R3 (1×)
Projektbeschreibung
Gas-Durchlauferhitzer halten eine Zündflamme (Pilot Light) permanent brennend. Diese erhitzt ein Thermoelement, das eine winzige Spannung (bis 30 mV) erzeugt. Diese Spannung hält das Gasventil offen. Erlischt die Flamme, fällt die Spannung auf 0 und das Ventil schließt sicher. Da die Flamme bei mir gelegentlich erlischt (ca. 3×/Jahr), überwache ich die Thermospannung. Fällt sie auf 0, senden Raspberry Pi per E-Mail/SMS Alarm – so kann ich die Flamme neu entzünden, bevor kaltes Wasser fließt.
Übersicht
Raspberry Pi Zero WH sendet Benachrichtigungen. Da der Pi keine Analogeingänge hat, misst ein Arduino Nano die Thermospannung und übermittelt den Wert digital an den Pi (einfaches Single-Wire-Protokoll).
Schritt 1: Raspberry Pi vorbereiten
Pi ins Netzwerk einbinden (Headless-Setup). Python-Skript HotWaterNotifier.py erstellen, das in Endlosschleife auf Signale vom Arduino wartet, Werte dekodiert, bei zu niedrigem Wert (5 Messungen hintereinander) Alarm per SMTP (Gmail) sendet. Cooldown: 6 Stunden zwischen Alarmen.
Schritt 2: Arduino vorbereiten
Günstige China-Nanos evtl. Treiberprobleme unter Windows 10 lösen. Sketch laden, der alle 30 Sekunden die Spannung an A0 misst (interne 1,1V Referenz für höhere Auflösung: 0–1023 entspricht 0–1,1V, 30 mV ≈ 28). Wert als zweistellige Zahl per Single-Wire an Pin 9 senden.
Schritt 3: Arduino an Thermoelement anschließen
Thermoelement-Koaxialkabel zum Gasthermostat ca. 13 cm vom Thermostat abschneiden. Außenleiter (Plus) freilegen, Innenleiter (Minus) isoliert lassen. Außenleiter an Arduino A0, Innenleiter an Arduino GND. Gleichzeitig muss der Außenleiter weiter zum Thermostat geführt werden (Parallelschaltung). Krokodilklemmen für temporären Test.
Schritt 4: Arduino an Raspberry Pi anschließen
Arduino Pin 9 (5V Pegel) → Spannungsteiler → Raspberry Pi GPIO 16 (3,3V max). Spannungsteiler: zwei Widerstände (z. B. 550 Ω gesamt oben, 1 kΩ unten → ca. 2,8V). Alle GNDs verbinden.
Schritt 5: Arduino sendet Messwert
Alle 30 s: ADC lesen, als zweistellige Zahl (0–28) per Pulsfolge senden: Startpuls, dann für Zehner und Einer je Wert+1 Pulse (20 ms High, 20 ms Low). Zwischen Ziffern 50 ms Pause.
Schritt 6: Raspberry Pi empfängt & dekodiert
Python wartet auf Rising Edge an GPIO 16. Misst Pulsabstände: <70 ms = gleiche Ziffer, >70 ms = nächste Ziffer, Timeout 200 ms = Zahl komplett. Berechneter Sensorwert = (Zehner×10) + Einer.
Schritt 7: Benachrichtigung senden
Bei Sensorwert ≤ 1 (entspricht ~0 mV) Low-Count erhöhen. Bei 5 aufeinanderfolgenden Low-Messungen (2,5 Min) Alarm per smtplib (Gmail App-Passwort). E-Mail an eigene Adresse, SMS via Carrier-Gateway (z. B. 5555555555@vtext.com für Verizon). Timestamp speichern, nächster Alarm erst nach 6 h.
Schritt 8: Alles verbinden & starten
Arduino an Thermoelement & Pi (Spannungsteiler) anschließen. Arduino mit Strom versorgen (USB). Pi Skript starten.
Schritt 9: Python-Skript als Dienst einrichten
- Starter-Skript
run_HotWaterNotifier.sherstellen (cd /home/pi/hotwater && sudo python HotWaterNotifier.py). - Root-Crontab:
@reboot sh /home/pi/hotwater/run_HotWaterNotifier.sh >> /home/pi/hotwater/logs/HotWaterNotifier.log 2>&1 - Manueller Start: Skript ausführen, Strg+Z,
bg,disown. Prüfen mitps aux | grep -i HotWater.
Code
Arduino Sketch
/****************************************************************************** HotWaterHeater Measures the voltage coming from the hot water heater's thermocouple. Uses signaling to send this voltage sensor measurement to the 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;
Serial.print("PinInputA0="); Serial.print(pinInput);
Serial.print(", voltageA0="); Serial.println(voltage);
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;
sendPulse(pin, intraDigitWait);
for (int i=0; i
Python Code (HotWaterNotifier.py)
###############################################################################
# HotWaterNotifier.py
# Monitor the input pin and receive signals from an Arduino.
# Decode the signals into numeric voltage sensor measurements.
# When the received voltage reading is too low, this indicates that the
# pilot light is out. When this occurs for 5 measurements in a row, assume that
# the pilot light really is out. Send emails/texts and record the time.
# Only send an email/text every six hours.
###############################################################################
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()
emailWaitDelta = datetime.timedelta(hours=emailWaitHours)
limitTime = nowTime - emailWaitDelta
if lastEmailSentTime is None or limitTime > lastEmailSentTime:
logger.info('Sending email alert...')
HOST = "smtp.gmail.com"; PORT = 587
SUBJECT = "Hot Water Heater Alert"
TO = ["XXXXXXXXXXXXXX@gmail.com", "5555555555@vtext.com"]
FROM = "XXXXXXXXXXXXXX@gmail.com"
PWD = "XXXXXXXXXXXXXX" # App-Passwort
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
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()
GPIO.cleanup()
if __name__=="__main__": main()
Starter-Skript (run_HotWaterNotifier.sh)
#!/bin/bash
cd /home/pi/hotwater
sudo python HotWaterNotifier.py
Automatische Pflanzenbewässerung mit Arduino – Sorgenfrei in den Urlaub
ATmega328P Alien-Slot-Machine Kit – Selbstbau-Spielautomat
Herstellungsprozess
- Home Energy Centre: Solar PV, Thermische Panels & Raumtemperaturen mit Raspberry Pi & Moteino überwachen
- Monitor-Ambilight selbst bauen mit Arduino Nano & WS2812B LEDs
- Echtzeit-Solarmonitoring mit Arduino: Low-Cost Datenerfassungssystem
- Wassertropfen-Hochgeschwindigkeitsfotografie mit Arduino Nano – DIY Setup
- Arduino Energiemonitor & Datenlogger (Dr. Wattson, MCP39F521) – Schritt-für-Schritt
- Echtzeit-IoT-Herzfrequenzmonitor mit Arduino & MAX30100
- Arduino Temperaturoverwachung & Echtzeituhr mit 3,2″ TFT-Display
- Optimale Wärmepumpen-Warmwasserbereiter: Energieeffiziente Warmwasserversorgung
- Die beste Warmwasser-Zirkulationspumpe für zu Hause wählen – Expertentipps & Ratgeber
- Heißwasserpumpen: Funktionsweise, Einsatzgebiete & Energiesparpotenzial