import machine
from machine import Pin, PWM, ADC, Timer
from hcsr04 import HCSR04
import time
from utime import sleep
sliderComida = machine.ADC(1)
# configuraciones iniciales
lectura_inicial = 0
tiempo_a_transcurrir = 0
seg_max_Comida= 4
gr_max_Comida = 50
distancia_lleno = 0
tiempo_inicial = 0
intervalo_comida_hs = 0
intervalo_comida_min = 0
#preguntarle al usuario si quiere configurar un temporizador
usar_temporizador = str(input('Desea programar una hora para servir comida? SI/NO'))
if(usar_temporizador == 'si' or usar_temporizador == 'SI' or usar_temporizador=='Si'):
selec_tiempo=str(input('Ingrese H si quiere ingresar horas, M si quiere ingresar minutos o HM si quiere ingresar ambos:\n'))
if(selec_tiempo == 'H' or selec_tiempo == 'h'):
intervalo_comida_hs = int(input('Ingrese cada cuantas horas quiere servir la comida:\n'))
elif(selec_tiempo == 'm' or selec_tiempo == 'M'):
intervalo_comida_min = int(input('Ingrese cada cuantos minutos quiere servir la comida:\n'))
elif (selec_tiempo == 'HM' or selec_tiempo == 'Hm' or selec_tiempo=='hM' or selec_tiempo=='hm'):
intervalo_comida_hs = int(input('Ingrese cada cuantas horas quiere servir la comida:\n'))
intervalo_comida_min = int(input('Ingrese cada cuantos minutos quiere servir la comida:\n'))
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()
return distancia
print('Espere antes de llenar el depósito...')
time.sleep(0.5)
distancia_vacio_depo= leer_sensor(sensorDepo)
print('capacidad maxima:'+str(distancia_vacio_depo)+'cms')
print('Ya puede llenar el depósito')
time.sleep(5)
distancia_actual_depo = leer_sensor(sensorDepo)
print('Distancia actual: '+str(distancia_actual_depo)+'cms')
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 capacidad_depo():
distancia_actual_depo = leer_sensor(sensorDepo)
porcentaje_actual=(((distancia_vacio_depo)-distancia_actual_depo)/(distancia_vacio_depo))*100
print('EL dispenser está un'+str(porcentaje_actual)+'% lleno')
if(porcentaje_actual <= 100 and porcentaje_actual >= 50):
print("Hay suficiente comida")
elif(porcentaje_actual <50 and porcentaje_actual>=20):
print("Cuidado, podrías quedarte sin comida")
elif(porcentaje_actual < 20 and porcentaje_actual >0):
print("Te estás quedando sin comida! Llena antes de que tu mascota tenga hambre!")
elif(porcentaje_actual <= 0):
print("Te quedaste sin comida! Recarga el dispenser para que tu mascota no tenga hambre")
return porcentaje_actual
def calcular_tiempo_llenado(distancia, seg):
if distancia <= distancia_lleno:
return 0
# calcula el tiempo que falta si hay comida
else:
diferencia = distancia - distancia_lleno
tiempo_necesario = min(diferencia, seg)
print(f"Diferencia: {diferencia:.1f} cm -> Tiempo: {tiempo_necesario:.1f}s")
return tiempo_necesario
def rellenar_plato(seg, distancia):
distancia_actual = leer_sensor(sensorPorcion)
if distancia_actual > distancia:
tiempo_llenado = calcular_tiempo_llenado(distancia_actual, seg)
print(f"Rellenando plato por {tiempo_llenado:.1f} segundos...")
girar_servo(tiempo_llenado)
sleep(1)
nueva_distancia = leer_sensor(sensorPorcion)
print(f"Nivel después del rellenado: {nueva_distancia:.1f} cm")
elif distancia_actual == distancia_vacio:
tiempo_llenado = calcular_tiempo_llenado(distancia_vacio, seg)
print(f"Rellenando plato por {tiempo_llenado:.1f} segundos...")
girar_servo(tiempo_llenado)
sleep(1)
else:
print("El plato ya está lleno")
return True
def detectar_comida_por_distancia(sensor):
distancia = leer_sensor(sensor)
# Si la distancia es menor o igual a lo que consideramos "vacio", hay comida
if distancia < distancia_vacio:
print(f"Comida detectada por distancia: {distancia} cm")
return True
else:
print(f"No hay comida detectada. Distancia actual: {distancia} cm")
return False
def servir_faltante(tiempo, distancia):
hay_comida = detectar_comida_por_distancia(sensorPorcion)
distancia_ahora = leer_sensor(sensorPorcion)
print(f"Distancia actual: {distancia_ahora} cm")
if hay_comida:
print("Se detectó comida restante. Rellenando plato...")
rellenar_plato(tiempo, distancia)
elif distancia_ahora == distancia_vacio:
print("El plato está vacío, sirviendo porción completa...")
rellenar_plato(tiempo, distancia)
else:
print("Sirviendo porción completa...")
girar_servo(tiempo)
print("Sistema de alimentación iniciado")
estado_depo = capacidad_depo()
(input('Ingrese el plato vacio para calcular la distancia: '))
distancia_vacio = leer_sensor(sensorPorcion)
print(f"La distancia de vacío es de {distancia_vacio}cm")
(input('¿Cuánta comida desea colocar?')) #ingresar valor por slider
# Bucle principal
while True:
#define la porción la primera vez
lectura_comida = sliderComida.read() / 1000
estado_depo = capacidad_depo()
if estado_depo>0:
if lectura_comida != lectura_inicial and estado_depo>0:
lectura_inicial = lectura_comida
tiempo_a_transcurrir = (lectura_comida * seg_max_Comida ) / gr_max_Comida
girar_servo(tiempo_a_transcurrir)
time.sleep(tiempo_a_transcurrir)
distancia_lleno = leer_sensor(sensorPorcion)
print(f"Nivel después del rellenado: {distancia_lleno} cm")
estado_depo = capacidad_depo()
servirComida = str(input('Servir comida?:\n'))
while((servirComida == 'si' or servirComida == 'Si' or servirComida =='SI') and estado_depo>0):
if (servirComida == 'si' or servirComida == 'Si' or servirComida =='SI') and estado_depo>0:
servir_faltante(tiempo_a_transcurrir, distancia_lleno)
elif servirComida == 'no' or servirComida== 'NO' or servirComida == 'No' or estado_depo<0:
break
estado_depo = capacidad_depo()
servirComida = str(input('Servir comida?:\n'))
if (intervalo_comida_hs + intervalo_comida_min) != 0 and estado_depo>0:
time.sleep(36*intervalo_comida_hs + 6*intervalo_comida_min)
print("Hora de comer!")
servir_faltante(tiempo_a_transcurrir, distancia_lleno)
estado_depo = capacidad_depo()
elif estado_depo<=0:
print('El dispenser no tiene comida! Recargar para que continue con su funcionamiento')
estado_depo = capacidad_depo()
time.sleep(1)
sleep(1) # Esperar 1 segundo entre iteracionessensor deposito
sensor porcion