# Universidad Nacional de la Matanza
# Materia: Fundamentos de los Sistemas Embebidos
# Proyecto Final IoT - Luz Dinámica, Versión simil al ESP32-C3-12F
## Aclaración
# En el simulador utilizamos ESP-32-C3-mini-1, porque tiene la misma cantidad de pines que
# el ESP-32-C3-12F. Además, nos permitió tener una versión funcional en el simulador que físicamente
# con la posición de lso pines correctos de las placas que tenemos en el laboratorio.
# De esta manera, habiendo considerado las particularidades de cada componente,
# teniendo el modelo en el protoboard la implementación sobre HW es más sencilla.
### ESP32-C3-12F
## max voltage input allowed 3,3 v
# Se evita utilizar los pines del segundo bloque del ADC del ESP32-C3-12F, porque comparten un reloj interno utilizado para conectarse al internet por Wifi.
#### LDR
### MODELO: LIGHT-SENSOR MARCA: Duaitek
## Varía la tensión en función de la intensidad lumínica, siendo más tensión menos luz, y viceversa
## Datasheet:
## Opera en el rango de 3,3 V - 5 V
## Devuelve en el rango de 3,3 V - 5 V (en modo analogico) (Minimo 0 V, máximo Vcc, por lo tanto no afecta al chip porque ambos están siendo alimentados con 3,3V)
#### PIR
### MODELO: HC-SR501 MARCA: Generico
## Entiendo que, detecta movimiento utilizando infrarojo, y devuelve un valor de tension en high y uno en low
## Datasheet: https://www.alldatasheet.es/datasheet-pdf/pdf/1131987/ETC2/HC-SR501.html
## Opera en el rango de 4,5 V - 20 V
## Tensión en alto: 3.3 V (compatible con los pines del chip, no es necesario hacerle caer tension)
## Tensión en bajo: 0 V
## En Wokwi el valor en HIGH se retiene por 5s aunque ya no exista movimiento, en la pieza real se regula con unas perillas
from umqtt.simple import MQTTClient
from machine import ADC, PWM, Pin
import time
import network, ntptime
## Componentes (al lado de cada sentencia se encuentra el numero de pin que debería llevar
## en la placa ESP32-C3-12F si se conectan en el mismo punto)
LDR = ADC(3) # Pin 3 # Por defecto lee hasta 3,3 V
PIR = Pin(6, Pin.IN) # Pin 6
pinLedInterno = Pin(10, Pin.OUT) # Pin 18
pwmPin = PWM(pinLedInterno)
pwmPin.freq(50)
pwmPin.duty(0)
## WiFi
ssid = 'Wokwi-GUEST'
wifipassword = ''
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect(ssid, wifipassword)
while not sta_if.isconnected():
try:
print(".", end="")
time.sleep(1)
except:
print("Error al conectar a la red " + ssid)
exit()
print("Conectado a la red " + ssid)
ntptime.settime() # Obtener hora de la red
hora_actual = time.localtime()[3]
## Credenciales de adafruit
client_id = "LuzDinamica"
topic_PIR = "Matias_Lista/feeds/sensorpir"
topic_OnOff = "Matias_Lista/feeds/onoff"
topic_RangoHorario = "Matias_Lista/feeds/rangohorario"
mqtt_server = "io.adafruit.com"
port = 1883
user = "Matias_Lista"
password = "aio_VjOq75uDNPylwyt0eAjWdaoPHOKK"
forzado = 0
rango = [0]
last_sent_value = -1
def funcion_callback (topico, msg):
# Esta función es llamada con cada nuevo mensaje del servidor MQTT para procesarlo,
# recibe como parametros el topico de origen y el mensaje.
global forzado, rango
topico_rec = topico.decode("utf-8")
dato = msg.decode("utf-8")
if (topico_rec == topic_OnOff):
forzado = int(dato)
elif topico_rec == topic_RangoHorario:
rango = dato.split("-")
print(rango)
print("Recibido! \n Topico: " + topico.decode("utf-8") + " - Mensaje: " + msg.decode("utf-8"))
## Se intenta la conexión con adafruit
try:
conexionMQTT = MQTTClient(client_id, mqtt_server, user=user, password=password, port=port)
conexionMQTT.connect()
conexionMQTT.set_callback(funcion_callback)
conexionMQTT.subscribe(topic_OnOff)
conexionMQTT.subscribe(topic_RangoHorario)
print("Se creo la conexion con el servidor MQTT " + mqtt_server)
except OSError as e:
print("Error al crear la conexion con el servidor MQTT + " mqtt_server)
exit()
while True:
# Evitamos enviar información redundante
if (last_sent_value != str(PIR.value())):
last_sent_value = str(PIR.value())
conexionMQTT.publish(topic_PIR, str(PIR.value()))
valor = LDR.read()
brillo_porcentaje = ((valor - 32) / (4063 - 32) )# Función que relaciona el valor
# con el porcentaje de brillo objetivo
if (forzado == 1):
pwmPin.duty(1023)
else:
if(len(rango) < 2):
# la cantidad de elementos del rango es < 2,
# no hay rango, por lo tanto, tiene en cuenta el PIR
if (PIR.value()):
pwmPin.duty(int (1023 * brillo_porcentaje))
else:
pwmPin.duty(0)
else:
# Si hay un rango valido activo,
if ((hora_actual >= int(rango[0])) and (hora_actual < int(rango[1]))):
# Y la hora actual está dentro del rango...
pwmPin.duty(1023)
else:
# Si no estamos en el rango, comportamiento normal
if (PIR.value()):
pwmPin.duty(int (1023 * brillo_porcentaje))
else:
pwmPin.duty(0)
conexionMQTT.check_msg()
time.sleep_ms(500)
hora_actual = time.localtime()[3]