from machine import Pin, I2C,SPI
import ssd1306
import time
import random
import dht
import urequests #Para realizar request a un server
import network #Para conectar a internet
# ----- Internet -----
def send_data(data):
# Define la URL de tu servidor en PythonAnywhere
url = "https://shizadecaf.pythonanywhere.com/changedata"
# Envía el valores a través del request GET
params = "?param1="+data[0]+"¶m2="+data[1]
response = urequests.get(url + params)
# Verifica la respuesta
print("Respuesta del servidor:", response.text)
response.close()
return "ok"
# ----- SENSOR DE TEMPERATURA Y HUMEDAD -----
def init_temp():
d = dht.DHT22(Pin(23)) #Definimos un objeto DHT para recibir los datos del sensor, conectado al pin 23
return d
def get_temp(d):
d.measure() #ejecutamos esta función para obtener los datos del sensor y posteriormente retornarlos
return str(d.temperature()) , str(d.humidity()) #Retornamos tupla de temperatura y humedad, en formato string
# ----- LEDS -----
def init_leds(led_pins):
leds=[Pin(pin,Pin.OUT)for pin in led_pins]
return leds
def random_led(leds,timerr):
for i in range(0,32,1):
random_led_index= random.randint(0, len(leds)-1) #Escoge un led al azar dentro del rango de pines definidos
leds[random_led_index].off() #dicho led es encendido (los leds se encienden con off)
time.sleep(timerr) #se hace un retardo en segundos del valor time
leds[random_led_index].on() #el led se apaga
def serial_led(leds,timerr):
for led in leds:
led.off()
time.sleep(timerr)
led.on()
# ----- PANTALLA OLED -----
def init_oled():
i2c = I2C(1, scl=Pin(22), sda=Pin(21)) #Definimos el protocolo I2C como un objeto
oled_width = 128 #Definimos la resolución de la pantalla oled, ancho y alto
oled_height = 64 #La pantalla que tenemos disponible es de 128x64 pixeles
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c) #definimos la pantalla oled como un objeto de la clase ssd1306, recibe como parámetros las dimensiones de la pantalla y el protocólo i2c que previamente definimos.
return oled
def clear_screen(oled):
oled.fill(0)
oled.show() # Se actualiza el contenido de la pantalla oled con los cambios hechos en el buffer
def oled_text(oled,tex,x,y):
oled.text(tex, x, y) # Imprimimos un texto en las coordenadas x y
oled.show()
def oled_text_multiline(oled,lines,x,y,salto):
for line in lines: #recorremos todos los elemenos de la lista de lineas
oled.text(line, x, y) # e inmediatamente imprimimos dicha linea en las coordenadas definidas.
y += salto #tras cada linea impresa, hacemos un salto de linea (coordenada y) respecto al valor de distancia que definimos.
oled.show() #refrescamos la pantalla
# ----- SEVEN-SEGMENTS -----
def ini_max(): #Este método inicializa y controla un dispositivo conectado por el bus SPI, en este caso un display de 7 segmentos controlado por un decodificador MAX7219.
cs = Pin(15,Pin.OUT) #cs corresponde al chip select, conectado al pin GPIO 15 como salida digital para el dispositivo SPI.
"""
CS es el pin que permite seleccionar al dispositivo con el que el ESP32 va a comunicarse en el bus SPI.
Al poner CS en bajo (off), el dispositivo sabe que debe recibir comandos.
"""
hspi = SPI(1, 100000, sck=Pin(14), mosi=Pin(13), miso=Pin(12)) #Se inicializa el periférico SPI usando el segundo bus del mismo (1), se define 100,000 como la frecuencia en hz de transmisión de datos
#el pin GPIO 14 será usado para la señal SCK (reloj del bus SPI), el 13 será usado para la señal MOSI (Master Out Slave In), y el pin 12 para MISO (Master In Slave Out)
#aunque hemos definido el protocolo MISO, por esta ocasión no lo estaremos usando, ya que sólo mandamos señal desde la placa al display, no viceversa.
cs.off() #Baja la señal del pin CS, activando el dispositivo para que esté listo para recibir comandos.
hspi.write(b'\x09\xff') ## 1er decodificador
"""
Se envía el comando 0x09 al dispositivo SPI para configurar el modo de decodificación de los dígitos.
El valor 0xFF habilita la decodificación BCD (Binary-Coded Decimal) para todos los dígitos.
Este comando permite mostrar números en los displays de 7 segmentos usando un formato de decodificación (números del 0 al 9).
"""
cs.on() #sube la señal del pin CS, indicando al dispositivo que deje de escuchar los comandos.
cs.off()
hspi.write(b'\x0a\x01') ## brillo
"""
Se envía el comando 0x0A para ajustar el brillo del display.
El valor 0x01 indica un brillo muy bajo, ya que el valor máximo sería 0x0F.
"""
cs.on()
cs.off()
hspi.write(b'\x0b\x07') ## los 7 segmentos
"""
Se envía el comando 0x0B para definir el número de dígitos activos en el display de 7 segmentos.
El valor 0x07 indica que se están usando 8 dígitos (en un display típico de 8 dígitos, numerados de 0 a 7).
"""
cs.on()
cs.off()
hspi.write(b'\x0c\x01') ## modo normal
"""
Se envía el comando 0x0C para poner el dispositivo en modo normal (es decir, encender la pantalla).
El valor 0x01 activa el modo normal; el valor 0x00 sería para modo de apagado.
"""
cs.on()
cs.off()
hspi.write(b'\x0f\x00') ## test
"""
Se envía el comando 0x0F para desactivar el modo de prueba (test mode).
El valor 0x00 desactiva el modo de prueba; en cambio, 0x01 activaría el modo de prueba,
donde se encienden todos los segmentos del display para verificar que funcionan.
"""
cs.on()
cs.off()
#A continuación, se configuran los dígitos de cada display
hspi.write(b'\x01\x08') #Se muestra el número 8 en el display 01, 08 en hexadecimal, que también es 8 en decimal.
cs.on()
cs.off()
hspi.write(b'\x02\x07') #Se muestra el número 7 en el display 02
cs.on()
cs.off()
hspi.write(b'\x03\x06') #Se muestra el número 6 en el display 03
cs.on()
cs.off()
hspi.write(b'\x04\x05') #Se muestra el número 5 en el display 04
cs.on()
cs.off()
hspi.write(b'\x05\x04') #Se muestra el número 4 en el display 05
cs.on()
cs.off()
hspi.write(b'\x06\x03') #Se muestra el número 3 en el display 06
cs.on()
cs.off()
hspi.write(b'\x07\x02') #Se muestra el número 2 en el display 07
cs.on()
cs.off()
hspi.write(b'\x08\x01') #Se muestra el número 1 en el display 08
cs.on()
time.sleep(1) #Pausamos la ejecución un segundo
cs.off()
hspi.write(b'\x0f\x01') # regresamos el display al modo test, encendiendo todos los segmentos.
cs.on() #Dejamos de escuchar los comandos, finalizando la ejecución.
def ini_max_tecnm():
# Diccionario que mapea caracteres a segmentos de 7 segmentos (esto es solo un ejemplo)
char_map = { #Todo el abecedario y digitos numéricos
'C': 0x4E,
'E': 0x4F,
'S': 0x5B,
'A': 0x77,
'R': 0x46,
'-': 0x01,
'2': 0x6D,
'4': 0x33,
}
cs = Pin(15, Pin.OUT)
hspi = SPI(1, 100000, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
# Configuraciones iniciales del display
cs.off()
hspi.write(b'\x09\x00') # 0x00 corresponde al modo de NO decodificación (caracteres personalizados)
cs.on()
cs.off()
hspi.write(b'\x0a\x01') # Brillo bajo
cs.on()
cs.off()
hspi.write(b'\x0b\x07') # Los 8 dígitos del display
cs.on()
cs.off()
hspi.write(b'\x0c\x01') # Modo normal (encendido)
cs.on()
cs.off()
hspi.write(b'\x0f\x00') # Desactivar modo test
cs.on()
# Mostrar los caracteres de "TECNM-24"
text = reversed("CESAR-24") # Volteamos el texto para que se imprima en orden inverso.
for i, char in enumerate(text):
cs.off()
# Mapea el carácter a su representación en el display de 7 segmentos
char_code = char_map.get(char.upper(), 0x00) # Si el carácter no está en el mapa, muestra espacios en blanco
hspi.write(bytearray([i+1, char_code])) # Envía al display el carácter en la posición correcta
cs.on()
# Test de encendido de segmentos por 1 segundo
time.sleep(5)
cs.off()
hspi.write(b'\x0f\x01') # Modo test
cs.on()
# ----------- EJECUCION -----------
buzzer=Pin(2,Pin.OUT) #Establece en que pin está conectada la bocina. En este caso, en el pin 2. El OUT significa quem es un dispositivo de salida
buzzer.on() #Enciende la bocina, generando un pitido durante
time.sleep(0.2) # medio segundo
buzzer.off() # y pasado ese segundo, deja de sonar.
time.sleep(0.2)
# ----- inicializamos -----
d = init_temp()
oled = init_oled()
clear_screen(oled)
led_pins = [16,17,21,22,23,25,26,27]
leds = init_leds(led_pins)
# -- WIFI --
ssid = "Wokwi-GUEST"
password = ""
station = network.WLAN(network.STA_IF)
station.active(True)
try:
oled_text(oled,"Conectando ...",5,5)
station.connect(ssid, password)
# Esperar a que se conecte
for i in range(10): # Intenta por 10 ciclos
if station.isconnected():
break
time.sleep(1) # Esperar 1 segundo entre intentos
if not station.isconnected():
raise RuntimeError("No se pudo conectar a la red WiFi")
print("Conexión exitosa!", station.ifconfig())
except Exception as e:
print("Error al conectarse a WiFi:", e)
oled_text(oled,"No fue posible conectarse a internet.",5,5)
time.sleep(2)
clear_screen(oled)
# Aquí puedes agregar lógica adicional si falla la conexión
# como reiniciar el ESP32, etc.
# machine.reset() # Reinicia el ESP32
pass
# ----- CICLO -----
while True: #Este ciclo se repite de manera indefinida, en este caso, mientras el ESP32 esté encendido.
random_led(leds,0.5)
oled_text(oled,"Hello new world",5,5)
time.sleep(1) #pausamos la ejecución por un segundo
oled_text(oled,"All the boys and girls",10,15)
serial_led(leds,0.1)
time.sleep(1)
oled_text(oled,"I got some true stories to tell ",15,25)
time.sleep(2)
#ini_max() #Iniciamos el display 7 segmentos y mostramos números del 1 al 8
#ini_max_tecnm() #Imprimimos "TECNM-24" en el display. (hace falta testeo)
clear_screen(oled)
time.sleep(1)
temp = get_temp(d)
lines = [
"Temp: " +temp[0]+" C",
"Humd: " +temp[1]+"%"
] #definimos una lista para imprimir en la función oled multilinea, ajustamos la impresión de temperatura y humedad.
oled_text_multiline(oled,lines,0,30,10) #Imprimimos en contenido de la lista con la función multiline.
time.sleep(1)
tst = send_data(temp)
if station.isconnected():
if tst is "error":
clear_screen(oled)
oled_text(oled,"No se pudo enviar datos al server.",0,25)
time.sleep(2)
clear_screen(oled)
#La ejecución se repite de forma indefinida.