import time,machine,micropython,network,neopixel,dht
from neopixel import NeoPixel
from machine import Pin,PWM,I2C
from umqtt.simple import MQTTClient
from time import sleep,sleep_ms
from lcd_i2c import LCD
#Indicamos red WIFI y clave
ssid = 'Wokwi-GUEST'
wifipassword = ''
#Datos Server MQTT (Broker)
#Indicamos datos MQTT Broker (server y puerto)
mqtt_server = 'io.adafruit.com'
port = 1883
user = 'joelrueda' #definido en adafruit
password = 'aio_ypOr55ZrhhoAsRiXhJvgZRkbbL9H' #key adafruit
#Indicamos ID(unico) y topicos
client_id = 'MiSensor'
topic_LEDTEMPERATURA = 'joelrueda/feeds/LedTemperatura'
topic_SENSOR = 'joelrueda/feeds/Sensor'
topic_Humedad = 'joelrueda/feeds/Humedad'
#Usamos una variable para definir si los sensores están activos.
sensorTempActivo =False
alarmaHumedadActiva = False
displayEstado = False
#Definimos modo Station (conectarse a Access Point remoto)
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
#Conectamos al wifi
sta_if.connect(ssid, wifipassword)
print("Conectando")
while not sta_if.isconnected():
print(".", end="")
sleep(0.1)
print("Conectado a Wifi!")
#Vemos cuales son las IP
print(sta_if.ifconfig())
#Antes de conectarnos al broker, vamos a definir una funcion que sera llamada cada vez que se produzca un publish sobre un topico donde estamos suscriptos
def callback_sensor(topic, msg):
global sensorTempActivo,alarmaHumedadActiva,displayEstado
#Cuando se ejecuta esta funcion quere decir que hubo un mensaje nuevo en algun topico, verificamos esto dado que lo que llega viene en UTF-8, lo decodificamos para que sea una cadena de texto regular
dato = msg.decode('utf-8')
topicrec = topic.decode('utf-8')
print("Cambio en: "+topicrec+":"+dato)
#Nos fijamos si es el topico esperado y el valor del dato
if topicrec == topic_SENSOR:
if "OFF" in dato:
sensorTempActivo = False
alarmaHumedadActiva = False
#Apago el Display
displayEstado = False
lcd.set_backlight(displayOFF)#=0
lcd.no_display()
else: #"ON"
sensorTempActivo = True
alarmaHumedadActiva = True
#Enciendo el Display
displayEstado = True
lcd.set_backlight(displayON)#=1
lcd.display()
#Intentamos conectarnos al broker MQTT
try:
conexionMQTT = MQTTClient(client_id, mqtt_server,user=user,password=password,port=int(port))
conexionMQTT.set_callback(callback_sensor)
conexionMQTT.connect()
conexionMQTT.subscribe(topic_SENSOR)
print("Conectado con Broker MQTT")
except OSError as e:
#Si fallo la conexion, reiniciamos todo
print("Fallo la conexion al Broker, reiniciando...")
sleep(5)
machine.reset()
#LED Variables
cantLeds = 16
npTemperatura = NeoPixel(Pin(2), cantLeds)
ledCalor = (255,0,0)
ledNormal = (0,255,0)
ledFrio = (0,0,255)
ledApagado = (0,0,0)
#Sensor de Humedad Variables
SensorDHT22 = dht.DHT22(Pin(14))
SensorDHT22.measure()
nuevaHumedad = SensorDHT22.humidity()
hume = SensorDHT22.humidity()
freqLow = 400
freqHigh = 550
#Sensor de temperatura Variables
alarma = PWM(Pin(5), freq=500, duty_u16=32768)
minT = -40 #Temperatura Minima
maxT = 80 #Temperatura Maxima
temp = SensorDHT22.temperature()
#Humedad y Temperatura ideales:
minTempNormal = 20
maxTempNormal = 28
limEstadosTemp= [[minT,minTempNormal-0.0001],[minTempNormal,maxTempNormal],[maxTempNormal+0.0001,maxT]]
# FRIO NORMAL CALOR
minHumNormal = 80
maxHumNormal = 95
limHumedad = [minHumNormal,maxHumNormal]
# LimInf LimSup
#Estados de la Temperatura
frio = 0
normal = 1
calor = 2
apagado = 3 #Para el Led
#Estados de la Humedad
humBaja = 0
humNormal = 1
humAlta = 2
#Display Variables
I2C_ADDR = 0x27 # DEC 39, HEX 0x27
i2c = I2C(0, scl=Pin(18), sda=Pin(19), freq=800000)
lcd = LCD(addr=I2C_ADDR, cols=20, rows=4, i2c=i2c)
#Estados del Display
displayON = 1
displayOFF = 0
limInf = 0 #Para acceder al
limSup = 1 #array limEstadosTemp y limHumedad
print("Comenzando monitoreo del sensor")
alarma.duty(0)
alarmaHumedadSonando = False
estActualTemp = apagado
estActualHum = apagado
lcd.begin()
lcd.set_backlight(displayOFF)
while True:
try:
#Tenemos que verificar si hay mensajes nuevos publicados por el broker
conexionMQTT.check_msg()
sleep_ms(1000)
#Actualizamos los valores del sensor
SensorDHT22.measure()
nuevaHumedad = SensorDHT22.humidity()
nuevaTemp = SensorDHT22.temperature()
#Si el sensor esta activo ...
#Temperatura:
if sensorTempActivo:
if nuevaTemp <= limEstadosTemp[frio][limSup] and estActualTemp != frio:
npTemperatura.fill(ledFrio)
conexionMQTT.publish(topic_LEDTEMPERATURA,str(frio))
estActualTemp = frio
elif limEstadosTemp[normal][limInf] <= nuevaTemp <= limEstadosTemp[normal][limSup] and estActualTemp != normal:
npTemperatura.fill(ledNormal)
conexionMQTT.publish(topic_LEDTEMPERATURA,str(normal))
estActualTemp = normal
elif limEstadosTemp[calor][limInf] <= nuevaTemp and estActualTemp != calor:
npTemperatura.fill(ledCalor)
conexionMQTT.publish(topic_LEDTEMPERATURA,str(calor))
estActualTemp = calor
else:
if estActualTemp != apagado:
npTemperatura.fill(ledApagado)
conexionMQTT.publish(topic_LEDTEMPERATURA,str(apagado))
estActualTemp = apagado
npTemperatura.write()
#Humedad:
if alarmaHumedadActiva:
if not alarmaHumedadSonando: #Alarma no suena
if nuevaHumedad < limHumedad[limInf] and estActualHum != humBaja:
alarma.duty(512)
alarma.freq(freqLow)
alarmaHumedadSonando = True
conexionMQTT.publish(topic_Humedad,str(humBaja))
estActualHum = humBaja
elif nuevaHumedad > limHumedad[limSup] and estActualHum != humAlta:
alarma.duty(512)
alarma.freq(freqHigh)
alarmaHumedadSonando = True
conexionMQTT.publish(topic_Humedad,str(humAlta))
estActualHum = humAlta
elif limHumedad[limInf] <= nuevaHumedad <= limHumedad[limSup] and estActualHum == apagado:
estActualHum = normal
conexionMQTT.publish(topic_Humedad,str(humNormal))
else: #Alarma suena
if limHumedad[limInf] <= nuevaHumedad <= limHumedad[limSup] and estActualHum != humNormal:
alarma.duty(0)
alarmaHumedadSonando = False
conexionMQTT.publish(topic_Humedad,str(humNormal))
estActualHum = normal
else:
if estActualHum != apagado:
if alarmaHumedadSonando:
alarma.duty(0)
alarmaHumedadSonando = False
conexionMQTT.publish(topic_Humedad,str(apagado))
estActualHum = apagado
#Display:
if displayEstado:
if nuevaHumedad != hume or nuevaTemp != temp:
lcd.clear()
else:
lcd.home()
lcd.print("Temperatura: {:.2f}".format(nuevaTemp))
lcd.set_cursor(col=0 ,row=1 )
lcd.print("Humedad: {:.2f}%".format(nuevaHumedad))
temp = nuevaTemp
hume = nuevaHumedad
except OSError as e:
print("Error ",e)
sleep(5)
machine.reset()