import network
import time
from machine import Pin, ADC
import dht
import ubinascii # Para mostrar MAC legible
# --- PINES ---
led = Pin(2, Pin.OUT) # LED integrado en ESP32 (alerta general)
sensor = dht.DHT22(Pin(4)) # Sensor DHT22 en GPIO 4
soil_adc = ADC(Pin(34)) # Potenciómetro simula humedad del suelo
soil_adc.atten(ADC.ATTN_11DB) # Rango 0–3.3V
# --- RELÉS ---
relay_bomba = Pin(26, Pin.OUT) # Relé para bomba de agua
relay_fan = Pin(27, Pin.OUT) # Relé para ventilador
# --- SENSOR MQ-2 ---
mq2 = ADC(Pin(35))
mq2.atten(ADC.ATTN_11DB) # Rango 0–3.3V
MQ2_THRESHOLD = 60 # Umbral de gas en porcentaje
# --- RANGOS RECOMENDADOS ---
TEMP_MIN = 5
TEMP_MAX = 35
HUM_MIN = 40
HUM_MAX = 80
SOIL_MIN = 30
SOIL_MAX = 70
# --- CONEXIÓN WiFi ---
print("Conectando a WiFi...", end="")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('Wokwi-GUEST', '')
timeout = 10
start = time.time()
while not sta_if.isconnected():
time.sleep(0.1)
print(".", end="")
if time.time() - start > timeout:
print("\n⚠️ No se pudo conectar a WiFi (simulado)")
break
if sta_if.isconnected():
print("\n✅ Conectado a WiFi (simulado)")
ip, subnet, gateway, dns = sta_if.ifconfig()
print("Dirección IP:", ip)
print("Máscara de subred:", subnet)
print("Gateway:", gateway)
print("DNS:", dns)
print("SSID:", sta_if.config('essid'))
mac_bytes = sta_if.config('mac')
print("MAC:", ubinascii.hexlify(mac_bytes, ':').decode())
print("Intensidad señal (RSSI):", sta_if.status('rssi'), "dBm")
else:
print("⚠️ No hay conexión de red")
# --- CONTADOR PARA SIMULAR HORA ---
start_time = time.time()
# --- FUNCIONES ---
def read_soil():
"""Convierte la lectura analógica (0–4095) en % de humedad."""
value = soil_adc.read()
return round((1 - (value / 4095)) * 100, 1) # 0 seco, 100 mojado
def read_mq2():
"""Convierte la lectura analógica del MQ-2 en %"""
value = mq2.read()
return round((value / 4095) * 100, 1)
# --- LOOP PRINCIPAL ---
try:
while True:
# Reintentar lectura del DHT22 3 veces
for _ in range(3):
try:
sensor.measure()
temp = sensor.temperature()
hum = sensor.humidity()
break
except OSError:
time.sleep(1)
else:
print("⚠️ No se pudo leer el DHT22 después de 3 intentos")
temp = None
hum = None
# Leer humedad del suelo y MQ-2
soil = read_soil()
gas = read_mq2()
# Simulación de hora tipo NTP
elapsed = int(time.time() - start_time)
h = elapsed // 3600
m = (elapsed % 3600) // 60
s = elapsed % 60
hora = "{:02d}:{:02d}:{:02d}".format(h, m, s)
# Mostrar valores
if temp is not None and hum is not None:
print("[{}] Temp: {:.1f}°C Hum: {:.1f}% Soil: {}% Gas: {}%".format(
hora, temp, hum, soil, gas
))
fuera_rango = False
# Verificar temperatura
if temp < TEMP_MIN or temp > TEMP_MAX:
print("⚠️ Temperatura fuera de rango!")
fuera_rango = True
# Verificar humedad aire
if hum < HUM_MIN or hum > HUM_MAX:
print("⚠️ Humedad del aire fuera de rango!")
fuera_rango = True
# Verificar humedad suelo
if soil < SOIL_MIN or soil > SOIL_MAX:
print("⚠️ Humedad del suelo fuera de rango!")
fuera_rango = True
# Verificar gas
if gas > MQ2_THRESHOLD:
print("⚠️ Gas detectado en exceso! 💨")
fuera_rango = True
# --- Control de relés ---
# Bomba de agua
if soil < SOIL_MIN:
relay_bomba.value(1)
print("💧 Bomba ACTIVADA (riego)")
else:
relay_bomba.value(0)
# Ventilador (por temperatura o gas)
if temp > TEMP_MAX or gas > MQ2_THRESHOLD:
relay_fan.value(1)
if temp > TEMP_MAX:
print("🌬️ Ventilador ACTIVADO (temperatura alta)")
if gas > MQ2_THRESHOLD:
print("🌬️ Ventilador ACTIVADO (gas detectado en exceso)")
else:
relay_fan.value(0)
# LED de alerta general
led.value(1 if fuera_rango else 0)
else:
# Apagar todo si no hay lectura
led.value(0)
relay_bomba.value(0)
relay_fan.value(0)
time.sleep(5)
except KeyboardInterrupt:
print("Programa detenido por usuario")
led.value(0)
relay_bomba.value(0)
relay_fan.value(0)