# ======================== IMPORTS ESP32 ============================
from machine import Pin, SoftI2C
from time import sleep, ticks_ms, ticks_diff
import dht
import network
import urequests
import ujson
# ======================== CONFIG WiFi ==============================
WIFI_SSID = "CATARI NET"
WIFI_PASSWORD = "Catari_12345"
GOOGLE_SCRIPT_URL = "https://script.google.com/macros/s/AKfycbyqwJgAKeTXb4Gex9KMDMhLrSWcwH_VEHlFmA5Aq-Do6WtGp7_bps2_AQHtyqL5YBLx/exec"
# ============= CONFIGURACIÓN DE PINES (ESP32) ======================
LCD_SDA = Pin(19) # I2C SDA
LCD_SCL = Pin(18) # I2C SCL
DHTPIN = Pin(4) # DHT11
RELE_CALENTADOR = Pin(27, Pin.OUT)
RELE_VENTILADOR = Pin(23, Pin.OUT) # ⚠ Nuevo ventilador
LED_EMERGENCIA = Pin(26, Pin.OUT)
BOTON_ENCENDIDO = Pin(12, Pin.IN, Pin.PULL_UP)
LED_ROJO = Pin(22, Pin.OUT) # Sistema apagado
LED_VERDE = Pin(21, Pin.OUT) # Sistema encendido
# ================= RANGOS DE TEMPERATURA ==========================
TEMP_MIN = 22.0
TEMP_MAX = 25.0
VENTILADOR_UMBRAL = 27.0 # ⚠ Nuevo umbral de ventilador
AJUSTE_TEMP = 0
# ================= CONFIG LCD I2C ================================
I2C_ADDR = 0x27
I2C_ROWS = 2
I2C_COLS = 16
i2c = SoftI2C(sda=LCD_SDA, scl=LCD_SCL, freq=400000)
# === Cargar librerías LCD (igual que tu versión Pico) ===============
try:
from lcd_api import LcdApi
from i2c_lcd import I2cLcd
lcd = I2cLcd(i2c, I2C_ADDR, I2C_ROWS, I2C_COLS)
except ImportError:
class I2cLcd:
def __init__(self, i2c, addr, rows, cols):
self.i2c = i2c
self.addr = addr
self.rows = rows
self.cols = cols
self.clear()
def clear(self):
self.i2c.writeto(self.addr, b'\x01')
sleep(0.1)
def putstr(self, text):
self.i2c.writeto(self.addr, text.encode())
def move_to(self, col, row):
addr = 0x80 + (0x40 * row) + col
self.i2c.writeto(self.addr, bytes([addr]))
lcd = I2cLcd(i2c, I2C_ADDR, I2C_ROWS, I2C_COLS)
# ================= SENSOR DHT11 ===============================
dht_sensor = dht.DHT11(DHTPIN)
# ================ VARIABLES DEL SISTEMA =====================
temperatura = 0.0
humedad = 0.0
sistema_encendido = False
emergencia_temperatura = False
estado_temp = "Estable"
ultimo_tiempo_boton = 0
DEBOUNCE_DELAY = 200
# ================= INTERUPCIÓN BOTÓN ========================
def handle_button_interrupt(pin):
global sistema_encendido, ultimo_tiempo_boton
t = ticks_ms()
if ticks_diff(t, ultimo_tiempo_boton) > DEBOUNCE_DELAY:
sistema_encendido = not sistema_encendido
LED_ROJO.value(not sistema_encendido)
LED_VERDE.value(sistema_encendido)
if not sistema_encendido:
RELE_CALENTADOR.off()
RELE_VENTILADOR.off()
LED_EMERGENCIA.off()
ultimo_tiempo_boton = t
BOTON_ENCENDIDO.irq(trigger=Pin.IRQ_FALLING, handler=handle_button_interrupt)
# ================= MENSAJE INICIAL ==========================
def mostrar_mensaje_inicial():
lcd.clear()
lcd.putstr("IG Company")
lcd.move_to(0, 1)
lcd.putstr("Camara Curado")
sleep(2)
lcd.clear()
lcd.putstr("Temp:22-25C")
sleep(2)
# ================= LEER DHT11 ===============================
def leer_sensor_dht():
global temperatura, humedad
try:
dht_sensor.measure()
t = dht_sensor.temperature()
h = dht_sensor.humidity()
if t is None or h is None:
return False
temperatura = t + AJUSTE_TEMP
humedad = h
print("Temp:", temperatura, "Hum:", humedad)
return True
except:
print("Error DHT")
return False
# ================= CONTROLAR TEMPERATURA ====================
def controlar_temperatura():
global emergencia_temperatura, estado_temp
if temperatura < TEMP_MIN:
emergencia_temperatura = True
estado_temp = "Baja"
elif temperatura > TEMP_MAX:
emergencia_temperatura = True
estado_temp = "Alta"
else:
emergencia_temperatura = False
estado_temp = "Estable"
# ================= ACTUALIZAR LCD ===========================
def actualizar_pantalla():
lcd.clear()
lcd.putstr(f"Sist:{'ON' if sistema_encendido else 'OFF'}")
lcd.move_to(0, 1)
if sistema_encendido:
lcd.putstr(f"T:{temperatura:.1f}C H:{humedad:.1f}%")
else:
lcd.putstr("Presione BOTON")
# ================= WIFI ESP32 ===============================
def conectar_wifi():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print("Conectando WiFi...")
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
for _ in range(15):
if wlan.isconnected():
break
sleep(1)
if wlan.isconnected():
print("WIFI OK:", wlan.ifconfig())
return True
else:
print("Error WiFi")
return False
# ========== ENVIAR DATOS GOOGLE SHEETS =======================
def enviar_datos_google():
if not conectar_wifi():
return False
estado_excel = "BAJA" if estado_temp=="Baja" else "ALTA" if estado_temp=="Alta" else "ESTABLE"
datos = {
"temperatura": temperatura,
"humedad": humedad,
"estado": estado_excel,
"calefactor": "ON" if RELE_CALENTADOR.value() else "OFF",
"ventilador": "ON" if RELE_VENTILADOR.value() else "OFF"
}
try:
r = urequests.post(GOOGLE_SCRIPT_URL, json=datos)
r.close()
print("Datos enviados:", datos)
return True
except Exception as e:
print("Error enviando:", e)
return False
# ================= INICIALIZACIÓN ============================
RELE_CALENTADOR.off()
RELE_VENTILADOR.off()
LED_EMERGENCIA.off()
LED_ROJO.on()
LED_VERDE.off()
mostrar_mensaje_inicial()
ultimo_envio = 0
INTERVALO_ENVIO = 60000 # 60s
# ================= BUCLE PRINCIPAL ==========================
while True:
if sistema_encendido:
if leer_sensor_dht():
controlar_temperatura()
# --- calefactor ---
RELE_CALENTADOR.value(temperatura < TEMP_MIN)
# --- emergencia ---
LED_EMERGENCIA.value(emergencia_temperatura)
# --- ventilador nuevo ---
RELE_VENTILADOR.value(temperatura > VENTILADOR_UMBRAL)
# --- envío a Google ---
ahora = ticks_ms()
if ticks_diff(ahora, ultimo_envio) >= INTERVALO_ENVIO:
enviar_datos_google()
ultimo_envio = ahora
actualizar_pantalla()
sleep(2)