from machine import Pin, I2C, PWM, time_pulse_us
import dht
import ujson
import time
import ssd1306
# Definición de pines
emergencia = Pin(2, Pin.IN, Pin.PULL_DOWN)
RiegoDesactivado = Pin(13, Pin.OUT)
RiegoActivado = Pin(12, Pin.OUT)
warmLed = Pin(14, Pin.OUT)
# Bombas de agua
bomba1 = Pin(16, Pin.OUT)
bomba2 = Pin(17, Pin.OUT)
# Sensor de nivel digital (Seguridad de llenado)
sensor_nivel = Pin(18, Pin.IN)
# Válvula de llenado del tanque
valvula = Pin(27, Pin.OUT)
# Interruptor para modo manual/automático
modo = Pin(19, Pin.IN, Pin.PULL_DOWN)
# Botones para activar manualmente las bombas
boton_bomba1 = Pin(5, Pin.IN, Pin.PULL_DOWN)
boton_bomba2 = Pin(4, Pin.IN, Pin.PULL_DOWN)
# Asignación de pines para OLED
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# Configuración del sensor DHT22
sensor = dht.DHT22(Pin(15))
# Configuración del servo en el pin 23
servo = PWM(Pin(23))
servo.freq(50)
# Definir salida para modo automático en el pin 26
modo_automatico_salida = Pin(26, Pin.OUT)
# Configuración del sensor ultrasónico HC-SR04
TRIG = Pin(32, Pin.OUT)
ECHO = Pin(33, Pin.IN)
def mover_servo(angulo):
"""Convierte el ángulo en el duty cycle correcto para el servo."""
duty = int((angulo / 180) * 2000 + 500)
servo.duty_u16(duty)
def medir_distancia():
"""Mide la distancia del agua usando un sensor ultrasónico."""
TRIG.off()
time.sleep_us(2)
TRIG.on()
time.sleep_us(10)
TRIG.off()
duracion = time_pulse_us(ECHO, 1)
distancia = (duracion / 2) / 29.1
return distancia
def calcular_nivel(distancia):
"""Convierte la distancia del sensor ultrasónico en porcentaje de llenado."""
nivel_porcentaje = ((400 - distancia) / (400 - 2)) * 100
return max(0, min(100, nivel_porcentaje))
while True:
sensor.measure()
temperatura = sensor.temperature()
humedad = sensor.humidity()
estado_modo = modo.value()
distancia_nivel = medir_distancia()
nivel_porcentaje = calcular_nivel(distancia_nivel)
tanque_lleno = sensor_nivel.value() == 1 # Seguridad de llenado
# 🛑 PARO DE EMERGENCIA: APAGAR TODO
if emergencia.value() == 1:
print("🛑 EMERGENCIA ACTIVADA: APAGANDO TODO")
RiegoActivado.off()
RiegoDesactivado.on()
warmLed.off()
bomba1.off()
bomba2.off()
valvula.off()
mover_servo(0)
# 📢 Mensaje en la pantalla OLED
oled.fill(0)
oled.text("🚨 EMERGENCIA ACTIVADA", 10, 25)
oled.text("🔴 SISTEMA APAGADO", 10, 40)
oled.show()
continue # Salta el resto del código y sigue verificando la emergencia
if estado_modo == 0:
modo_automatico_salida.on()
else:
modo_automatico_salida.on()
time.sleep(0.001)
modo_automatico_salida.off()
time.sleep(0.005)
message = ujson.dumps({
"modo": "Manual" if estado_modo == 1 else "Automático",
"temp": temperatura,
"humidity": humedad,
"nivel": nivel_porcentaje
})
print(message)
# 🌡️ Control del riego según temperatura
if temperatura < 15:
RiegoActivado.off()
RiegoDesactivado.on()
print("🌿 Riego desactivado por baja temperatura")
else:
RiegoActivado.on()
RiegoDesactivado.off()
print("💦 RIEGO ACTIVADO")
if estado_modo == 0:
if temperatura > 35:
warmLed.on()
mover_servo(180)
elif temperatura > 40:
print("🚨 TEMPERATURA EXTREMADAMENTE ALTA")
else:
warmLed.off()
mover_servo(0)
if nivel_porcentaje < 20 and not tanque_lleno:
bomba1.on()
mover_servo(0)
time.sleep(5)
if nivel_porcentaje < 10:
bomba2.on()
else:
bomba1.off()
bomba2.off()
if tanque_lleno:
print("🚰 Seguridad: Tanque lleno, bombas detenidas")
# 🚰 Control de la válvula de llenado (50% activa, 80% desactiva)
if nivel_porcentaje <= 50:
valvula.on()
print("💧 Válvula activada: llenando el tanque")
elif nivel_porcentaje >= 80:
valvula.off()
print("🔴 Válvula desactivada: tanque suficiente")
# 🚫 Seguridad: Si el tanque está por debajo del 10%, las bombas no encienden
if nivel_porcentaje < 10:
bomba1.off()
bomba2.off()
print("⚠️ ALERTA: Tanque por debajo del 10%, bombas apagadas")
# 🖐️ MODO MANUAL: Encender bombas con botones
if estado_modo == 1:
print("🔧 MODO MANUAL ACTIVADO")
if boton_bomba1.value() == 1:
bomba1.on()
print("🚰 BOMBA 1 ACTIVADA MANUALMENTE")
else:
bomba1.off()
if boton_bomba2.value() == 1:
bomba2.on()
print("🚰 BOMBA 2 ACTIVADA MANUALMENTE")
else:
bomba2.off()
# 📢 Aviso en la pantalla OLED cuando el riego está activado
oled.fill(0)
oled.text(f"Modo: {'Manual' if estado_modo == 1 else 'Automático'}", 10, 10)
oled.text(f"Temp: {temperatura}C", 10, 25)
oled.text(f"Humedad: {humedad}%", 10, 40)
oled.text(f"Tanque: {nivel_porcentaje:.1f}%", 10, 55)
if RiegoActivado.value() == 1:
oled.text("💦 RIEGO ACTIVADO", 10, 40)
oled.show()
time.sleep(3)