import machine
import ssd1306
from utime import sleep_ms, sleep_us
from machine import I2C, Pin, ADC, PWM, reset, Timer
import math
import bme280
"""
SENSORES
1-Temperatura, Humedad y Presión - BME280
2-Sensor de presencia - PIR
3-Sensor de Iluminación - LDR
ACTUADORES
1-Servo motor
2-Buzzer y LEDS
3-Motor 5Vcc
MÓDULOS
1. Matriz LED MAX7219
2. Módulo de 4 relevadores DE ESTADO SOLIDO
3. Sensor táctil
"""
# Configuracion de la comunicacion I2C
i2c = machine.I2C(scl=machine.Pin(21), sda=machine.Pin(22))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
#┌───── Configurar BME ─────┐
bme = bme280.BME280(i2c=i2c,adress=0x76)
#└────────────────────────────┘
#┌───── Configurar PIR ─────┐
pir_pin = Pin(27, Pin.IN)
#└────────────────────────────┘
#┌───── Configurar LDR ─────┐
ldr = ADC(Pin(33))
ldr.atten(ADC.ATTN_11DB)
#└────────────────────────────┘
#┌───── Configurar Motor ─────┐
pinMotor = Pin(4, Pin.OUT)
#└────────────────────────────┘
#┌───── Configurar Servo ─────┐
servo_angulos = [60, 90, 120]
servo_angulosstr = ["60 ", "90 ", "120"]
servo_angulo_idx = 0
# Crear un PWM para controlar el servo
servo_pin = Pin(5)
servo = PWM(servo_pin, freq=50)
servo.duty(0)
#└────────────────────────────┘
#┌───── Configurar LEDs ─────┐
pred = Pin(34, Pin.OUT)
pgre = Pin(35, Pin.OUT)
pblu = Pin(32, Pin.OUT)
#└────────────────────────────┘
#┌───── Configurar Touch ─────┐
ptouch = Pin(23, Pin.OUT)
#└────────────────────────────┘
#┌───── Configurar Matriz LED ─────┐
pmax = Pin(19, Pin.OUT)
#└────────────────────────────┘
#┌───── Configurar Rele ─────┐
prel = Pin(18, Pin.OUT)
#└────────────────────────────┘
#┌──── Valores Iniciales ────┐
temp_max = 50
hume_max = 75
pres_max = 1020
temp_min = 15
hume_min = 20
pres_min = 1013
#└────────────────────────────┘
b_mov = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP)
b_abajo = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP)
b_derecha = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_UP)
b_izquierda = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP)
A = ["Menu Principal: ","Sensores","Actuadores","Ajustes"]
B = ["Sensores: ", "Ambiente" ,"Iluminacion","Presencia"]
C = ["Actuadores", "Motor","Servo","LEDs"]
G = [A,B,C]
pantalla_actual = 0
pantalla_anterior = 0
buzzer_pin = machine.Pin(14, machine.Pin.OUT)
buzzer = machine.PWM(buzzer_pin)
buzzer.duty(0) # Apagar el buzzer inicialmente
# Función de callback para el botón "Arriba"
def callback_mov(pin):
# Hacer sonar el buzzer
buzzer.duty(512) # Ajusta el ciclo de trabajo para encender el buzzer
time.sleep(0.1) # Sonido durante 0.1 segundos
buzzer.duty(0) # Apaga el buzzer
def callback_sel(pin):
# Hacer sonar el buzzer
buzzer.duty(128) # Ajusta el ciclo de trabajo para encender el buzzer
time.sleep(0.1) # Sonido durante 0.1 segundos
buzzer.duty(0) # Apaga el buzzer
def callback_esc(pin):
# Hacer sonar el buzzer
buzzer.duty(64) # Ajusta el ciclo de trabajo para encender el buzzer
time.sleep(0.1) # Sonido durante 0.1 segundos
buzzer.duty(0) # Apaga el buzzer
# Configurar las interrupciones para los botones
b_arriba.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback_mov)
b_abajo.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback_mov)
b_derecha.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback_sel)
b_izquierda.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback_esc)
def oled_print(texto, x, y):
# Tamaño de un carácter (asumiendo 10x10 píxeles)
char_width = 10
char_height = 10
# Calcula las coordenadas en píxeles en función de las coordenadas en caracteres
x_pixels = x * char_width
y_pixels = y * char_height
# Borra solo la región donde se imprimirá el nuevo texto
for i in range(char_height):
for j in range(len(texto) * char_width):
oled.pixel(x_pixels + j, y_pixels + i, 0)
# Imprime el nuevo texto en la posición especificada
oled.text(texto, x_pixels, y_pixels)
# Actualiza la pantalla para mostrar el nuevo texto
oled.show()
def oled_clear():
oled.fill(0)
oled.show()
def fill_area(x_start,y_start,x_end,y_end,color):
for x in range(x_start, x_end + 1):
for y in range(y_start, y_end + 1):
oled.pixel(x, y, color)
sleep_us(1)
""" funciones """
# SENSOR BME ##############################################
def BME():
global temp, hume, pres, temp_max, temp_min, pres_max, pres_min, hume_max, hume_min
oled_clear()
oled_print("Sensor BME:",0,0)
oled_print("Temp:",1,1)
oled_print("Hume:",1,2)
oled_print("Pres:",1,3)
oled_print("°C",17,1)
oled_print("%",18,2)
oled_print("hPa",16,3)
while True:
temp = bme.read_temperature()/100
hume = bme.read_humidity()/1000
press = bme.read_pressure()/10000
temperature = "{:.1f}".format(temp) # Lee la temperatura
humidity = "{:.1f}".format(hume) # Lee la humedad
pressure = "{:.1f}".format(press) # Lee la presión
if temp > temp_max:
oled_print(str("MAX"),5,1)
elif temp < temp_min:
oled_print(str("MIN"),5,1)
else:
oled_print(str(temperature),5,1)
if hume > hume_max:
oled_print(str("MAX"),5,2)
elif hume < hume_min:
oled_print(str("MIN"),5,2)
else:
oled_print(str(humidity),5,2)
if press > pres_max:
oled_print(str("MAX"),5,3)
elif press < press_min:
oled_print(str("MIN"),5,3)
else:
oled_print(str(pressure),5,3)
if b_izquierda.value() == 0:
break
# SENSOR LDR #################################################
def LDR():
global pant, pact, sens, acts, ajs
oled_clear()
oled_print("Sensor LDR:",0,0)
oled_print("Iluminacion:",1,1)
oled_print("%",5,2)
while True:
voltage = ldr.read() / 4095 * 3.3 # 4095 es el valor máximo de lectura en ESP32 (12 bits)
porcentaje = 100 - ((voltage / 3.3) * 100)
porcentaje_formateado = "{:.1f}".format(porcentaje)
oled_print(porcentaje_formateado, 1, 2)
if b_izquierda.value() == 0:
break
# SENSOR PIR #################################################
def PIR():
global pant, pact, sens, acts, ajs
oled_clear()
oled_print("Sensor PIR",0,0)
while True:
if pir_pin.value() == 1:
oled_print("Mov. detectado ",1,1)
else:
oled_print("No hay movimiento ",1,1)
if b_izquierda.value() == 0:
break
# MOTOR 5V #################################################
def MOTOR():
#Pin del Motor ON
oled_clear()
mon = False
oled_print("Motor:",0,0)
oled_print("Estado:",1,1)
oled_print("OFF",10,1)
while True:
if js.is_button_pressed():
reset()
if b_derecha.value() == 0:
if mon:
pinMotor.off()
mon = False
oled_print("OFF",10,1)
else:
pinMotor.on()
mon = True
oled_print("ON ",10,1)
oled_print(">",0,1)
if b_izquierda.value() == 0:
break
# SERVOMOTOR #################################################
def SERVO():
global servo_angulo_idx, menu_servo
oled_clear()
oled_print("Servo", 0, 0)
while True:
oled_print(str(servo_angulosstr[servo_angulo_idx]), 1, 1)
oled_print("Grados", 5, 1)
if b_mov.value() == 0:
servo_angulo_idx = (servo_angulo_idx + 1) % len(servo_angulos)
Angulo = servo_angulos[servo_angulo_idx]
servo.duty(Angulo)
sleep_ms(200)
elif b_abajo.value() == 0:
servo_angulo_idx = (servo_angulo_idx - 1) % len(servo_angulos)
Angulo = servo_angulos[servo_angulo_idx]
servo.duty(Angulo)
sleep_ms(200)
if b_izquierda.value() == 0:
servo.duty(0)
break
# LEDS #################################################
def LEDS():
posicion = 1
ron = False
gon = False
bon = False
print("actuadores, LED")
oled_clear()
oled_print("LED RGB:",0,0)
oled_print("Rojo:",1,1)
oled_print("Verde:",1,2)
oled_print("Azul:",1,3)
for i in range (3):
oled_print("OFF",10,i+1)
while True:
if b_mov.value() == 0:
posicion = posicion-1
if posicion < 1:
posicion = 1
elif b_abajo.value() == 0:
posicion = posicion+1
if posicion > 3:
posicion = 3
if b_derecha.value() == 0:
if posicion == 1:
if ron:
pred.off()
ron = False
oled_print("OFF",10,1)
else:
pred.on()
ron = True
oled_print("ON ",10,1)
elif posicion == 2:
if gon:
pgre.off()
gon = False
oled_print("OFF",10,2)
else:
pgre.on()
gon = True
oled_print("ON ",10,2)
elif posicion == 3:
if bon:
pblu.off()
bon = False
oled_print("OFF",10,3)
else:
pblu.on()
bon = True
oled_print("ON ",10,3)
for i in range(3):
oled_print(" ",0,i+1)
oled_print(">",0,posicion)
if b_izquierda.value() == 0:
break
# AJUSTES #################################################
def ajustes_parametros():
global temp_max, temp_min, hume_max, hume_min, pres_max,pres_min
parametros = {
"Temperatura": {"unit": "°C", "min": temp_min, "max": temp_max},
"Humedad": {"unit": "%", "min": hume_min, "max": hume_max},
"Presion": {"unit": "Hpa", "min": pres_min, "max": pres_max}
}
oled_clear()
oled_print("Ajustes de Valores:", 0, 0)
while True:
if js.is_button_pressed():
reset()
for param_name, param_info in parametros.items():
while True:
oled_print(f"{param_name} ", 1, 1)
oled_print(f"Min: {param_info['min']}", 1, 2)
oled_print(f"Max: {param_info['max']}", 1, 3)
oled_print(param_info['unit'], 10, 4)
sleep_ms(200)
fill_area(0, 10, 10, 40, 0)
oled_print(">", 0, 2)
if b_mov.value() == 0:
param_info['min'] += 1
elif b_abajo.value() == 0:
param_info['min'] -= 1
if b_izquierda.value() == 0:
print("X:" + str(js.read_x()))
break
if b_derecha.value() == 0:
continue#####################
while True:
oled_print(f"{param_name} ", 1, 1)
oled_print(f"Min: {param_info['min']}", 1, 2)
oled_print(f"Max: {param_info['max']}", 1, 3)
oled_print(param_info['unit'], 10, 4)
sleep_ms(200)
fill_area(0, 10, 10, 40, 0)
oled_print(">", 0, 3)
if b_mov.value() == 0:
param_info['max'] += 1
elif b_abajo.value() == 0:
param_info['max'] -= 1
if b_izquierda.value() == 0:
print("X:" + str(js.read_x()))
break
if b_derecha.value() == 0:
continue#####################
# Actualiza las variables con los valores del diccionario
temp_min = parametros["Temperatura"]["min"]
temp_max = parametros["Temperatura"]["max"]
hume_min = parametros["Humedad"]["min"]
hume_max = parametros["Humedad"]["max"]
pres_min = parametros["Presion"]["min"]
pres_max = parametros["Presion"]["max"]
# Devuelve el diccionario actualizado de parámetros
return parametros
#---------------------------------------------------------#
###########################################################
""" fin de funciones """
#MAIN
while True:
posicion = 1
if pantalla_actual == 0:
oled_clear()
oled_print(A[0],0,0)
for i in range (3):
oled_print(A[i+1],1,(i+1))
elif pantalla_actual == 1:
oled_clear()
oled_print(B[0],0,0)
for i in range (3):
oled_print(B[i+1],1,(i+1))
elif pantalla_actual == 2:
BME()
elif pantalla_actual == 3:
LDR()
elif pantalla_actual == 4:
PIR()
elif pantalla_actual == 5:
oled_clear()
oled_print(C[0],0,0)
for i in range (3):
oled_print(C[i+1],1,(i+1))
elif pantalla_actual == 6:
MOTOR()
elif pantalla_actual == 7:
SERVO()
elif pantalla_actual == 8:
LEDS()
elif pantalla_actual == 9:
nuevos_parametros = ajustes_parametros()
sleep_ms(30)
#CURSOR
while True:
# Llenar la región específica con color (0)
fill_area(0, 10, 10, 40, 0)
sleep_ms(30)
oled_print(">",0,posicion)
if b_mov.value() == 0:
print("Arriba")
posicion = max(1, posicion - 1)
elif b_abajo.value() == 0:
print("Abajo")
posicion = min(3, posicion + 1)
if b_derecha.value() == 0: #Adelante
print("Seleccionado")
if pantalla_actual == 0 and posicion == 1: #Si estas en menu Principal
pantalla_actual = 1
break
elif pantalla_actual == 0 and posicion == 2:
pantalla_actual = 5
break
elif pantalla_actual == 0 and posicion == 3:
pantalla_actual = 9
break
elif pantalla_actual == 1 and posicion == 1: #Si estas en Sensores
pantalla_actual = 2
break
elif pantalla_actual == 1 and posicion == 2:
pantalla_actual = 3
break
elif pantalla_actual == 1 and posicion == 3:
pantalla_actual = 4
break
elif pantalla_actual == 5 and posicion == 1: #Si estas en Actuadores
pantalla_actual = 6
break
elif pantalla_actual == 5 and posicion == 2:
pantalla_actual = 7
break
elif pantalla_actual == 5 and posicion == 3:
pantalla_actual = 8
break
elif b_izquierda.value() == 0: #Atrás
print("Escape")
if pantalla_actual == 0:
pantalla_actual = 0
break
elif pantalla_actual == 1 or pantalla_actual == 5 or pantalla_actual == 9:
pantalla_actual = 0
break
elif pantalla_actual == 2 or pantalla_actual == 3 or pantalla_actual == 4:
pantalla_actual = 1
break
elif pantalla_actual == 6 or pantalla_actual == 7 or pantalla_actual == 8:
pantalla_actual = 5
break