import machine
import dht
import time
from machine import I2C,Pin
from lcd_i2c import LCD
from umqtt.simple import MQTTClient
import network
I2C_ADDR = 0x27 # DEC 39, HEX 0x27
i2c = I2C(0, scl=Pin(27), sda=Pin(14), freq=800000)
lcd = LCD(addr=I2C_ADDR, cols=20, rows=4, i2c=i2c)
PinAlerta = Pin(22,Pin.OUT)
PinAlerta2 = Pin(23,Pin.OUT,Pin.PULL_UP)
PinAlerta2.value(0)
PinDir = Pin(2,Pin.OUT)
PinDir.value(1)
PinPaso = machine.Pin(0)
pwmPinPs = machine.PWM(PinPaso)
pwmPinPs.freq(10000) #no hace falta que este pero si no esta, inicia el programa con 1 paso trivialmente
pwmPinPs.duty(0)
ssid = 'Wokwi-GUEST'
wifipassword = ''
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect(ssid, wifipassword)
print("CONECTANDO")
while not sta_if.isconnected():
print(".",end="")
time.sleep(0.1)
print("CONECTADO A INTERNET")
print(sta_if.ifconfig())
mqtt_server = 'io.adafruit.com'
port = 1883
user = 'LucasLeonel04'
password = 'aio_aXHQ89rmmlVhb9PGHMsIZ485KxE3'
client_id = 'tmp.idem.test'
topic_1 = 'LucasLeonel04/feeds/EstadoTemperatura'
topic_2 = 'LucasLeonel04/feeds/Max_Umbral'
topic_3 = 'LucasLeonel04/feeds/MaxTemp'
topic_4 = 'LucasLeonel04/feeds/ModoManual'
topic_5 = 'LucasLeonel04/feeds/Temp_Manual'
topic_6 = 'LucasLeonel04/feeds/VisorVentilador'
topic_7 = 'LucasLeonel04/feeds/PadNumerico'
activador = Pin(5,Pin.IN,Pin.PULL_UP) #se definio el pin como Pull_Up por lo que sera 1 hasta que se lo precione
estadoact = 0 #indicador de estado actual del pulsador, para que solo registre un pulso al precionarlo
cont = 0 #contador de pulsos del boton
#temp_manual = 40 #se le asigna la temperatura manual controlada por el dashboard
modoc = 0 #activador modo cultivo, con 0=desactivado, con 1=activado
caract = '' #caracter recibido por el dashboard
cant_car = 0 #cantidad de caracteres recibidos desde el dashboard
car_rec = 0 #indicado para saber si se recibio un caracter nuevo, necesario para restablecer la variable que guarda el caracter recibido
conta = 1234 #Contraseña que se debe ingresar para iniciar el modo.
s_mc = 0 #detector de salida de modoc para actualizar display lcd
NADA = 0
EVENTO = 1
ESPERA = 2
def procesarentrada(estadoActual,valorpin):
#funcion importante para que solo se detecte un pulso
#con esto se evita, al poner un contador, que se tomen valores mientras el
#boton este pulsado, es decir, solo admite un pulso.
if estadoActual==NADA and valorpin==False:
#si se esta en estado cero (no se recibio nada)
#y se oprime el boton, pasa a estado: evento
return EVENTO
if estadoActual==EVENTO:
return ESPERA
if estadoActual==ESPERA and valorpin==False:
return ESPERA
return NADA
def controlent():
global estadoact, cont, modoc, manual_temp
time.sleep_ms(5)
estadoact = procesarentrada(estadoact,activador.value())
temp_manual = float(manual_temp)
if(estadoact==EVENTO):
cont = cont + 1
if(temp_manual == 40 and cont == 5):
print("Modo ingreso de cultivo")
modoc = 1
cont = 0
if(temp_manual != 40 and cont == 5):
cont = 0
def mostrariniciocult():
lcd.begin()
lcd.print("1-M.TEMP 2-M.HUMED")
lcd.set_cursor(col=0, row=1)
lcd.print("3-A.RIEG 4-Mod.VENT")
lcd.set_cursor(col=0, row=2)
lcd.print("5-MA.TEMP 6-MA.HUMED")
lcd.set_cursor(col=0, row=3)
lcd.print("7-Md.CONT 8-SALIR")
def consalarm(temp1, umbralt, alarmat, hum1, umbralh, alarmah):
if alarmat == 1:
if temp1 > umbralt:
PinAlerta.value(1)
time.sleep_ms(50)
PinAlerta.value(0)
if alarmah == 1:
if hum1 > umbralh:
PinAlerta2.value(1)
time.sleep_ms(50)
PinAlerta2.value(0)
if alarmat == 0:
PinAlerta.value(0)
if alarmah == 0:
PinAlerta2.value(0)
def cultacept():
global caract,freqvent,car_rec,conta,cant_car
temp1 = 0
tempant = 0 #temperatura anterior (para publicar)
temp1umbl = 0
tempalar = 0
hum1 = 0
hum1umbl = 0
humalar = 0
rep = 1
ret = 0 #bandera de retroceso para actualizacion de pantalla unica, solo en la vuelta
rieg = 0
catrotor = freqvent
contant = ''
rotant = 0 #velocidad anterior del rotor
print("INGRESO EXITOSO (INGRESAR # PARA SALIR)")
while caract != '#':
print("PANTALLA INICIO CON INDICACIONES DE CONFIGURACIONES: ")
if(ret == 0):
ret = 1
mostrariniciocult()
while rep!=0:
#se selecciona la opcion deseada y en los if, se muestra en pantalla, se indica boton de salida #
tempsens.measure()
temp1 = tempsens.temperature()
hum1 = tempsens.humidity()
consalarm(float(temp1), int(temp1umbl), int(tempalar), float(hum1), float(hum1umbl), int(humalar))
if caract == str(1):
tempsens.measure()
temp1 = tempsens.temperature()
#print("Haz a: "+str(temp1))
lcd.begin()
lcd.print("TEMPERATURA ACTUAL: ")
lcd.set_cursor(col=2, row=1)
lcd.print(str(temp1)+" C")
time.sleep(2)
mostrariniciocult()
caract = ''
elif caract == str(2):
tempsens.measure()
hum1 = tempsens.humidity()
lcd.begin()
lcd.print("HUMEDAD ACTUAL: ")
lcd.set_cursor(col=2, row=1)
lcd.print(str(hum1)+"%")
time.sleep(2)
mostrariniciocult()
caract = ''
elif caract == str(3):
rieg = not rieg
if rieg == 0:
lcd.begin()
lcd.print("REGADOR DESACTIVADO")
time.sleep(2)
if rieg == 1:
lcd.begin()
lcd.print("REGADOR ACTIVADO")
time.sleep(2)
mostrariniciocult()
caract = ''
elif caract == str(4):
lcd.begin()
lcd.print("ROTOR (PPS): "+str(catrotor))
lcd.set_cursor(col=1, row=1)
lcd.print("INGRESE VELOCIDAD: ")
lcd.set_cursor(col=4, row=2)
lcd.print("MAX 30000 PPS")
lcd.set_cursor(col=4, row=3)
lcd.print("# Para Aceptar")
antrotor = catrotor
catrotor = ''
caract = ''
while caract != '#' and caract != '*':
if car_rec == 1:
car_rec = 0
catrotor = str(catrotor) + str(caract)
try:
conexionMQTT.check_msg()
time.sleep_ms(500)
except OSError as e:
print("Error ",e)
time.sleep(3)
machine.reset()
if catrotor == '':
catrotor = antrotor
if int(catrotor) <= 30000 and int(catrotor) != 0:
pwmPinPs.freq(int(catrotor))
pwmPinPs.duty(1023)
if int(catrotor) == 0:
pwmPinPs.duty(0)
lcd.begin()
lcd.print("ROTOR (PPS): "+str(catrotor))
time.sleep(2)
mostrariniciocult()
caract = ''
elif caract == '5':
lcd.begin()
lcd.print("UMBRAL TEMP: "+str(temp1umbl)+" C")
if tempalar == 0:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: DESACT")
if tempalar == 1:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: ACT")
lcd.set_cursor(col=1, row=2)
lcd.print("INGRESE NUEVO UMB: ")
lcd.set_cursor(col=0, row=3)
lcd.print("# ACEPT - * AL: A/D")
caract = ''
umbtempant = 0
umbtempant = temp1umbl
temp1umbl = ''
while caract != '#' and caract != '*':
if car_rec == 1:
car_rec = 0
temp1umbl = str(temp1umbl) + str(caract)
try:
conexionMQTT.check_msg()
time.sleep_ms(500)
except OSError as e:
print("Error ",e)
time.sleep(3)
machine.reset()
if caract == '*':
tempalar = not tempalar
if caract == '*' or caract == '#':
caract = 0
if temp1umbl == '':
temp1umbl=umbtempant
auxtemp = int(temp1umbl)
if auxtemp>=(-40) and auxtemp<=(80):
lcd.begin()
lcd.print("UMBRAL TEMP: "+str(temp1umbl)+" C")
if tempalar == 0:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: DESACT")
if tempalar == 1:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: ACT")
if auxtemp<(-40) or auxtemp>(80):
temp1umbl = umbtempant
lcd.begin()
lcd.print("UMBRAL TEMP: "+str(temp1umbl)+" C")
if tempalar == 0:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: DESACT")
if tempalar == 1:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: ACT")
time.sleep(2)
mostrariniciocult()
caract = ''
elif caract == '6':
lcd.begin()
lcd.print("UMBRAL HUMED: "+str(hum1umbl)+"%")
if humalar == 0:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: DESACT")
if humalar == 1:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: ACT")
lcd.set_cursor(col=1, row=2)
lcd.print("INGRESE NUEVO UMB: ")
lcd.set_cursor(col=0, row=3)
lcd.print("# ACEPT - * AL: A/D")
caract = ''
umbhumant = 0
umbhumant = hum1umbl
hum1umbl = ''
while caract != '#' and caract != '*':
if car_rec == 1:
car_rec = 0
hum1umbl = str(hum1umbl) + str(caract)
try:
conexionMQTT.check_msg()
time.sleep_ms(500)
except OSError as e:
print("Error ",e)
time.sleep(3)
machine.reset()
if caract == '*':
humalar = not humalar
if caract == '*' or caract == '#':
caract = 0
if hum1umbl == '':
hum1umbl = umbhumant
auxhum = int(hum1umbl)
if auxhum>=(0) and auxhum<=(100):
lcd.begin()
lcd.print("UMBRAL HUMED: "+str(hum1umbl)+"%")
if humalar == 0:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: DESACT")
if humalar == 1:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: ACT")
if auxhum<(0) or auxhum>(100):
hum1umbl = umbhumant
lcd.begin()
lcd.print("UMBRAL HUMED: "+str(hum1umbl)+"%")
if humalar == 0:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: DESACT")
if humalar == 1:
lcd.set_cursor(col=2, row=1)
lcd.print("ALARMA: ACT")
time.sleep(2)
mostrariniciocult()
caract = ''
elif caract == '7':
print("CONTRA ANTERIOR: "+str(conta))
lcd.begin()
lcd.print("INGRESE NUEVA CLAVE")
lcd.set_cursor(col=2, row=1)
lcd.print("4 CARACT")
lcd.set_cursor(col=0, row=3)
lcd.print("# GUARDAR")
contant = str(conta)
conta = ''
caract = ''
cant_car = 0
while caract != '#' and caract != '*':
if car_rec == 1 and cant_car <= 4:
car_rec = 0
conta = str(conta) + str(caract)
try:
conexionMQTT.check_msg()
time.sleep_ms(500)
except OSError as e:
print("Error ",e)
time.sleep(3)
machine.reset()
print("CANTIDAD DE CARACTERES: "+str(cant_car))
if str(conta) == '':
conta = str(contant)
if cant_car < 5:
conta = str(contant)
lcd.begin()
lcd.print("CLAVE NUEVA: "+str(conta))
time.sleep(2)
mostrariniciocult()
caract = ''
elif caract == '8':
lcd.begin()
lcd.print("DESACTIVANDO MODO")
lcd.set_cursor(col=2, row=1)
lcd.print("......")
time.sleep(1)
rep=0
caract = '#'
ret = 0
try:
conexionMQTT.check_msg()
time.sleep_ms(200)
if float(rotant) != float(catrotor):
rotant = catrotor
conexionMQTT.publish(topic_6,str(catrotor))
if float(tempant) != float(temp1):
tempant = temp1
print("PUBLICADA TEMPERATURA")
conexionMQTT.publish(topic_1,str(temp1))
except OSError as e:
print("Fallo la conexion al Broker, Reiniciando....")
time.sleep(5)
machine.reset()
try:
conexionMQTT.check_msg()
time.sleep_ms(500)
except OSError as e:
print("Fallo la conexion al Broker, Reiniciando....")
time.sleep(5)
machine.reset()
def mod_C(active):
global modoc,caract,concatcad,car_rec,cant_car,conta,s_mc
if(modoc == 1):
lcd.begin()
lcd.print("MODO CULTIVO ACT")
lcd.set_cursor(col=1, row=1)
lcd.print("INGRESE CLAVE: ")
while modoc==1 and caract != '#':
time.sleep(1)
print("Cultivador Activado")
if car_rec == 1:
car_rec = 0
print("Caracter Recibido: "+str(caract))
concatcad = str(concatcad) + str(caract)
print("Cadena Concatenada: "+str(concatcad))
if cant_car == 4 and str(concatcad) == str(conta):
lcd.begin()
lcd.print("CLAVE")
lcd.set_cursor(col=1, row=1)
lcd.print("ACEPTADA")
print("CONTRASEÑA ACEPTADA")
time.sleep(1)
caract = ''
concatcad = ''
cultacept()
cant_car = 0
caract = '#'
s_mc = 1
if cant_car == 4 and str(concatcad) != str(conta):
lcd.begin()
lcd.print("CLAVE")
lcd.set_cursor(col=1, row=1)
lcd.print("INCORRECTA")
print("CONTRASEÑA INCORRECTA")
caract='#'
s_mc = 1 #indicador de actualizacion de pantalla luego de salir de modo c
try:
conexionMQTT.check_msg()
time.sleep_ms(500)
except OSError as e:
print("Fallo la conexion al Broker, Reiniciando....")
time.sleep(5)
machine.reset()
#LAS SIGUIENTES SENTENCIAS SE EJECUTAN SI SE SALEN DEL MODO CULTIVO (DEBIENDOSE RESTABLECER TODAS LAS VARIABLES):
modoc = 0 #si se sale del bucle de modo cultivo porque no se cumple la condicion del while
#que se limpien las variables activadoras del modo, asi no se vuelve a activar hasta que se cumpla la condicion de 5 pulsos en el boton.
caract = '' #se limpia el ultimo caracter recibido del topic a los efectos de que si se sale porque esa variable
#es #, se pueda volver a ejecutar el ciclo ya que ya no sera #
concatcad = '' #se limpia la contraseña tipeada previamente (para ingresar otra nueva y que no se concatene a la vieja)
cant_car = 0 #se limpia el contador de caracterese ingresados, a los efectos de que pueda validarse la contraseña nuevamente
umbralmax = 0
manual_mode = 0
manual_temp = 0
dutyvent = 0
freqvent = 0
def estadoled(temp2, umbral):
if temp2>=umbral:
PinAlerta.value(1)
PinAlerta2.value(1)
else:
PinAlerta.value(0)
PinAlerta2.value(0)
def detfeq(tempact):
global freqvent, ppm, dutyvent
if tempact > 70:
dutyvent = 1023
freqvent = 10000
if tempact >= 60 and tempact <= 70:
dutyvent = 1023
freqvent = 5000
if tempact >= 40 and tempact < 60:
dutyvent = 1023
freqvent = 3334
if tempact >= 0 and tempact < 40:
dutyvent = 1023
freqvent = 1667
if tempact < 0:
dutyvent = 1023
freqvent = 100
def funcion_callback(topic, msg):
dato = msg.decode('utf-8')
topicrec = topic.decode('utf-8')
print("Mensaje en Topico: "+topicrec+": "+dato)
#topicrec indica la direccion del topico, siendo una cadena de caracteres que indica la direccion de topicoç
#Esto es util porque la funcion callback recibe mensajes de cualquier topico configurado, comparandolo con
#otra cadena de texto es posible diferencia el topico de origen de la informacion.
if topicrec == topic_2:
global umbralmax
print("Aumenta el umbral")
umbralmax = dato
if topicrec == topic_4:
global manual_mode
manual_mode = dato
print("Modo de manejo (0 - Automatico. 1 - Manual): "+str(manual_mode))
if topicrec == topic_5 and manual_mode == str(1):
global manual_temp
manual_temp = dato
print("TemperaturaManual: "+str(manual_temp))
if topicrec == topic_7:
global caract,car_rec,cant_car
caract = dato
cant_car = cant_car + 1
car_rec = 1
try:
conexionMQTT = MQTTClient(client_id,mqtt_server,user=user,password=password,port=int(port))
conexionMQTT.set_callback(funcion_callback) #Funcion callback para recibir mensajes del broker
conexionMQTT.connect()
conexionMQTT.subscribe(topic_1) #se envia un dato
conexionMQTT.subscribe(topic_2) #se recibe un dato
conexionMQTT.subscribe(topic_3) #se envia un dato
conexionMQTT.subscribe(topic_4) #se recibe un dato
conexionMQTT.subscribe(topic_5) #se recibe un dato
conexionMQTT.subscribe(topic_6) #se envia un dato
conexionMQTT.subscribe(topic_7) #se recibe caracteres
print("Conectado con Broker MQTT")
except OSError as e:
print("Fallo la conexion al Broker, Reiniciando...")
time.sleep(3)
machine.reset()
tempsens = dht.DHT22(Pin(26))
tempant = 0
umbant = 0
maytemp = 0
mintemp = 0
tempsens.measure()
temp = tempsens.temperature()
if manual_mode != str(1):
temp = tempsens.temperature()
if manual_mode == str(1):
temp = float(manual_temp)
mintemp = temp
maytemp = temp
while True:
if manual_mode != str(1):
tempsens.measure()
temp = tempsens.temperature()
if manual_mode == str(1):
temp = float(manual_temp)
detfeq(temp)
pwmPinPs.freq(int(freqvent))
pwmPinPs.duty(int(dutyvent))
controlent()
mod_C(modoc)
print("TEMP="+str(temp))
print("Frecuencia Ventilador="+str(freqvent))
if tempant != temp or umbant != umbralmax or s_mc == 1:
s_mc = 0
umbant = umbralmax
lcd.begin()
lcd.print("Temperatura: "+str(temp)+" C")
lcd.set_cursor(col=1, row=1)
lcd.print("Maxima: "+str(umbralmax)+" C")
lcd.set_cursor(col=1, row=2)
lcd.print("Rotor (PPS): "+str(freqvent))
lcd.set_cursor(col=1, row=3)
lcd.print("Modo Temp: "+str(manual_mode))
try:
conexionMQTT.check_msg()
#print("Umbral maximo de temperatura: "+str(umbralmax))
estadoled(float(temp),float(umbralmax))
#print("Maxima Temperatura Alcanzada: "+str(maytemp))
#print("Minima Temperatura Alcanzada: "+str(mintemp))
if tempant != temp:
time.sleep(1)
conexionMQTT.publish(topic_1,str(temp))
conexionMQTT.publish(topic_6,str(freqvent))
tempant = temp
if tempant >= maytemp:
maytemp=tempant
conexionMQTT.publish(topic_3,str(maytemp))
if mintemp >= tempant:
mintemp = tempant
except OSError as e:
print("Error ",e)
time.sleep(3)
machine.reset()