# Proyecto "Regulador de Bomba" creado por alumnos de la Universidad Nacional de La Matanza para la materia de Fundamentos de Sistemas Embebidos.
"""
Integrantes del grupo 9 (Comisión 5):
Ojeda Brian Ezequiel
Salazar Nicolás Ezequiel
Cristó Mártin Lautaro
"""
# Programa
"""
El siguiente programa detectará la luz del día y
activara una bomba de agua de una pileta durante un tiempo determinado,
ciclo que se repetira una vez por día.
Tendremos una aplicación (dashboard en Adafruit) que nos mostrará el estado del programa,
una función de apagado y encendido de emergencia.
"""
# Solución
"""
Para solucionar nuestro problema utilizamos un sensor LDR y un módulo de relé.
El primero nos permite conocer la cantidad de luz que hay en el medio,
permitiendo a nuestro programa reaccionar en base a este dato, y el segundo
nos permite determinar si la bomba de agua se encuentra encendida o apagada según el estado del LED.
Además, utilizamos el RTC interno del ESP32 sincronizándolo por NTP para la determinación de los
ciclos de uso.
"""
# Bibliotecas
import time
import machine
from machine import Pin, ADC
import network
from umqtt.simple import MQTTClient
import ntptime
# Configuración de pines
sensor_luz = ADC(1)
sensor_luz.atten(ADC.ATTN_11DB) # VCC = 3.3V https://docs.micropython.org/en/latest/esp32/quickref.html#ADC
rele = Pin(7, Pin.OUT) # Control del módulo de relé
rele.value(1)
# Variables del sistema
bomba_activada = False
modo_emergencia = False
umbral_luz = 2000 # Umbral de nivel de luz para encender/apagar la bomba
ultima_activacion = None # Última activación de la bomba
ciclo_bomba = False # Ciclo que determina que permita volver a activar la bomba
# Conexión Wi-Fi
def conectar_wifi():
print("Conectando a Wi-Fi", end="")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('Wokwi-GUEST', '') # ssid y password
intentos = 0
max_intentos = 20
while not sta_if.isconnected(): # En caso de que la conexión falle
print(".", end="")
time.sleep(0.5)
intentos += 1
if intentos >= max_intentos:
print("\nConexión fallida. Reiniciando...")
time.sleep(1)
machine.reset()
print("\n¡Conexión exitosa!")
print("Direcciones IP:")
print(sta_if.ifconfig())
# Sincronización con NTP https://docs.micropython.org/en/late_st/esp8266/quickref.html#real-time-clock-rtc
print("Fecha Hora de inicio:%s" % str(time.localtime()))
ntptime.settime() # Ajusta la hora usando el servidor NTP
print("Fecha Hora sincronizada por NTP:%s" % str(time.localtime()))
conectar_wifi()
# Variables del broker MQTT y Adafruit
mqtt_server = 'io.adafruit.com'
port = 1883
user = 'bittertrvth'
password = 'aio_NrBW29dtMHCDTbpNvJnT8gQigLBX'
client_id = 'Qwerty'
topic_1 = 'bittertrvth/feeds/bombamanual'
topic_2 = 'bittertrvth/feeds/estadobomba'
# Función de control MQTT
def funcion_callback(topic, msg):
global bomba_activada # Accedemos a las variables para controlar el estado
global modo_emergencia
dato = msg.decode('utf-8')
topicrec = topic.decode('utf-8')
print("Mensaje en tópico " + topicrec + ": " + dato)
if topicrec == topic_1:
if "ON" in dato: # Encender la bomba manualmente
activar_rele()
bomba_activada = True
modo_emergencia = True
print("Bomba activada manualmente.")
elif "OFF" in dato: # Apagar la bomba manualmente
desactivar_rele()
bomba_activada = False
modo_emergencia = True
print("Bomba desactivada manualmente.")
elif "RESET" in dato:
modo_emergencia = False
print("Modo manual desactivado.")
# Conexión al broker MQTT
try:
conexionMQTT = MQTTClient(client_id, mqtt_server, user=user, password=password, port=int(port))
conexionMQTT.set_callback(funcion_callback) # Función Callback para recibir mensajes
conexionMQTT.connect() # Hacemos la conexión
conexionMQTT.subscribe(topic_1) # Suscripción a tópico
print("Conectado con Broker MQTT")
except OSError as e:
print("Conexión fallida. Reiniciando...")
time.sleep(5)
machine.reset()
# Funciones para controlar el módulo de relé
def activar_rele():
print("Activando bomba (relé encendido)...")
rele.value(0)
def desactivar_rele():
print("Desactivando bomba (relé apagado)...")
rele.value(1)
# Lógica principal
while True:
try:
# Leer mensajes del broker
conexionMQTT.check_msg()
# Leer sensor de luz
nivel_luz = sensor_luz.read()
# Comprobamos si la bomba está activada o no y lo mostramos en el dashboard
if bomba_activada:
time.sleep(10)
conexionMQTT.publish(topic_2,str(1))
else:
if not bomba_activada:
time.sleep(10)
conexionMQTT.publish(topic_2,str(0))
# Lógica para activar/desactivar la bomba según el umbral (en este caso 2000)
if not modo_emergencia:
if nivel_luz > umbral_luz:
if not bomba_activada and not ciclo_bomba:
print(f"Nivel de luz {nivel_luz} supera el umbral de {umbral_luz}. Activando bomba.")
activar_rele()
bomba_activada = True
ultima_activacion = time.localtime()
# Temporizador para apagar la bomba después de 20 segundos, o el tiempo que se quiere que dure el ciclo de encendido
if bomba_activada and ultima_activacion:
tiempo_actual = time.localtime()
# Calculamos la diferencia entre los minutos y segundos del tiempo actual y la última activación y así obtener el tiempo total (en segundos)
tiempo_activada = (tiempo_actual[4] - ultima_activacion[4]) * 60 + (tiempo_actual[5] - ultima_activacion[5])
if tiempo_activada >= 20 and not modo_emergencia:
print("Tiempo límite alcanzado. Apagando bomba.")
desactivar_rele()
bomba_activada = False
ciclo_bomba = True
# Temporizador para encender la bomba después de 30 segundos, o el tiempo que se quiere que dure el ciclo de apagado
if ciclo_bomba:
tiempo_actual_2 = time.localtime()
tiempo_activada_2 = (tiempo_actual_2[4] - ultima_activacion[4]) * 60 + (tiempo_actual_2[5] - ultima_activacion[5])
if tiempo_activada_2 >= 30 and not modo_emergencia:
print("Tiempo límite alcanzado. La bomba está óptima para volver a encender.")
ciclo_bomba = False
time.sleep(1)
except OSError as e:
print("Error:", e)
time.sleep(5)
machine.reset()Loading
esp32-c3-devkitm-1
esp32-c3-devkitm-1