Tabla de contenido:

Bomba de máquina de café inteligente controlada por sensor ultrasónico Raspberry Pi y HC-SR04 y Cloud4RPi: 6 pasos
Bomba de máquina de café inteligente controlada por sensor ultrasónico Raspberry Pi y HC-SR04 y Cloud4RPi: 6 pasos

Video: Bomba de máquina de café inteligente controlada por sensor ultrasónico Raspberry Pi y HC-SR04 y Cloud4RPi: 6 pasos

Video: Bomba de máquina de café inteligente controlada por sensor ultrasónico Raspberry Pi y HC-SR04 y Cloud4RPi: 6 pasos
Video: ✅ El más usado en Robótica para controlar Motores DC, Motores de Pasos, Driver L298N Puente H 2024, Mes de julio
Anonim
Bomba de máquina de café inteligente controlada por sensor ultrasónico Raspberry Pi y HC-SR04 y Cloud4RPi
Bomba de máquina de café inteligente controlada por sensor ultrasónico Raspberry Pi y HC-SR04 y Cloud4RPi

En teoría, cada vez que vas a la máquina de café por tu taza de la mañana, solo hay una probabilidad entre veinte de que tengas que llenar el tanque de agua. En la práctica, sin embargo, parece que la máquina de alguna manera encuentra una manera de siempre imponerle esta tarea. Cuanto más desee café, más probabilidades tendrá de recibir el temido mensaje de "llenar el tanque de agua". Mis colegas sienten lo mismo al respecto. Siendo los nerds que somos, decidimos implementar la tecnología que pondría fin a esto.

Suministros

Nuestro equipo

Disponemos de una cafetera SAECO Aulika Focus. Hasta el día de hoy, usamos una bomba manual para llenar el tanque de agua de la máquina con una botella de agua estándar de 5 galones (19L).

Nuestras metas

  1. Utilice una bomba eléctrica accionada por algún tipo de controlador o una microcomputadora a través de un relé.
  2. Tenga una forma de medir el nivel de agua en el tanque de la máquina de café para que nuestro sistema sepa cuándo volver a llenarlo.
  3. Disponer de medios para controlar el sistema, preferiblemente en tiempo real desde un dispositivo móvil.
  4. Reciba notificaciones (a través de Slack o un servicio similar) si algo sale mal con el sistema.

Paso 1: elección del equipo

Elección del equipo
Elección del equipo
Elección del equipo
Elección del equipo
Elección del equipo
Elección del equipo
Elección del equipo
Elección del equipo

La bomba

Una búsqueda rápida en la web mostrará varios modelos de bombas eléctricas diseñadas para la botella de agua que elijas. Estas bombas generalmente se controlan mediante un interruptor de ENCENDIDO / APAGADO (por ejemplo, Hot Frost A12 o SMixx ХL-D2). Aquí está la bomba que elegimos para nuestro proyecto.

El dispositivo controlador

Probamos varios dispositivos, pero nos decidimos por una Raspberry Pi debido a las siguientes ventajas:

  • Tiene un GPIO que nos permite conectar un sensor de proximidad
  • Es compatible con Python

Instalamos una nueva versión de Raspbian Buster Lite y todo lo necesario para ejecutar Python 3.

Cómo cambiamos la bomba

Para controlar la potencia, elegimos un relé de estado sólido de potencia media (12V / 2A) adecuado para corriente alterna. El relé conecta la bomba a la toma de corriente y es controlado por el pin digital de la Raspberry Pi.

Cómo verificamos el nivel del agua

Para nosotros era importante no alterar la construcción de la máquina de café, por lo que decidimos utilizar el sensor de proximidad ultrasónico HC-SR04 para medir el nivel del agua.

Imprimimos en 3D una tapa de tanque de agua personalizada con dos orificios para los emisores del sensor. Encontramos fácilmente una biblioteca de GitHub para el sensor. En este punto, todos los preparativos estaban terminados.

Paso 2: diseñar el sistema

Diseñando el Sistema
Diseñando el Sistema
Diseñando el Sistema
Diseñando el Sistema

Lógica del sistema

El sistema está diseñado con la siguiente lógica simple en mente:

  • El sistema monitorea constantemente la distancia entre el sensor y la superficie del agua.
  • Siempre que un cambio en la distancia supera un valor umbral, el sistema envía información sobre su estado a la nube.
  • Si la distancia supera el valor máximo permitido (el tanque está vacío), el sistema activa la bomba y la apaga una vez que la distancia es menor que el valor mínimo permitido.
  • Siempre que cambia el estado del sistema (por ejemplo, la bomba se activa), informa a la nube.

En caso de error, se envía una notificación a un canal de Slack.

Cuando la máquina de café está inactiva, el sistema hace ping al servicio en la nube con datos de diagnóstico una vez por minuto. Además, envía su estado a la nube cada 5 minutos.

Cuando la bomba está activa, el sistema envía datos con más frecuencia, pero no más de una vez cada medio segundo.

def enviar (nube, variables, dist, error_code = 0, force = False): pump_on = is_pump_on () percent = calc_water_level_percent (dist) variables ['Distance'] ['value'] = dist variables ['WaterLevel'] [' valor '] = porcentaje de variables [' PumpRelay '] [' valor '] = bomba_en variables [' Estado '] [' valor '] = calc_status (error_code, percent, pump_on)

actual = tiempo ()

last_sending_time global si es forzado o actual - last_sending_time> MIN_SEND_INTERVAL: lecturas = cloud.read_data () cloud.publish_data (lecturas) last_sending_time = actual

Trabajar con la bomba

Definimos las siguientes constantes como base para la lógica de operación de la bomba.

# Pines GPIO (BCM) GPIO_PUMP = 4 GPIO_TRIGGER = 17 GPIO_ECHO = 27

# Bomba

START_PUMP = 1 STOP_PUMP = 0 PUMP_BOUNCE_TIME = 50 # milisegundos PUMP_STOP_TIMEOUT = 5 # segundos

IMPORTANTE: Si va a utilizar el Pin 4, no olvide deshabilitar la opción 1-Wire raspi-config para evitar conflictos.

Al inicio del programa, registramos una devolución de llamada y configuramos el estado inicial en APAGADO.

Aquí está el código de la función que alterna la bomba:

def toggle_pump (valor): if pump_disabled: return if is_pump_on ()! = value: log_debug ("[x]% s"% ('START' if value else 'STOP')) GPIO.setup (GPIO_PUMP, GPIO. OUT) GPIO.output (GPIO_PUMP, value) # Iniciar / Detener vertido

Como se define en el código de inicio anterior, cuando el relé se enciende, se llama a la siguiente devolución de llamada:

pump_on = False def pump_relay_handle (pin): global pump_on pump_on = GPIO.input (GPIO_PUMP) log_debug ("El relé de la bomba cambió a% d"% pump_on)

En la devolución de llamada, guardamos el estado actual de la bomba en una variable. En el bucle principal de la aplicación, podemos detectar el momento en que la bomba cambia como se muestra a continuación:

def is_pump_on (): global pump_on return pump_on

si GPIO.event_detected (GPIO_PUMP):

is_pouring = is_pump_on () #… log_debug ('[!] Evento de bomba detectado:% s'% ('On' if is_pouring else 'Off')) enviar (nube, variables, distancia, fuerza = Verdadero)

Midiendo la distancia

Es bastante fácil medir la distancia hacia la superficie del agua usando un sensor de proximidad ultrasónico. En nuestro repositorio, compartimos un par de scripts de Python que le permiten probar un sensor.

En aplicaciones reales, las lecturas del sensor pueden fluctuar debido al efecto de rebote del sensor y las oscilaciones del agua. En algunos casos, las lecturas pueden faltar por completo. Implementamos una clase BounceFilter que acumula N valores recientes, descarta picos y calcula el promedio de las mediciones restantes. El proceso de medición se implementa mediante el siguiente algoritmo asincrónico.

# Mantiene las últimas medidas del sensor lecturas = BounceFilter (size = 6, discard_count = 1)

read_complete = threading. Event ()

def wait_for_distance ():

reading_complete.clear () thread = threading. Thread (objetivo = read_distance) thread.start ()

si no es read_complete.wait (MAX_READING_TIMEOUT):

log_info ('Tiempo de espera del sensor de lectura') return Ninguno return readings.avg ()

def read_distance ():

try: value = hcsr04.raw_distance (tamaño_muestra = 5) redondeado = valor si el valor es Ninguno más round (valor, 1) lecturas.add (redondeado) excepto Excepción como err: log_error ('Error interno:% s'% err) finalmente: reading_complete.set ()

Puede encontrar la implementación completa del filtro en las fuentes.

Paso 3: Manejo de situaciones de emergencia

Manejo de situaciones de emergencia
Manejo de situaciones de emergencia
Manejo de situaciones de emergencia
Manejo de situaciones de emergencia
Manejo de situaciones de emergencia
Manejo de situaciones de emergencia

¿Qué pasa si el sensor se quemó, se cayó o apunta a un área incorrecta? Necesitábamos una forma de informar estos casos para poder tomar medidas manuales.

Si el sensor no proporciona lecturas de distancia, el sistema envía el estado cambiado a la nube y genera una notificación correspondiente.

La lógica se ilustra con el siguiente código.

distance = wait_for_distance () # Lee la profundidad actual del agua si la distancia es None: log_error ('¡Error de distancia!') notify_in_background (calc_alert (SENSOR_ERROR)) send (cloud, variables, distance, error_code = SENSOR_ERROR, force = True)

Tenemos un rango de nivel de agua operativo que debe mantenerse cuando el sensor está en su lugar. Probamos si el nivel del agua actual cae en este rango:

# Distancia del sensor al nivel del agua # según el depósito de agua de la cafetera MIN_DISTANCE = 2 # cm MAX_DISTANCE = 8 # cm

# La distancia está fuera del rango esperado: no comience a verter

si distancia> MAX_DISTANCE * 2: log_error ('La distancia está fuera de rango:%.2f'% distancia) continuar

Apagamos la bomba si estaba activa cuando ocurrió un error.

if is_pump_on () y prev_distance <STOP_PUMP_DISTANCE + DISTANCE_DELTA: log_error ('[!] Parada de emergencia de la bomba. No hay señal de un sensor de distancia')

toggle_pump (STOP_PUMP)

También procesamos el caso cuando la botella se queda sin agua. Comprobamos si el nivel del agua no cambia cuando la bomba funciona. Si es así, el sistema espera 5 segundos y luego verifica si la bomba se ha apagado. Si no es así, el sistema implementa el apagado de emergencia de la bomba y envía una notificación de error.

PUMP_STOP_TIMEOUT = 5 # secsemergency_stop_time = Ninguno

def set_emergency_stop_time (ahora, is_pouring):

tiempo de parada de emergencia global tiempo de parada de emergencia = ahora + PUMP_STOP_TIMEOUT if / is_pouring else Ninguno

def check_water_source_empty (ahora):

return Emergency_stop_time y ahora> Emergency_stop_time

# --------- bucle principal -----------

si GPIO.event_detected (GPIO_PUMP): is_pouring = is_pump_on () set_emergency_stop_time (ahora, is_pouring) #…

global pump_disabled

if check_water_source_empty (ahora): log_error ('[!] Parada de emergencia de la bomba. / La fuente de agua está vacía') toggle_pump (STOP_PUMP) pump_disabled = True

Arriba hay un ejemplo de un registro de mensajes generado durante una parada de emergencia.

Paso 4: Ejecutar el sistema 24 horas al día, 7 días a la semana

Ejecución del sistema 24 horas al día, 7 días a la semana
Ejecución del sistema 24 horas al día, 7 días a la semana

El código del dispositivo se depura y se ejecuta sin problemas. Lo lanzamos como un servicio, por lo que se reinicia si se reinicia la Raspberry Pi. Para mayor comodidad, creamos un Makefile que ayuda con la implementación, la ejecución del servicio y la visualización de registros.

. PHONY: instalar, ejecutar, iniciar, detener, registro de estado, implementar MAIN_FILE: = coffee-pump / main.py SERVICE_INSTALL_SCRIPT: = service_install.sh SERVICE_NAME: = coffee-pump.service

Instalar en pc:

chmod + x $ (SERVICE_INSTALL_SCRIPT) sudo./$(SERVICE_INSTALL_SCRIPT) $ (MAIN_FILE)

correr:

sudo python3 $ (MAIN_FILE)

comienzo:

sudo systemctl start $ (SERVICE_NAME)

estado:

sudo systemctl status $ (SERVICE_NAME)

parada:

sudo systemctl stop $ (SERVICE_NAME)

Iniciar sesión:

sudo journalctl -u coffee-pump --desde hoy

desplegar:

rsync -av configuración del sensor de la bomba de café Makefile *.sh pi@XX. XX. XXX. XXX: ~ /

Puede encontrar este archivo y todos los scripts necesarios en nuestro repositorio.

Paso 5: Monitoreo en la nube

Monitoreo en la nube
Monitoreo en la nube
Monitoreo en la nube
Monitoreo en la nube
Monitoreo en la nube
Monitoreo en la nube
Monitoreo en la nube
Monitoreo en la nube

Usamos Cloud4RPi para implementar un panel de control. Primero agregamos widgets para indicar los parámetros esenciales del sistema.

Por cierto, el widget para la variable STATUS puede usar diferentes esquemas de color según su valor (vea la imagen de arriba).

Agregamos un widget de gráfico para mostrar datos dinámicos. En la imagen a continuación, puede ver el momento en que la bomba se enciende y apaga y los niveles de agua respectivos.

Si analiza un período de tiempo más largo, puede ver picos, es decir, cuando la bomba estaba funcionando.

Cloud4RPi también le permite establecer diferentes niveles de suavizado.

Paso 6: Funciona

Image
Image

¡Funciona! El panel de control en su totalidad se ve como se muestra a continuación.

Actualmente, nuestra bomba automática ha estado funcionando durante varias semanas y todo lo que teníamos que hacer es reemplazar las botellas de agua. El código completo de nuestro proyecto está disponible en nuestro repositorio de GitHub.

Recomendado: