Monitor de voltaje del termopar del calentador de agua caliente
Componentes y suministros
| × | 1 | ||||
| × | 1 |
Acerca de este proyecto
Sistema de control de luz piloto de calentador de agua caliente
Los calentadores de agua a gas tradicionales mantienen una luz piloto 24x7. Esta luz piloto calienta un termopar que genera un pequeño voltaje (hasta 30 milivoltios). Este voltaje es utilizado por el termostato del calentador de agua para mantener abierta una válvula de gas. Si la luz piloto se apaga, el voltaje se detiene y la válvula de gas se cierra automáticamente.
En mi calentador de agua, la luz piloto se apaga ocasionalmente. Dado que esto solo ocurre alrededor de 3 veces al año, no quiero reemplazar el costoso calentador de agua. Intenté reemplazar el termopar, pero esto no resolvió el problema.
Mi solución:monitorear el voltaje generado por el termopar. Si cae a cero, envíe mensajes de texto y correos electrónicos para que pueda volver a encender la luz piloto. Recuerde, no hay peligro de fuga de gas aquí, porque la válvula de gas se cerrará siempre que el voltaje del termopar caiga a cero.
Descripción general
Se utilizará una Raspberry Pi Zero WH para enviar correos electrónicos y mensajes de texto cuando se apague la luz piloto. Debido a que la Raspberry Pi no tiene una forma de medir el voltaje, se usa un Arduino Nano para monitorear el voltaje del termopar.
Los arduinos tienen convertidores de analógico a digital (ADC) que pueden leer un voltaje y convertirlo a un número entre 0 y 1023. En este proyecto, el Arduino lee el voltaje del termopar y comunica este valor a la Raspberry Pi. La Raspberry Pi recibe la lectura de voltaje y la interpreta. Si el valor es demasiado bajo, asumimos que la luz piloto se ha apagado y enviamos notificaciones.
Paso 1:prepara tu Raspberry Pi
Ponga en marcha la Raspberry Pi en su red (puede consultar mi otro proyecto para obtener instrucciones para hacer esto).
Cree un programa Python que reciba lecturas de voltaje del Arduino. El programa se repetirá y enviará notificaciones cuando la lectura de voltaje sea demasiado baja. Se adjunta el código fuente.
Paso 2:prepara tu Arduino
Compré Arduino Nanos chinos baratos, por lo que fue necesario un poco de prueba y error para que funcionaran con mi computadora con Windows 10.
Cargue el Arduino con un boceto para medir el voltaje en su pin de entrada cada 30 segundos. El Arduino puede medir voltaje entre 0 y un voltaje de referencia. Se puede seleccionar 1,1 V o 5 V como voltaje de referencia. Debido a que el termopar solo emite como máximo 30 milivoltios, usaremos el voltaje de referencia de 1.1V para una mayor resolución. El Arduino ADC emite 0 para 0 V y 1023 para 1,1 V. Como se mencionó, el termopar está emitiendo como máximo 30 milivoltios, por lo que la lectura será 28 o menos.
Paso 3:conecta el Arduino a la fuente de voltaje
El termopar envía voltaje al termostato del calentador de agua a través de un cable coaxial. El exterior del cable es positivo.
Corte el cable a unas 5 pulgadas del termostato del calentador de agua. Corta un poco la parte exterior del cable coaxial para que el cable del medio sea accesible. No destruya el aislamiento que esté pintado en el cable del medio. No queremos que el cable del medio se cortocircuite con el exterior del cable coaxial.
Conecte el cable para que suministre el voltaje positivo al termostato del calentador de agua caliente y al pin de entrada Arduino. Usé el pin de entrada A0. El lado negativo de la fuente de voltaje debe estar conectado a la tierra del Arduino, así como el lado negativo del termostato del calentador de agua.
Usé cables de 1 pie de largo con pinzas de cocodrilo en los extremos para hacer las conexiones.
Paso 4:conecta el Arduino a la Raspberry Pi
Nuestro boceto que se ejecuta en Arduino transmitirá el número de voltaje del ADC a la Raspberry Pi. El Arduino enviará la señal como salida desde su pin digital 9.
Los arduinos envían señales a + 5V. La Raspberry Pi solo puede recibir una entrada de 3V. Por lo tanto, entre Arduino y Raspberry Pi, debe haber un divisor de voltaje. Esto reduce el voltaje de 5 V a aproximadamente 2,8 V.
Un divisor de voltaje es un sistema de resistencias que reducen el voltaje de entrada.
El voltaje de salida está determinado por la relación del divisor de voltaje.
No se puede usar una sola resistencia para reducir el voltaje porque cuando no fluye corriente, el voltaje en ambos lados de la resistencia será Vin (5V). El uso de un divisor de voltaje reducirá el voltaje incluso en una situación sin corriente.
Los cables de tierra de todo deben estar conectados. Vea el diagrama de conexión.
Paso 5:Arduino transmite la medición de voltaje
Cada 30 segundos, el boceto de Arduino obtiene la medición de voltaje del ADC y transmite el número a la Raspberry Pi. Decidí usar un sistema de señalización primitivo de un solo cable desde el pin 9 de Arduino al pin 16 de Raspberry Pi.
Paso 6:Raspberry Pi recibe la medición de voltaje
La Raspberry Pi usa un programa Python con un bucle infinito para escuchar los bordes ascendentes en el pin 16. Cuando se detecta un borde ascendente, se asume que Arduino ha comenzado a transmitir un número.
Sistema de señalización
Transmita un número de dos dígitos (por ejemplo:"12"). Cada dígito está precedido por un pulso positivo recibido en el pin 16. Los pulsos positivos subsiguientes separados por menos de 20 milisegundos (ms) incrementan el valor de este dígito. Una pausa de más de 40 ms indica que este dígito está completo y comienza el siguiente. Otra pausa de más de 40 ms indica que el segundo dígito está completo. El número completo de dos dígitos ahora está completo.
En el código Python que se ejecuta en Raspberry Pi, el número recibido del Arduino se devuelve del método que interpreta las señales del Arduino. Otro código de Python decide si se debe enviar una notificación o no. Luego, el código vuelve a esperar en el próximo flanco ascendente en el pin 16.
Paso 7:envíe la notificación
Si el voltaje es demasiado bajo, incremente el conteo bajo. Se mantiene un recuento bajo para evitar falsas alarmas. Si el recuento bajo llega a 5, entonces el voltaje ha sido bajo durante 5 mediciones. Cada medición tiene una diferencia de 30 segundos. Envíe la notificación y restablezca el recuento bajo. Las notificaciones se envían mediante smtplib y una cuenta de Gmail. Una marca de tiempo se almacena en el código Python cuando se envía la notificación. La próxima notificación no se enviará hasta dentro de 6 horas.
Para enviar alertas de texto, utilicé una función que ofrecen la mayoría de los proveedores de telefonía móvil:la capacidad de enviar un mensaje de texto a sus usuarios por correo electrónico. Ej .:para Verizon:[email protected] envía un mensaje de texto a ese número.
Gmail
Creé una nueva cuenta de Gmail para usarla para enviar notificaciones. Al principio, configuré la configuración de seguridad en esta cuenta de Gmail para permitir un acceso 'menos seguro', de modo que el código Python pudiera enviar correos electrónicos. Sin embargo, después de unos meses, Gmail puede desactivar este acceso menos seguro. Descubrí que Gmail prefiere que los usuarios usen contraseñas de aplicaciones.
Configurar una contraseña de aplicación
https://support.google.com/accounts/answer/185833
Paso 8:conecta todo
Conecte el Arduino al cable del termopar del calentador de agua y a la Raspberry Pi a través del divisor de voltaje. (La parte superior de mi divisor de voltaje usa dos resistencias que suman 550 ohmios, porque esas son las resistencias que tenía a mano). Encienda el Arduino y comenzará a medir el voltaje y enviar señales a la Raspberry Pi cada 30 segundos.
Paso 9:Ejecute el programa Python
- Cree una secuencia de comandos que inicie su programa Python.
- Edite el crontab raíz para ejecutar automáticamente su secuencia de comandos en el momento del arranque. Edite las rutas del directorio según corresponda para su Raspberry Pi y donde tenga guardado el programa Python.
- Para editar el crontab:
sudo crontab -e
- Agregue una línea para ejecutar su secuencia de comandos 'kick-off' cuando se reinicie la Raspberry Pi:
@reboot sh /home/pi/hotwater/run_HotWaterNotifier.sh>> / home / pi / hotwater /logs/HotWaterNotifier.log 2> &1
- Para ejecutar manualmente (antes de tener la configuración de crontab)
Primero ejecute el proceso (ejecute su script run_HotWaterNotifier.sh)
Luego escribactrl-Z
para suspender su proceso
Luego escribabg
una o dos veces para enviar el proceso al fondo
Escribadisown
, esto permite que el proceso continúe ejecutándose después de cerrar la sesión - Para ver si el proceso aún se está ejecutando
ps aux | grep -i Agua Caliente
Código
- Código Arduino
- Código Phython
- Secuencia de comandos para iniciar el código Python
Código Arduino Arduino
Esto lee el voltaje cada 30 segundos y envía señales a la Raspberry Pi/ ****************************** ******************************************* HotWaterHeater Mide el voltaje procedente del termopar del calentador de agua. Utiliza la señalización para enviar esta medición del sensor de voltaje a la Raspberry Pi. *********************************************** ************************** /// doble ReferenceVoltage =5.0; // voltaje de referencia no utilizado doble ReferenceVoltage =1.1; int OUTPUT_PIN =9; int INTRA_DIGIT_WAIT =20; int BETWEEN_DIGIT_WAIT =50; //////////////////////////// //////////////////////////////////////////////////// ///// la función de configuración se ejecuta una vez al presionar reiniciar o encender la placa ////////////////////////////////// ///////////////////////////////////////////////// configuración vacía ( ) {// inicializa el pin digital LED_BUILTIN como salida. pinMode (LED_BUILTIN, SALIDA); pinMode (OUTPUT_PIN, SALIDA); // establece el pin digital 9 como salida analogReference (INTERNAL); Serial.begin (9600); // abre el puerto serie, establece la velocidad de datos en 9600 bps} /////////////////////////////////////// ////////////////////////////////////////////// La función de bucle se ejecuta y otra vez para siempre.// Mida el voltaje en el pin de entrada.// Luego envíe esa lectura a la Raspberry Pi //////////////////////////// //////////////////////////////////////////////////// /// bucle vacío () {int pinInput; doble voltaje; pinInput =analogRead (A0); // Entrada de sonda Serial.print ("PinInputA0 ="); Serial.print (pinInput); // El Arduino ADC es un convertidor de diez bits, lo que significa que el valor de salida variará de 0 a 1023 voltaje =(pinInput * ReferenceVoltage) / 1023; Serial.print (", voltageA0 ="); Serial.println (voltaje); // Nota:una lectura de 5 =5.38 mV sendNumberSignal (pinInput, OUTPUT_PIN, INTRA_DIGIT_WAIT, BETWEEN_DIGIT_WAIT); // Ejecute la verificación una vez cada 30 segundos de retraso (30000);} / ******************************** ****************************************** * Señalar un número en un solo alambre. * * Para cada dígito envíe una serie de pulsos. * También hay un pulso de inicio inicial. * Cada pulso se ve así:__ / 20ms \ __ 20ms__ * 20 + 20ms entre bordes ascendentes dentro del mismo dígito * * Entre dígitos:__ / 20ms \ __ 20ms__ 50ms___ * 20 + 20 + 50ms entre dígitos ********* *********************************************** ****************** / void sendNumberSignal (int número, int pin, int intraDigitWait, int betweenDigitWait) {int decenas =número / 10; int unos =número% 10; Serial.print ("Señalización:"); Serial.println (número); // depuración //////// //Serial.print("tens:"); //Serial.println(tens); //Serial.print("ones:"); //Serial.println(ones); //Serial.print("millis:"); //Serial.println (millis ()); // depuración //////// //Serial.println("enviar decenas "); //Serial.print("millis:"); //Serial.println (millis ()); // envía el número de decenas sendPulse (pin, intraDigitWait); para (int i =0; iCódigo Phython Python
Este código recibe señales del Arduino. Interpreta las señales en una lectura de voltaje. Luego decide si el voltaje es demasiado bajo. Si el voltaje es demasiado bajo, envía correos electrónicos y mensajes de texto.################################ ########################################### HotWaterNotifier.py # Monitoree el pin de entrada y reciba señales de un Arduino. # Decodifique las señales en medidas numéricas del sensor de voltaje. # Cuando la lectura de voltaje recibida es demasiado baja, esto indica que la luz piloto # está apagada. Cuando esto ocurre durante 5 mediciones seguidas, suponga que # la luz piloto realmente está apagada. Envíe correos electrónicos / mensajes de texto y registre el tiempo. # Solo envíe un correo electrónico / mensaje de texto cada seis horas. ## Esto fue escrito para Python 2.7. Es posible que se requieran cambios menores para Python 3. ####################################### ################################### Importar smtplibimport RPi.GPIO como GPIOimport osimport os.pathimport timeimport datetimeimport stringimport loggingimport sys # Ingrese GPIO para recibir señales del ArduinoGPIO_Alert =16 # Cuántas horas esperar entre emailsemailWaitHours =6 # Lectura del sensor de bajo voltaje. # Menor o igual a esto es bajo voltaje.lowSensorReading =1 # Una vez este número bajo se alcanzan las lecturas del sensor, envíe el alertmaxLowVoltageCount =5 # para la numeración GPIO, elija BCMGPIO.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) #declare variable global ################################# ########################################## Configurar el registrador. ## ################################################ ########################## def setup_custom_logger (nombre):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 (formateador) screen_handler =logging.StreamHandler (stream =sys.stdout) screen_handler.setFormatter (formateador) logger =logging.getLogger (nombre) logger.setLevel (logging.DEBUG) logger.addHandler (handler) logger.addHandler (screen_handler) return logger ## ################################################ ############################ Función para enviar correos electrónicos / mensajes de texto ################ ################################################ ############# def send_email_alert ():# permite escribir en la variable global global lastEmailSentTime # comprobar si ha pasado suficiente tiempo desde el último correo electrónico nowTime =datetime.datetime.now () emailWaitDelta =datetime .timedelta (hours =emailWaitHours) limitTime =nowTime - emailWaitDelta #si ha pasado suficiente tiempo, envíe el correo electrónico. si lastEmailSentTime es None o limitTime> lastEmailSentTime:logger.info ('Enviando alerta por correo electrónico ...') HOST ="smtp.gmail.com" PORT =587 SUBJECT ="Alerta de calentador de agua" # Esto debería ser un objeto de lista para varias direcciones TO =["[email protected]", "[email protected]"] #TO =["[email protected]"] FROM ="[email protected]" PWD ="XXXXXXXXXXXXXX" text =" Bajo voltaje medido en el calentador de agua caliente "# El campo a se une en 1 cadena aquí. #Esto es lo que se muestra al destinatario en su correo electrónico. BODY =string.join (("from:% s"% FROM, "to:% s"% "," .join (TO), "Subject:% s"% SUBJECT, "", text), "\ r \ n ") intente:s =smtplib.SMTP (HOST, PORT) s.set_debuglevel (1) s.ehlo () s.starttls () s.login (FROM, PWD) s.sendmail (FROM, TO, BODY) s.quit excepto Exception como e:logger.exception ('Excepción de envío de archivos capturados. Intentando de nuevo en 6 horas') # establezca la hora para que no se envíe un correo electrónico durante 6 horas lastEmailSentTime =nowTime else:logger.info (' No enviamos correo electrónico. Último correo electrónico enviado a:'+ lastEmailSentTime.strftime ("% Y-% m-% d% H:% M:% S")) ############### ################################################ ############### Recibe señales del Arduino. # Un número se compone de dos dígitos. (un dígito en lugar de decenas y un dígito en lugar de unidades) # El Arduino siempre transmite un número, que consta de 2 dígitos. # Las señales recibidas son una serie de pulsos altos en el pin de entrada. # El método waitReceiveNumber () cuenta los pulsos altos y el [conteo -1] es # el valor del dígito. # Cada dígito está precedido por 1 pulso. ## 70 ms como máximo entre los bordes de la señal dentro del mismo dígito # los bordes ascendentes separados por menos de 70 ms son el mismo dígito # si es mayor de 70 ms, luego pasar al siguiente dígito # 200 ms significa que el número está completo ############################### ########################################### def waitReceiveNumber (GPIO_Alert ):lastSignalTime =datetime.datetime (2000,1,1,0,0,0,0) isTens =True isFirstIteration =True tensValue =0 onesValue =0ivedEdge =None #Menos de 70ms entre pulsos:este es el mismo dígito todavía siendo transmitido # Incrementar el valor del dígito actual # Más de 70ms:cambiar al siguiente dígito singleDigitMilliseconds =datetime.timedelta (milisegundos =70) #Si este tiempo de espera se alcanza, es el final del número WholeNumberWaitTime =200 # espere aquí hasta que se detecte un flanco ascendente # logger.info ('Esperando en el pin GPIO:' + str (GPIO_Alert)) mientras que True:#Arduino envía un pulso cuando parpadea eso, inicie la Raspberry Pi en segundo lugar. # El Arduino debería arrancar más rápido en caso de un corte de energía. if isFirstIteration :ivedBorde =GPIO.wait_for_edge (GPIO_Alert, GPIO.RISING, timeout =-1) #esperar eternamente hasta un pulso de inicio else:selectedEdge =GPIO.wait_for_edge (GPIO_Alert, GPIO.RISING, timeout =wholeNumberWaitTime) # up to waitTime ms #calcular las métricas de tiempo para esta señal signalTime =datetime.datetime.now () signalInterval =signalTime - lastSignalTime lastSignalTime =signalTime #debugging:logger.info ('signalInterval:' + str (signalInterval.total_seconds () * 1000 )) #determine qué dígito incrementar if (signalInterval=singleNumber isMillise to ones isTens =False onesValue + =1 else:#isOnes # no puede pasar al siguiente dígito, por lo que el número está completo. #Esto no debería suceder. Una vez hecho el número, #la espera debe agotarse y el borde recibido debe ser Ninguno. return ((tensValue -1) * 10) + (onesValue -1) else:#timeout, por lo que el número está completo. return ((tensValue -1) * 10) + (onesValue -1) ################################ ########################################### El método principal # ################################################ ########################### def main ():logger.info ('Iniciando HotWaterNotifier') referenceVoltage =1.1 lowVoltageCount =0 prueba:while True:# Esto se bloqueará hasta que reciba señales del Arduino. # Solo regresará una vez que se reciba un número completo. sensorReading =waitReceiveNumber (GPIO_Alert) #calcular el voltaje del voltaje de lectura del sensor Arduino =(sensorReading * referenceVoltage) / 1023; logger.info ('sensorReading:' + str (sensorReading) + ', voltage:' + str (voltage)) if sensorReading <=lowSensorReading:lowVoltageCount + =1 #increment if lowVoltageCount> =maxLowVoltageCount:logger.info ('Alerta de bajo voltaje ') send_email_alert () lowVoltageCount =0 #restablecer el contador porque enviamos una alerta else:lowVoltageCount =0 #restablecer el contador porque se recibió un buen voltaje excepto KeyboardInterrupt:logger.info (' Se recibió una interrupción del teclado ') GPIO.cleanup () # limpiar GPIO en CTRL + C salir GPIO.cleanup () # limpiar GPIO ############################### ################################################ La prueba método de correo electrónico ############################################# ############################## def testEmail ():logger.info ('Iniciando HotWaterNotifier') referenceVoltage =1.1 lowVoltageCount =0 intente:send_email_alert () excepto KeyboardInterrupt:logger.info ('Se recibió una interrupción del teclado') GPIO.cleanup () # limpiar GPIO en CTRL + C salir de GPIO.cleanup () # limpiar GPIO ######## ############ ############################################### ########## Una variable global #################################### ######################################### Configurar un registro de archivos de registro =setup_custom_logger ('HotWaterNotifier') ########################################## ################################## Llamar al método principal. ## Llamar testEmail () aquí en su lugar si desea probar la capacidad de correo electrónico. ######################################### ################################### if __name __ =="__main__":main () Script para iniciar el código Python SH
Este es el script que crontab llama para iniciar el código Python#! / Bin / bash # run_HotWaterNotifier.sh # Ejecuta notifiercd / home / pi / hotwatersudo python HotWaterNotifier.py
Proceso de manufactura
- Monitoreo de la temperatura ambiente con Moteino's y Raspberry Pi
- Hacer Monitor Ambilight usando Arduino
- Adquisición de datos en tiempo real del panel solar usando Arduino
- Capturando las gotas de agua con Arduino
- Cómo construir un monitor de energía Arduino y un registrador de datos
- Monitor de frecuencia cardíaca con IoT
- Arduino Temp. Monitor y reloj en tiempo real con pantalla 3.2
- Contador Geiger Muller personalizable
- La Bomba de Calor Perfecta Agua Caliente
- ¿Cómo elegir la mejor bomba de agua caliente sanitaria?
- Una introducción a la bomba de agua caliente