import machine
from machine import Pin, PWM, ADC
from hcsr04 import HCSR04
import time
from utime import sleep
potenciometro = machine.ADC(0)
lectura_potenciometro = potenciometro.read()
# configuraciones iniciales
tiempo_a_transcurrir = 5
altura_maxima = int(input('Ingrese la profundidad maxima del recipiente')) # altura máxima del plato en cm
distancia_lleno = lectura_potenciometro/100
distancia_min_depo = 2
print(str(distancia_lleno))
# Variable para almacenar la porción seleccionada
porcion_seleccionada = "grande" # Por defecto grande
boton0 = Pin(10, Pin.IN, Pin.PULL_UP)
boton1 = Pin(1, Pin.IN, Pin.PULL_UP)
boton2 = Pin(3, Pin.IN, Pin.PULL_UP)
servo_pin = machine.PWM(machine.Pin(2))
servo_pin.freq(50)
sensorPorcion = HCSR04(trigger_pin=5, echo_pin=4)
sensorDepo = HCSR04(trigger_pin=8, echo_pin=7)
def leer_sensor(sensor):
distancia = sensor.distance_cm()
print(f"Distancia sensor: {distancia} cm")
return distancia
def servo(degrees):
# Checkear si el ángulo buscado está dentro del rango de trabajo
if degrees > 180:
degrees = 180
if degrees < 0:
degrees = 0
# Valores min y max del duty cycle
maxDuty = 9000
minDuty = 1000
# Fórmula para pasar de grados a PWM/duty cycle
newDuty = minDuty + (maxDuty - minDuty) * (degrees / 180)
# Pasar el valor de duty al servo
servo_pin.duty_u16(int(newDuty))
def girar_servo(tiempo_espera):
# Girar hacia abajo (180 grados)
for degree in range(90, 181, 1):
servo(degree)
sleep(0.01)
# Esperar el tiempo especificado
sleep(tiempo_espera)
# Regresar a posición inicial
for degree in range(180, 85, -1):
servo(degree)
sleep(0.01)
print("Válvula cerrada")
def calcular_tiempo_llenado(distancia_actual, porcion):
# Definir la distancia objetivo según la porción
if porcion == "chica":
distancia_objetivo = distancia_lleno*1.5 # 2cm (más lejos del sensor)
print('Distancia objetivo: '+str(distancia_objetivo)+'cms')
seg = 1
elif porcion == "mediana":
distancia_objetivo = distancia_lleno*1.25 # 3cm
print('Distancia objetivo: '+str(distancia_objetivo)+'cms')
seg = 2
else: # grande
distancia_objetivo = distancia_lleno # 4cm
print('Distancia objetivo: '+str(distancia_objetivo)+'cms')
seg = 3
if distancia_actual <= distancia_objetivo:
return 0 # ya está lleno
# calcular cuanto falta para llegar a la distancia objetivo
diferencia = distancia_actual - distancia_objetivo
tiempo_necesario = min(diferencia, seg) # Máximo según la porción
return tiempo_necesario
def estado_dispenser():
distancia_actual_depo=leer_sensor(sensorDepo)
if distancia_actual_depo == distancia_min_depo:
print("El deposito está lleno")
elif distancia_actual_depo > distancia_min_depo:
print("El deposito necesita comida")
def rellenar_plato(porcion):
distancia_actual = leer_sensor(sensorPorcion)
# Determinar si necesita llenado según la porción
necesita_llenado = False
if porcion == "chica" and distancia_actual > (distancia_lleno*1.5):
necesita_llenado = True
elif porcion == "mediana" and distancia_actual > (distancia_lleno*1.25):
necesita_llenado = True
elif porcion == "grande" and distancia_actual > distancia_lleno:
necesita_llenado = True
if necesita_llenado:
tiempo_llenado = calcular_tiempo_llenado(distancia_actual, porcion)
print(f"Rellenando plato por {tiempo_llenado} segundos...")
girar_servo(tiempo_llenado)
sleep(1)
nueva_distancia = leer_sensor(sensorPorcion)
print(f"Nivel después del rellenado: {nueva_distancia} cm")
else:
print(f"El plato ya está lleno para la porción {porcion}")
def detectar_comida_por_distancia():
distancia_lleno = lectura_potenciometro
distancia = leer_sensor(sensorPorcion)
# Si la distancia es menor o igual a lo que consideramos "lleno", hay comida
if distancia <= distancia_lleno:
print(f"Comida detectada por distancia: {distancia} cm")
return True
else:
print(f"No hay comida detectada. Distancia actual: {distancia} cm")
return False
# Estados iniciales de los botones
ultimo_estado_boton0 = boton0.value()
ultimo_estado_boton1 = boton1.value()
ultimo_estado_boton2 = boton2.value()
print("Sistema de alimentación iniciado")
print(f"Estados iniciales - Botón 0: {boton0.value()}, Botón 1: {boton1.value()}, Botón 2: {boton2.value()}")
# Bucle principal
while True:
# Verificar si es hora de servir comida
if tiempo_a_transcurrir <= 0:
print("¡Hora de servir comida!")
hay_comida = detectar_comida_por_distancia()
distancia_actual = leer_sensor(sensorPorcion)
if hay_comida:
print("Se detectó comida restante. Rellenando plato...")
rellenar_plato(porcion_seleccionada)
else:
print("Sirviendo porción completa...")
# Servir según la porción seleccionada
if porcion_seleccionada == "chica":
girar_servo(1)
elif porcion_seleccionada == "mediana":
girar_servo(2)
else: # grande
girar_servo(3)
# Reiniciar el contador (simular próxima hora de comida)
tiempo_a_transcurrir = 5
# Leer estados actuales de los botones
estado_actual_boton0 = boton0.value()
estado_actual_boton1 = boton1.value()
estado_actual_boton2 = boton2.value()
# Porción chica
if estado_actual_boton0 != ultimo_estado_boton0:
if estado_actual_boton0 == 0: # Botón presionado
print("Porción chica seleccionada")
porcion_seleccionada = "chica"
girar_servo(3) # 1 segundo de espera
# Porción mediana
if estado_actual_boton1 != ultimo_estado_boton1:
if estado_actual_boton1 == 0: # Botón presionado
print("Porción mediana seleccionada")
porcion_seleccionada = "mediana"
girar_servo(4) # 2 segundos de espera
# Porción grande
if estado_actual_boton2 != ultimo_estado_boton2:
if estado_actual_boton2 == 0: # Botón presionado
print("Porción grande seleccionada")
porcion_seleccionada = "grande"
girar_servo(5) # 3 segundos de espera
# Actualizar estados de los botones
ultimo_estado_boton0 = estado_actual_boton0
ultimo_estado_boton1 = estado_actual_boton1
ultimo_estado_boton2 = estado_actual_boton2
tiempo_a_transcurrir -= 1
sleep(1) # Esperar 1 segundo entre iteracionesporción pequeña
porción mediana
porción grande