Table des matières:

Pompe de machine à café intelligente contrôlée par le capteur à ultrasons Raspberry Pi & HC-SR04 et Cloud4RPi : 6 étapes
Pompe de machine à café intelligente contrôlée par le capteur à ultrasons Raspberry Pi & HC-SR04 et Cloud4RPi : 6 étapes

Vidéo: Pompe de machine à café intelligente contrôlée par le capteur à ultrasons Raspberry Pi & HC-SR04 et Cloud4RPi : 6 étapes

Vidéo: Pompe de machine à café intelligente contrôlée par le capteur à ultrasons Raspberry Pi & HC-SR04 et Cloud4RPi : 6 étapes
Vidéo: Construction d'un radar à ultrasons 2024, Juin
Anonim
Pompe de machine à café intelligente contrôlée par un capteur à ultrasons Raspberry Pi & HC-SR04 et Cloud4RPi
Pompe de machine à café intelligente contrôlée par un capteur à ultrasons Raspberry Pi & HC-SR04 et Cloud4RPi

En théorie, chaque fois que vous allez à la machine à café pour votre tasse du matin, il n'y a qu'une chance sur vingt que vous deviez remplir le réservoir d'eau. Dans la pratique, cependant, il semble que la machine trouve d'une manière ou d'une autre un moyen de toujours vous imposer cette corvée. Plus vous voulez du café, plus vous avez de chances de recevoir le message redouté « remplir le réservoir d'eau ». Mes collègues ressentent la même chose à ce sujet. Étant les nerds que nous sommes, nous avons décidé de mettre en œuvre la technologie qui mettrait fin à cela.

Fournitures

Notre équipement

Nous avons une machine à café SAECO Aulika Focus. Jusqu'à ce jour, nous utilisions une pompe à main pour remplir le réservoir d'eau de la machine à partir d'une bouteille d'eau standard de 5 gallons (19 L).

Nos buts

  1. Utilisez une pompe électrique entraînée par une sorte de contrôleur ou un micro-ordinateur via un relais.
  2. Avoir un moyen de mesurer le niveau d'eau dans le réservoir de la machine à café afin que notre système sache quand le remplir.
  3. Disposer de moyens pour contrôler le système, de préférence en temps réel depuis un appareil mobile.
  4. Recevez des notifications (via Slack ou un service similaire) en cas de problème avec le système.

Étape 1: Choisir l'équipement

Choisir l'équipement
Choisir l'équipement
Choisir l'équipement
Choisir l'équipement
Choisir l'équipement
Choisir l'équipement
Choisir l'équipement
Choisir l'équipement

La pompe

Une recherche rapide sur le Web affichera plusieurs modèles de pompes électriques conçus pour la bouteille d'eau de votre choix. Ces pompes sont généralement contrôlées par un interrupteur ON/OFF (par exemple, Hot Frost A12 ou SMixx ХL-D2). Voici la pompe que nous avons choisie pour notre projet.

Le dispositif de contrôle

Nous avons essayé plusieurs appareils mais avons opté pour un Raspberry Pi en raison des avantages suivants:

  • Il dispose d'un GPIO qui nous permet de connecter un capteur de proximité
  • Il prend en charge Python

Nous avons installé une nouvelle version de Raspbian Buster Lite et tout le nécessaire pour exécuter Python 3.

Comment nous basculons la pompe

Pour contrôler la puissance, nous avons choisi un relais à semi-conducteurs de puissance moyenne (12 V/2 A) adapté au courant alternatif. Le relais connecte la pompe à la prise et est contrôlé par la broche numérique du Raspberry Pi.

Comment nous vérifions le niveau d'eau

Il était important pour nous de ne pas modifier la construction de la machine à café, nous avons donc décidé d'utiliser le capteur de proximité à ultrasons HC-SR04 pour mesurer le niveau d'eau.

Nous avons imprimé en 3D un couvercle de réservoir d'eau personnalisé avec deux trous pour les émetteurs du capteur. Nous avons facilement trouvé une bibliothèque GitHub pour le capteur. À ce stade, toutes les préparations étaient terminées.

Étape 2: Conception du système

Conception du système
Conception du système
Conception du système
Conception du système

Logique du système

Le système est conçu avec la logique simple suivante à l'esprit:

  • Le système surveille en permanence la distance entre le capteur et la surface de l'eau.
  • Chaque fois qu'un changement de distance dépasse une valeur seuil, le système envoie des informations sur son état au cloud.
  • Si la distance dépasse la valeur maximale autorisée (le réservoir est vide), le système active la pompe et l'éteint dès que la distance est inférieure à la valeur minimale autorisée.
  • Chaque fois que l'état du système change (par exemple, la pompe s'active), il en informe le cloud.

En cas d'erreur, une notification est envoyée à un canal Slack.

Lorsque la machine à café est inactive, le système envoie une requête ping au service cloud avec des données de diagnostic une fois par minute. De plus, il envoie son état au cloud toutes les 5 minutes.

Lorsque la pompe est active, le système envoie des données plus fréquemment mais pas plus d'une fois toutes les demi-secondes.

def send(cloud, variables, dist, error_code=0, force=False): pump_on = is_pump_on() percent = calc_water_level_percent(dist) variables['Distance']['value'] = dist variables['WaterLevel'][' value'] = pourcentage variables['PumpRelay']['value'] = variables pump_on['Status']['value'] = calc_status(error_code, percent, pump_on)

courant = heure()

global last_sending_time si forcé ou actuel - last_sending_time > MIN_SEND_INTERVAL: lectures = cloud.read_data() cloud.publish_data(readings) last_sending_time = actuel

Travailler avec la pompe

Nous définissons les constantes suivantes comme base pour la logique de fonctionnement de la pompe.

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

# Pompe

START_PUMP = 1 STOP_PUMP = 0 PUMP_BOUNCE_TIME = 50 # millisecondes PUMP_STOP_TIMEOUT = 5 # secondes

IMPORTANT: Si vous comptez utiliser la broche 4, n'oubliez pas de désactiver l'option 1-Wire raspi-config pour éviter les conflits.

Au démarrage du programme, nous enregistrons un rappel et définissons l'état initial sur OFF.

Voici le code de la fonction qui bascule la pompe:

def toggle_pump(value): 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) # Démarrer/Arrêter le versement

Comme défini dans le code de démarrage ci-dessus, lorsque le relais s'active, le rappel suivant est appelé:

pump_on = False def pump_relay_handle(pin): global pump_on pump_on = GPIO.input(GPIO_PUMP) log_debug("Relais de pompe changé en %d" % pump_on)

Dans le rappel, nous sauvegardons l'état actuel de la pompe dans une variable. Dans la boucle principale de l'application, nous pouvons détecter le moment où la pompe bascule comme indiqué ci-dessous:

def is_pump_on(): global pump_on renvoie pump_on

si GPIO.event_detected(GPIO_PUMP):

is_pouring = is_pump_on() # … log_debug('[!] Evénement de pompe détecté: %s' % ('On' if is_pouring else 'Off')) send(cloud, variables, distance, force=True)

Mesurer la distance

Il est assez facile de mesurer la distance vers la surface de l'eau à l'aide d'un capteur de proximité à ultrasons. Dans notre référentiel, nous avons partagé quelques scripts python qui vous permettent de tester un capteur.

Dans les applications réelles, les lectures du capteur peuvent fluctuer en raison de l'effet de rebond du capteur et des oscillations de l'eau. Dans certains cas, les lectures peuvent être complètement manquantes. Nous avons implémenté une classe BounceFilter qui accumule N valeurs récentes, élimine les pics et calcule la moyenne des mesures restantes. Le processus de mesure est mis en œuvre par l'algorithme asynchrone suivant.

# Conserve les dernières lectures des mesures du capteur = BounceFilter(size=6, throw_count=1)

read_complete = threading. Event()

def wait_for_distance():

read_complete.clear() thread = threading. Thread(target=read_distance) thread.start()

sinon read_complete.wait(MAX_READING_TIMEOUT):

log_info('Reading sensor timeout') return None return readings.avg()

def read_distance():

try: value = hcsr04.raw_distance(sample_size=5) rounded = value if value is None else round(value, 1) lectures.add(arrondi) sauf exception car err: log_error('Erreur interne: %s' % err) enfin: lecture_complete.set()

Vous pouvez trouver l'implémentation complète du filtre dans les sources.

Étape 3: Gérer les situations d'urgence

Gestion des situations d'urgence
Gestion des situations d'urgence
Gestion des situations d'urgence
Gestion des situations d'urgence
Gestion des situations d'urgence
Gestion des situations d'urgence

Que se passe-t-il si le capteur grille, tombe ou pointe vers une mauvaise zone ? Nous avions besoin d'un moyen de signaler de tels cas afin de pouvoir prendre des mesures manuelles.

Si le capteur ne parvient pas à fournir des lectures de distance, le système envoie le statut modifié au cloud et génère une notification correspondante.

La logique est illustrée par le code ci-dessous.

distance = wait_for_distance() # Lire la profondeur d'eau actuelle si la distance est None: log_error('Distance error!') notify_in_background(calc_alert(SENSOR_ERROR)) send(cloud, variables, distance, error_code=SENSOR_ERROR, force=True)

Nous avons une plage de niveau d'eau opérationnelle qui doit être maintenue lorsque le capteur est à sa place. Nous testons si le niveau d'eau actuel se situe dans cette plage:

# Distance du capteur au niveau d'eau# basée sur le réservoir d'eau de la machine à café MIN_DISTANCE = 2 # cm MAX_DISTANCE = 8 # cm

# La distance est en dehors de la plage prévue: ne commencez pas à verser

si distance > MAX_DISTANCE * 2: log_error('La distance est hors de portée: %.2f' % distance) continuer

Nous éteignons la pompe si elle était active lorsqu'une erreur s'est produite.

if is_pump_on() et prev_distance < STOP_PUMP_DISTANCE + DISTANCE_DELTA: log_error('[!] Arrêt d'urgence de la pompe. Pas de signal d'un capteur de distance')

toggle_pump(STOP_PUMP)

Nous traitons également la caisse lorsque la bouteille manque d'eau. Nous vérifions si le niveau d'eau ne change pas lorsque la pompe fonctionne. Si c'est le cas, le système attend 5 secondes puis vérifie si la pompe s'est éteinte. Si ce n'est pas le cas, le système met en œuvre un arrêt d'urgence de la pompe et envoie une notification d'erreur.

PUMP_STOP_TIMEOUT = 5 # secsemergency_stop_time = Aucun

def set_emergency_stop_time (maintenant, is_pouring):

global emergency_stop_time emergency_stop_time = maintenant + PUMP_STOP_TIMEOUT if / is_pouring else Aucun

def check_water_source_empty (maintenant):

retourner emergency_stop_time et maintenant > emergency_stop_time

# --------- boucle principale -----------

if GPIO.event_detected(GPIO_PUMP): is_pouring = is_pump_on() set_emergency_stop_time(maintenant, is_pouring) # …

global pump_disabled

if check_water_source_empty(now): log_error('[!] Arrêt d'urgence de la pompe. / La source d'eau est vide') toggle_pump(STOP_PUMP) pump_disabled = True

Ci-dessus, un exemple de journal de messages généré lors d'un arrêt d'urgence.

Étape 4: Exécution du système 24h/24 et 7j/7

Exécution du système 24h/24 et 7j/7
Exécution du système 24h/24 et 7j/7

Le code sur l'appareil est débogué et s'exécute sans problème. Nous l'avons lancé en tant que service, il redémarre donc si le Raspberry Pi est redémarré. Pour plus de commodité, nous avons créé un Makefile qui facilite le déploiement, l'exécution du service et l'affichage des journaux.

. PHONY: install run start stop status log deploy MAIN_FILE:= coffee-pump/main.py SERVICE_INSTALL_SCRIPT:= service_install.sh SERVICE_NAME:= coffee-pump.service

installer:

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

Cours:

sudo python3 $(MAIN_FILE)

début:

sudo systemctl start $(SERVICE_NAME)

statut:

sudo systemctl status $(SERVICE_NAME)

arrêter:

sudo systemctl stop $(SERVICE_NAME)

Journal:

sudo journalctl -u coffee-pump --depuis aujourd'hui

déployer:

rsync -av coffee-pump sensor-setup Makefile *.sh pi@XX. XX. XXX. XXX:~/

Vous pouvez trouver ce fichier et tous les scripts requis dans notre référentiel.

Étape 5: Surveillance du cloud

Surveillance en nuage
Surveillance en nuage
Surveillance en nuage
Surveillance en nuage
Surveillance en nuage
Surveillance en nuage
Surveillance en nuage
Surveillance en nuage

Nous avons utilisé Cloud4RPi pour implémenter un panneau de contrôle. Nous avons d'abord ajouté des widgets pour indiquer les paramètres essentiels du système.

Soit dit en passant, le widget de la variable STATUS peut utiliser différents schémas de couleurs en fonction de sa valeur (voir l'image ci-dessus).

Nous avons ajouté un widget graphique pour afficher des données dynamiques. Dans l'image ci-dessous, vous pouvez voir le moment où la pompe s'est allumée et éteinte et les niveaux d'eau respectifs.

Si vous analysez une période plus longue, vous pouvez voir des pics - c'est à ce moment-là que la pompe fonctionnait.

Cloud4RPi vous permet également de définir différents niveaux de lissage.

Étape 6: ça marche

Image
Image

Ça marche! Le panneau de commande dans son intégralité ressemble à celui illustré ci-dessous.

Actuellement, notre pompe automatique fonctionne depuis plusieurs semaines et il ne nous reste plus qu'à remplacer les bouteilles d'eau. Le code complet de notre projet est disponible dans notre référentiel GitHub.

Conseillé: