# Poryeto: SISTEMA DE INVERNADERO INTELIGENTE
#Estudiante: Elizabeth Brenes Sanabria
#=================LIBRERIAS=========================
from time import sleep, sleep_us, ticks_us, ticks_diff #Libreria para controlar los tiempos
from machine import Pin, ADC, time_pulse_us, I2C #Libreria para manejar los pines GPIO
from i2c_lcd import I2cLcd #libreria para utilizar la pantalla LCD
import dht #Libreria para el uso del sensor DHT22
from servo import Servo #Libreria para usar el Servo motor
import neopixel #Libreria parausar el aro de luz
from temperatura import temperatura # Importa la clase Temperatura desde el archivo temperatura.py
temp = temperatura() # Se crea un objeto
from invernadero import invernadero # invernadero Importa la clase invernadero desde el archivo invernadero.py
ventana = invernadero() # Se crea un objeto
#===========CREACIÓN DE LAS INSTANCIAS=============
sensor_temperatura = dht.DHT22(Pin(4)) #Instancia del sensor DHT, temperatura
sensor_luz = ADC(Pin(35)) #LUZ
sensor_luz.width(ADC.WIDTH_12BIT) #LUZ
sensor_luz.atten(ADC.ATTN_11DB) #Lee los valores, LUZ
trigger = Pin(5, Pin.OUT) #Sensor ultrasonico
echo = Pin(18, Pin.IN) #Sensor ultrasonico
sensor_potenciometro = ADC(Pin(34)) # sensor potenciometro
sensor_potenciometro.width(ADC.WIDTH_12BIT) # sensor potenciometro
sensor_potenciometro.atten(ADC.ATTN_11DB) # sensor potenciometro
boton = Pin(15, Pin.IN) #Instancia del pin para el boton
servo_pin = Pin(19) #Instancia de un pin para el servo motor
my_servo = Servo(servo_pin) #Instancia del objeto servo motor
pin_neopixel = Pin(21, Pin.OUT) # Aro NeoPixel RGB
aro_rgb = neopixel.NeoPixel(pin_neopixel,16) # Aro NeoPixel RGB
i2c = I2C(0, scl=Pin(22), sda=Pin(23), freq=400000) # Iniciación de los pines de la pantalla
lcd = I2cLcd(i2c, 0x27, 2, 16) #Se crea la instancia de la pantalla
sensor_actual = 0 #Variable para el botón
#===========FUNCIONES======================
def leer_temperatura(): # Esta función lleva la logica es decir la que piensa y toma decisiones
sensor_temperatura.measure() #Le indica al sensor que mida la temperatura
temperatura = sensor_temperatura.temperature() #Se obtiene el valor de la temperatura y despues se guarda en una variable
if temperatura >= 30: #Condicional que toma la decisión, Temperatura alta
actualizar_neopixel((180,0,255)) #Morado
mostrar_lcd ("Temp: " + str(temperatura) + "C", temp.mensaje_alta())
print("ALERTA: Temperatura alta.")
print("Abra la ventana para ventilar el invernadero.")
sleep (3)
# AQUI SE PONE LA LOGICA DE LA VENTANA
# Mientras la temperatura siga alta, revisar la Ventana
while True:
estado = estado_ventana() # Devuelve: 0 % CERRADA, 50% ABIERTA o 100% ABIERTA
if estado == "100% ABIERTA":
sleep(2) # Deja visible "VENTANA 100% ABIERTA"
actualizar_neopixel((0,0,255)) # Azul
mostrar_lcd("Temp: " + str(temperatura) + "C", temp.mensaje_normal())
sleep(2)
break
sleep(0.2)
elif temperatura <= 15: #Temperatura muy baja
actualizar_neopixel((255,255,255)) #BLANCO
mostrar_lcd ("Temp: " + str(temperatura) + "C", temp.mensaje_baja())
else: # Temperatura normal
actualizar_neopixel((0,0,255)) #Azul
mostrar_lcd ("Temp: " + str(temperatura) + "C", temp.mensaje_normal())
def leer_luz(): # Esta es la que lleva la logica es la que toma la desición
valor = sensor_luz.read() #Lee los Valores del sensor de la Luz
print("ADC:", valor) #imprime el valor
porcentaje = int((valor * 100) / 4095) # Se convierte la lectura de la luz a valores que comprenda el usuario
print("Porcentaje:", porcentaje) #
if valor < 1600:
actualizar_neopixel((0,0,0)) # Negro
mostrar_lcd("LUZ BAJA", str(porcentaje) + "%")
elif valor < 1800:
actualizar_neopixel((255,255,0)) # Amarillo
mostrar_lcd("LUZ NORMAL" , str(porcentaje) + "%")
else:
actualizar_neopixel((255,120,0)) # Naranja intenso
mostrar_lcd("LUZ MUY ALTA", str(porcentaje) + "%")
def leer_nivel_agua():
# Esta función solo lee el sensor ultrasónico para medir si el tanque esta lleno o bacido
trigger.value(0) #Aquí se pone el pin Trigger en estado 0 lógico.
sleep_us(2) # Espera 2 microsegundos
trigger.value (1)# Se pone el trigger en 1 es decir encendido, el sensor recibe la orden y envia una onda ultrasonica
sleep_us(10) # Se necesita un minimo para activarse, se deja encendido en 10 microsegundos
trigger.value(0) # se apaga el trigger
#Esperar el eco
tiempo = time_pulse_us(echo, 1) # Medir cuánto tiempo está en estado HIGH (1)"
# Se convierte el tiempo del eco en distancia (centímetros)
distancia = (tiempo * 0.0343) / 2 # Se convierte el tiempo en distancia
# Se muestra la distancia
print("Nivel de agua:", distancia, "cm")
return distancia
def estado_ventana():
valor = sensor_potenciometro.read()
porcentaje = int((valor * 100)/ 4095)
if porcentaje < 30:
mostrar_lcd("VENTANA", ventana.ventana_cerrada())
return "0% CERRADA"
elif porcentaje < 70:
mostrar_lcd( "VENTANA", ventana.ventana_media())
return "50% ABIERTA"
else:
mostrar_lcd( "VENTANA", ventana.ventana_abierta())
return "100% ABIERTA"
def leer_boton():
global sensor_actual # Se modifica la variable del sensor actual
if boton.value() == 0: # Si el botón fue presionado, pasa a leer el siguiente sensor
sensor_actual += 1
if sensor_actual > 2: # Cuando llegue al sensor 3 vuelve al inicio
sensor_actual = 0 # Vuelve a empezar desde la temperatura
while boton.value() == 0:
pass
def controlar_riego(): # Esta función lleva la lógica del riego
sensor_temperatura.measure() # Actualiza la lectura del DHT22
humedad = sensor_temperatura.humidity() # Obtiene la humedad relativa del ambiente
distancia = leer_nivel_agua()
# Primero revisamos la humedad del Ambiente
if humedad < 40:
print("Humedad baja")
# Ahora revisamos si hay agua en el tanque
if distancia < 300:
print("Hay agua disponible")
print("Activo riego")
my_servo.write_angle(180)
actualizar_neopixel((0,255,0)) #Se activa el led Verde indicando que esta encendido
mostrar_lcd("RIEGO", "ACTIVADO")
sleep(3)
else:
print("Tanque vacío")
print("No se puede regar")
print("POR FAVOR LLENAR TANQUE DE AGUA")
my_servo.write_angle(0)
actualizar_neopixel((255,0,0)) # Se activa el led rojo indicando advertencia o llene el tanque
mostrar_lcd("TANQUE", "VACIO")
else:
print("Humedad adecuada")
print("No se requiere activar el riego")
my_servo.write_angle(0)
actualizar_neopixel((0,0,0)) #Se activa el led negro indicando que no se requiere agua
mostrar_lcd("SUELO", "HUMEDO")
sleep(3)
def actualizar_neopixel(color): #Parametro de la función actualizar_neopixel
aro_rgb.fill(color) # Aquí el aro recibe ese color. Es decir se le indica quiero todos los leds de este mismo color seria, el valor del parametro
aro_rgb.write() # Envía la orden al aro
def mostrar_lcd(linea1, linea2): # Recibe los textos que se mostrarán en la LCD
lcd.clear() # Borrar completamente la pantalla.
lcd.putstr(linea1) # Muestra el texto en la primera línea.
lcd.move_to(0,1) # Mueve el cursor al inicio de la segunda línea.
lcd.putstr(linea2) # Muestra el texto en la segunda línea.
#===========PROGRAMA PRINCIPAL======================
while True:
leer_boton()
if sensor_actual == 0:
leer_temperatura()
elif sensor_actual == 1:
leer_luz()
elif sensor_actual == 2:
controlar_riego()
sleep(0.2)