from machine import Pin, ADC, SoftI2C
import time
import machine
import ssd1306
# ===========================
# INICIALIZAR OLED
# ===========================
i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
def oled_mostrar(l1="", l2="", l3="", l4=""):
oled.fill(0)
oled.text(l1, 0, 0)
oled.text(l2, 0, 15)
oled.text(l3, 0, 30)
oled.text(l4, 0, 45)
oled.show()
# ===========================
# PINES DE BOMBAS
# ===========================
PUMP_QUIMICO = Pin(23, Pin.OUT)
PUMP_AGUA = Pin(19, Pin.OUT)
PUMP_ASPER = Pin(15, Pin.OUT)
# ===========================
# BOTON DE EMERGENCIA
# ===========================
boton_emergencia = Pin(14, Pin.IN, Pin.PULL_UP)
def esperar_emergencia_ms(tiempo_ms):
inicio = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), inicio) < tiempo_ms:
if boton_emergencia.value() == 0:
oled_mostrar("EMERGENCIA!", "Reiniciando...")
time.sleep(0.5)
machine.reset()
time.sleep_ms(10)
# ===========================
# SENSOR ULTRASONICO
# ===========================
TRIG = Pin(5, Pin.OUT)
ECHO = Pin(18, Pin.IN)
def medir_distancia():
# Pulso de disparo
TRIG.off()
time.sleep_us(2)
TRIG.on()
time.sleep_us(10)
TRIG.off()
# Esperar inicio del pulso
start = time.ticks_us()
while ECHO.value() == 0:
if time.ticks_diff(time.ticks_us(), start) > 30000:
return 999
inicio = time.ticks_us()
# Esperar fin del pulso
stop = time.ticks_us()
while ECHO.value() == 1:
if time.ticks_diff(time.ticks_us(), stop) > 30000:
return 999
fin = time.ticks_us()
# Calculo distancia
duracion = time.ticks_diff(fin, inicio)
distancia = duracion / 58.0
return distancia
def esperar_objeto(umbral=50):
oled_mostrar("Esperando objeto")
time.sleep(1)
while True:
d = medir_distancia()
print("Distancia:", d)
if d == 999:
oled_mostrar("Esperando objeto", "Fuera de rango")
else:
oled_mostrar("Esperando objeto", f"Dist: {int(d)} cm")
if d < umbral:
oled_mostrar("OBJETO", "DETECTADO")
print("Objeto detectado")
time.sleep(1)
break
time.sleep(0.2)
# ===========================
# SENSOR DE PESO (ADC)
# ===========================
adc = ADC(Pin(34))
adc.atten(ADC.ATTN_11DB)
adc.width(ADC.WIDTH_12BIT)
def obtener_peso():
raw = adc.read()
peso = (raw / 4095) * 50
return peso
# ===========================
# ACTIVAR BOMBAS
# ===========================
def activar_bomba(pin, tiempo, nombre=""):
oled_mostrar("Activando:", nombre, f"{tiempo:.1f}s")
print(f"Activando {nombre} por {tiempo:.1f} s")
pin.on()
esperar_emergencia_ms(int(tiempo * 1000))
pin.off()
oled_mostrar(nombre, "Completado")
time.sleep(1)
# ===========================
# CALCULOS
# ===========================
def calcular_litros(peso):
if peso < 15:
return 5
elif peso < 30:
return 10
else:
return 20
def calcular_quimico(litros):
return litros * 2
def tiempo_bomba_quimico(ml):
caudal = 100
return (ml / caudal) * 60
# ===========================
# PROGRAMA PRINCIPAL
# ===========================
oled_mostrar("Sistema", "Aspersion ESP32")
time.sleep(1)
# Espera hasta detectar objeto
esperar_objeto(50)
# Medir peso
peso = obtener_peso()
litros = calcular_litros(peso)
ml = calcular_quimico(litros)
t_quimico = tiempo_bomba_quimico(ml)
oled_mostrar("Peso:", f"{peso:.1f} kg", "Mezcla:", f"{litros} L")
time.sleep(2)
# Proceso
activar_bomba(PUMP_QUIMICO, t_quimico, "Quimico")
activar_bomba(PUMP_AGUA, 25, "Agua")
activar_bomba(PUMP_ASPER, 30, "Aspersor")
oled_mostrar("Proceso", "Finalizado")
print("Sistema finalizado.")