Veilige CV-ketelbewaking: Thermocouple-spanningsmonitor voor pilootvlammen
Onderdelen en benodigdheden
| Adafruit Raspberry Pi Zero WH | 1 |
| Arduino Nano R3 | 1 |
Over dit project
CV-ketel pilootvlam monitoringssysteem
Traditionele gas-CV-ketels onderhouden 24/7 een pilootvlam. Deze verhit een thermocouple die een kleine spanning genereert (max 30 millivolt). De ketelthermostaat gebruikt deze spanning om de gasklep open te houden. Gaat de pilootvlam uit, valt de spanning weg en sluit de gasklep automatisch.
Mijn ketel heeft af en toe een uitgedoofde pilootvlam (~3x per jaar). Vervangen is duur, en een nieuwe thermocouple lost het niet op. Mijn oplossing: de thermocouple-spanning monitoren. Bij spanning = 0 → stuur SMS en e-mail om de pilootvlam weer aan te steken. Geen gevaar op gaslek: de gasklep sluit automatisch bij spanningsval.
Overzicht
Een Raspberry Pi Zero WH stuurt e-mails/SMS bij uitval. Omdat de Pi geen spanning kan meten, gebruikt een Arduino Nano de ADC (analog-naar-digitaal converter) om de thermocouple-spanning te lezen (0-1023). De Arduino communiceert de waarde naar de Pi. De Pi interpreteert: te lage waarde = pilootvlam uit → notificaties versturen.
Stap 1: Raspberry Pi voorbereiden
Zet de Pi op het netwerk (zie mijn ander project voor instructies). Maak een Python-programma dat spanningen van de Arduino ontvangt, in een lus draait, en notificaties stuurt bij te lage waarden. Broncode is bijgevoegd.
Stap 2: Arduino voorbereiden
Goedkope Chinese Arduino Nano's kunnen problemen geven op Windows 10 – probeer tot het werkt. Laad een sketch die elke 30 seconden de spanning op de invoerpin meet. Gebruik de 1.1V interne referentie voor hogere resolutie (thermocouple max 30mV → ADC-waarde max ~28).
Stap 3: Arduino aansluiten op de spanningbron
De thermocouple loopt via een coax-kabel naar de thermostaat. De buitenkant is plus.
- Knip de kabel ~12cm van de thermostaat af.
- Schuif de buitenmantel iets terug zodat de binnenleider bereikbaar is. Beschadig de isolatie van de binnenleider niet (kortsluitinggevaar).
- Verbind zo dat de plusspanning naar de thermostaat en naar Arduino pin A0 gaat. De min-zijde naar Arduino GND en thermostaat-min.
- Ik gebruikte 30cm draden met krokodillenklammen voor de verbindingen.
Stap 4: Arduino verbinden met Raspberry Pi
De Arduino stuurt de ADC-waarde via digitale pin 9 naar de Pi. Arduino = 5V logica, Pi = 3.3V max. Er is een spanningsdeler nodig (5V → ~2.8V).
Spanningsdeler: Twee weerstanden in serie. Uittap tussen de weerstanden naar Pi GPIO16. Alle grounds (Arduino, Pi, thermocouple) verbinden.
Formule: Vout = Vin × R2 / (R1 + R2). Kies weerstanden zodat Vout ≤ 3.3V.
Stap 5: Arduino stuurt meting door
Elke 30 seconden meet de Arduino de ADC-waarde en stuurt het getal via een primitief eendraads signaalprotocol van pin 9 naar Pi pin 16.
Stap 6: Raspberry Pi ontvangt meting
Python-programma met oneindige lus luistert naar stijgende flanken op pin 16. Bij detectie begint ontvangst van een 2-cijferig getal.
Signaalprotocol:
- Elk cijfer wordt voorafgegaan door een puls.
- Opvolgende pulsen < 20ms verhogen de cijferwaarde.
- Pauze > 40ms = einde van dit cijfer, volgende cijfer begint.
- Tweede pauze > 40ms = getal compleet.
De ontvangen waarde wordt teruggegeven. Andere code beslist of notificatie nodig is. Daarna wachten op volgende stijgende flank.
Stap 7: Notificatie versturen
Bij te lage spanning: verhoog low count. Bij 5 opeenvolgende lage metingen (2.5 minuten) → verstuur notificatie, reset teller. Herhaal niet binnen 6 uur.
E-mail via smtplib en Gmail. SMS via provider-gateway (bijv. Verizon: 5555555555@vtext.com).
Gmail: Maak een apart account. Eerst "less secure apps" inschakelen, later beter: app-wachtwoord gebruiken.
Stap 8: Alles verbinden
Arduino → thermocouple-draad + spanningsdeler → Raspberry Pi. Arduino voeden → begint met meten en signaleren elke 30 seconden.
Stap 9: Python-programma draaien
- Maak een startscript (
run_HotWaterNotifier.sh). - Voeg toe aan root crontab voor autostart bij boot:
@reboot sh /home/pi/hotwater/run_HotWaterNotifier.sh >> /home/pi/hotwater/logs/HotWaterNotifier.log 2>&1 - Handmatig starten: script uitvoeren, Ctrl+Z,
bg,disown. - Check of draait:
ps aux | grep -i HotWater
Code
Arduino Code (C++)
/*******************************************************************************
* HotWaterHeater - Meet thermocouple-spanning, stuurt naar 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);
// 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);
// Tens digit
sendPulse(pin, intraDigitWait);
for (int i = 0; i < tens; i++) sendPulse(pin, intraDigitWait);
delay(betweenDigitWait);
// Ones digit
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);
}
Python Code (HotWaterNotifier.py)
#!/usr/bin/env python2.7
import smtplib, RPi.GPIO as GPIO, os, time, datetime, 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)
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(levelname)-8s %(message)s',
handlers=[logging.FileHandler('HotWaterLog.txt'), logging.StreamHandler()])
logger = logging.getLogger('HotWaterNotifier')
lastEmailSentTime = datetime.datetime(2000,1,1)
def send_email_alert():
global lastEmailSentTime
now = datetime.datetime.now()
if lastEmailSentTime is None or (now - lastEmailSentTime) > datetime.timedelta(hours=emailWaitHours):
logger.info('Sending email alert...')
HOST, PORT = "smtp.gmail.com", 587
SUBJECT = "Hot Water Heater Alert"
TO = ["xxxx@gmail.com", "5555555555@vtext.com"]
FROM = "xxxx@gmail.com"
PWD = "xxxx"
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.starttls()
s.login(FROM, PWD)
s.sendmail(FROM, TO, BODY)
s.quit()
lastEmailSentTime = now
except Exception as e:
logger.exception('Email failed')
lastEmailSentTime = now
else:
logger.info('Not sending email. Last sent: %s' % lastEmailSentTime)
def waitReceiveNumber(pin):
lastSignal = datetime.datetime(2000,1,1)
isTens = True
first = True
tens = ones = 0
singleDigitMax = datetime.timedelta(milliseconds=70)
wholeNumberTimeout = 200 # ms
while True:
if first:
edge = GPIO.wait_for_edge(pin, GPIO.RISING, timeout=-1)
first = False
else:
edge = GPIO.wait_for_edge(pin, GPIO.RISING, timeout=wholeNumberTimeout)
now = datetime.datetime.now()
interval = now - lastSignal
lastSignal = now
if interval < singleDigitMax or first:
if isTens: tens += 1
else: ones += 1
elif edge is not None:
if isTens:
isTens = False
ones += 1
else:
return (tens-1)*10 + (ones-1)
else:
return (tens-1)*10 + (ones-1)
def main():
logger.info('Starting HotWaterNotifier')
refV = 1.1
lowCount = 0
try:
while True:
reading = waitReceiveNumber(GPIO_Alert)
voltage = (reading * refV) / 1023.0
logger.info('sensorReading: %d, voltage: %.6f' % (reading, voltage))
if reading <= lowSensorReading:
lowCount += 1
if lowCount >= maxLowVoltageCount:
logger.info('Low voltage alert')
send_email_alert()
lowCount = 0
else:
lowCount = 0
except KeyboardInterrupt:
logger.info('Keyboard interrupt')
finally:
GPIO.cleanup()
if __name__ == "__main__":
main()
Startscript (run_HotWaterNotifier.sh)
#!/bin/bash
# run_HotWaterNotifier.sh
cd /home/pi/hotwater
sudo python HotWaterNotifier.py
Productieproces
- Home Energy Centre: Zonnepanelen, thermische panelen en kamertemperaturen monitoren met Raspberry Pi en Moteino
- Bouw een indrukwekkend monitor Ambilight-systeem met Arduino
- Real-time zonnepaneelmonitoring met Arduino: Goedkope data-acquisitie
- Waterdruppels vastleggen met Arduino Nano – DIY High-Speed Fotografie
- Bouw een Betrouwbare Arduino Energiemonitor & Datalogger – Stapsgewijze Handleiding
- Real-time IoT hartslagmonitor met Arduino en MAX30100
- Arduino Temperatuurbewaking & Realtime Klok met 3.2" TFT-display
- Bouw een Eigen Geiger-Müller Tellers met Arduino, HV Boost en 20x4 LCD
- Optimale warmtepomp boiler: energie-efficiënte warmwateroplossingen
- Hoe de Beste Domestische Warmwaterpomp te Kiezen – Expert Tips & Gids
- Warmwaterpomp Basis: Hoe Ze Werken & Waarom Ze Belangrijk Zijn