# Proyecto 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.
Como implementación extra vamos a usar un reloj de tiempo real con el módulo
RTC del DS1307 con la interfaz de I2C
"""
# Bibliotecas
import time
import machine
from machine import Pin, ADC
#from machine import RTC
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
rele = Pin(7, Pin.OUT) # Control del módulo de relé
rele.value(0)
# 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 (falta implementar el registro)
# 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...")
machine.reset() # No reinicia la simulación que era lo que se quería así que podríamos sacar esto
print("\n¡Conexión exitosa!")
print("Direcciones IP:")
print(sta_if.ifconfig())
# Sincronización con NTP
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/bombanormal'
# 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.")
# 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: # Reinicio en caso de fallo
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(1)
def desactivar_rele():
print("Desactivando bomba (relé apagado)...")
rele.value(0)
# Lógica principal
while True:
try:
# Leer mensajes del broker
conexionMQTT.check_msg()
# Leer sensor de luz
nivel_luz = sensor_luz.read()
# Lógica para activar/desactivar la bomba según el umbral (en este caso 2000)
if not modo_emergencia:
if nivel_luz > umbral_luz: # Si el nivel de luz supera el umbral
if not bomba_activada:
print(f"Nivel de luz {nivel_luz} supera el umbral de {umbral_luz}. Activando bomba.")
activar_rele()
bomba_activada = True
ultima_activacion = time.localtime()
else: # Si el nivel de luz está por debajo del umbral
if bomba_activada:
print(f"Nivel de luz {nivel_luz} está por debajo del umbral de {umbral_luz}. Apagando bomba.")
desactivar_rele()
bomba_activada = False
# Temporizador para apagar la bomba después de 3600 segundos, lo que equivale a una hora
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 >= 3600:
print("Tiempo límite alcanzado. Apagando bomba.")
desactivar_rele()
bomba_activada = False
time.sleep(1)
except OSError as e:
print("Error:", e)
time.sleep(5)
machine.reset()