Inhaltsverzeichnis:

Intelligente Kaffeemaschinenpumpe, gesteuert durch Raspberry Pi & HC-SR04 Ultraschallsensor und Cloud4RPi - Gunook
Intelligente Kaffeemaschinenpumpe, gesteuert durch Raspberry Pi & HC-SR04 Ultraschallsensor und Cloud4RPi - Gunook

Video: Intelligente Kaffeemaschinenpumpe, gesteuert durch Raspberry Pi & HC-SR04 Ultraschallsensor und Cloud4RPi - Gunook

Video: Intelligente Kaffeemaschinenpumpe, gesteuert durch Raspberry Pi & HC-SR04 Ultraschallsensor und Cloud4RPi - Gunook
Video: M&F - AZURE IOT Webinar 2024, November
Anonim
Intelligente Kaffeemaschinenpumpe, gesteuert von Raspberry Pi & HC-SR04 Ultraschallsensor und Cloud4RPi
Intelligente Kaffeemaschinenpumpe, gesteuert von Raspberry Pi & HC-SR04 Ultraschallsensor und Cloud4RPi

Theoretisch müssen Sie jedes Mal, wenn Sie für Ihre Morgentasse zur Kaffeemaschine gehen, nur eine Chance von eins zu zwanzig haben, dass Sie den Wassertank füllen müssen. In der Praxis scheint es jedoch, dass die Maschine irgendwie einen Weg findet, Ihnen diese Arbeit immer zu übertragen. Je mehr Sie Kaffee wollen, desto wahrscheinlicher ist es, dass Sie die gefürchtete Meldung „Wassertank füllen“erhalten. Meine Kollegen sehen das ähnlich. Da wir die Nerds sind, die wir sind, haben wir uns entschieden, die Technologie zu implementieren, die dem ein Ende setzen würde.

Lieferungen

Unsere Ausrüstung

Wir haben eine SAECO Aulika Focus Kaffeemaschine. Bis heute benutzten wir eine Handpumpe, um den Wassertank der Maschine aus einer handelsüblichen 5 Gallonen (19L) Wasserflasche zu füllen.

Unsere Ziele

  1. Verwenden Sie eine elektrische Pumpe, die von einer Art Controller oder einem Mikrocomputer über ein Relais angetrieben wird.
  2. Haben Sie eine Möglichkeit, den Wasserstand im Tank der Kaffeemaschine zu messen, damit unser System weiß, wann es nachgefüllt werden muss.
  3. Mittel zur Steuerung des Systems haben, vorzugsweise in Echtzeit von einem mobilen Gerät aus.
  4. Erhalten Sie Benachrichtigungen (über Slack oder einen ähnlichen Dienst), wenn etwas mit dem System schief geht.

Schritt 1: Auswahl der Ausrüstung

Auswahl der Ausrüstung
Auswahl der Ausrüstung
Auswahl der Ausrüstung
Auswahl der Ausrüstung
Auswahl der Ausrüstung
Auswahl der Ausrüstung
Auswahl der Ausrüstung
Auswahl der Ausrüstung

Die Pumpe

Eine schnelle Websuche zeigt verschiedene Elektropumpenmodelle an, die für Ihre Wasserflasche Ihrer Wahl entwickelt wurden. Solche Pumpen werden in der Regel über einen EIN/AUS-Schalter gesteuert (zB Hot Frost A12 oder SMixx ХL-D2). Hier ist die Pumpe, die wir für unser Projekt ausgewählt haben.

Das Controller-Gerät

Wir haben mehrere Geräte ausprobiert, uns aber aufgrund der folgenden Vorteile für einen Raspberry Pi entschieden:

  • Es verfügt über einen GPIO, mit dem wir einen Näherungssensor anschließen können
  • Es unterstützt Python

Wir haben eine neue Version von Raspbian Buster Lite und alles, was zum Ausführen von Python 3 erforderlich ist, installiert.

Wie wir die Pumpe umschalten

Um die Leistung zu steuern, haben wir ein für Wechselstrom geeignetes Halbleiterrelais mittlerer Leistung (12 V / 2 A) ausgewählt. Das Relais verbindet die Pumpe mit der Steckdose und wird vom digitalen Pin des Raspberry Pi gesteuert.

Wie wir den Wasserstand überprüfen

Uns war es wichtig, die Konstruktion der Kaffeemaschine nicht zu verändern, daher haben wir uns für die Messung des Wasserstands mit dem Ultraschall-Näherungssensor HC-SR04 entschieden.

Wir haben eine benutzerdefinierte Wassertankabdeckung mit zwei Löchern für die Emitter des Sensors in 3D gedruckt. Wir fanden leicht eine GitHub-Bibliothek für den Sensor. Zu diesem Zeitpunkt waren alle Vorbereitungen abgeschlossen.

Schritt 2: Entwerfen des Systems

Entwerfen des Systems
Entwerfen des Systems
Entwerfen des Systems
Entwerfen des Systems

Logik des Systems

Das System ist unter Berücksichtigung der folgenden einfachen Logik konzipiert:

  • Das System überwacht ständig den Abstand zwischen Sensor und Wasseroberfläche.
  • Überschreitet eine Entfernungsänderung einen Schwellenwert, sendet das System Informationen über ihren Zustand an die Cloud.
  • Wenn die Entfernung den maximal zulässigen Wert überschreitet (der Tank ist leer), aktiviert das System die Pumpe und schaltet sie aus, sobald die Entfernung unter dem zulässigen Mindestwert liegt.
  • Immer wenn sich der Zustand des Systems ändert (z. B. wenn die Pumpe aktiviert wird), informiert es die Cloud.

Im Fehlerfall wird eine Benachrichtigung an einen Slack-Kanal gesendet.

Im Ruhezustand der Kaffeemaschine pingt das System einmal pro Minute den Cloud-Dienst mit Diagnosedaten an. Außerdem sendet es alle 5 Minuten seinen Status an die Cloud.

Wenn die Pumpe aktiv ist, sendet das System häufiger Daten, jedoch nicht öfter als einmal pro halbe Sekunde.

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'] = Prozent-Variablen['PumpRelay']['value'] = pump_on-Variablen['Status']['value'] = calc_status(error_code, Prozent, pump_on)

aktuell = Zeit ()

global last_sending_time wenn erzwungen oder aktuell - last_sending_time > MIN_SEND_INTERVAL: Readings = cloud.read_data() cloud.publish_data(readings) last_sending_time = current

Arbeiten mit der Pumpe

Wir definieren die folgenden Konstanten als Grundlage für die Pumpenbetriebslogik.

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

# Pumpe

START_PUMP = 1 STOP_PUMP = 0 PUMP_BOUNCE_TIME = 50 # Millisekunden PUMP_STOP_TIMEOUT = 5 # Sekunden

WICHTIG: Wenn Sie Pin 4 verwenden, vergessen Sie nicht, die Option 1-Wire raspi-config zu deaktivieren, um Konflikte zu vermeiden.

Beim Start des Programms registrieren wir einen Callback und setzen den Anfangszustand auf OFF.

Hier ist der Code für die Funktion, die die Pumpe umschaltet:

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, Wert) # Gießen starten/stoppen

Wie im obigen Startcode definiert, wird beim Einschalten des Relais der folgende Rückruf aufgerufen:

pump_on = Falsche Def pump_relay_handle(pin): global pump_on pump_on = GPIO.input(GPIO_PUMP) log_debug("Pumprelais geändert auf %d" % pump_on)

Im Callback speichern wir den aktuellen Zustand der Pumpe in einer Variablen. In der Hauptschleife der Anwendung können wir den Moment erkennen, in dem die Pumpe wie unten gezeigt umschaltet:

def is_pump_on(): global pump_on return pump_on

wenn GPIO.event_detected(GPIO_PUMP):

is_pouring = is_pump_on() # … log_debug('[!] Pumpenereignis erkannt: %s' % ('On' if is_pouring sonst 'Off')) send(cloud, variables, distance, force=True)

Messen der Entfernung

Die Entfernung zur Wasseroberfläche lässt sich ganz einfach mit einem Ultraschall-Näherungssensor messen. In unserem Repository haben wir einige Python-Skripte geteilt, mit denen Sie einen Sensor testen können.

In realen Anwendungen können die Sensormesswerte aufgrund des Rückpralleffekts des Sensors und der Wasserschwingungen schwanken. In einigen Fällen können Messwerte vollständig fehlen. Wir haben eine BounceFilter-Klasse implementiert, die N aktuelle Werte akkumuliert, Spitzen verwirft und den Durchschnitt der verbleibenden Messungen berechnet. Der Messprozess wird durch den folgenden asynchronen Algorithmus implementiert.

# Behält die letzten Sensormesswerte bei = BounceFilter(size=6, discard_count=1)

read_complete = threading. Event()

def wait_for_distance():

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

wenn nicht read_complete.wait(MAX_READING_TIMEOUT):

log_info('Zeitüberschreitung des Messwertsensors') return Keine return readings.avg()

def read_distance():

try: value = hcsr04.raw_distance(sample_size=5) round = value if value is None else round(value, 1) Reads.add(rounded) außer Ausnahme als err: log_error('Interner Fehler: %s' % err) finally: read_complete.set()

Die vollständige Implementierung des Filters finden Sie in den Quellen.

Schritt 3: Umgang mit Notfallsituationen

Umgang mit Notfallsituationen
Umgang mit Notfallsituationen
Umgang mit Notfallsituationen
Umgang mit Notfallsituationen
Umgang mit Notfallsituationen
Umgang mit Notfallsituationen

Was ist, wenn der Sensor durchgebrannt ist, heruntergefallen ist oder auf einen falschen Bereich zeigt? Wir brauchten eine Möglichkeit, solche Fälle zu melden, damit wir manuelle Maßnahmen ergreifen können.

Wenn der Sensor keine Entfernungsmesswerte liefert, sendet das System den geänderten Status an die Cloud und generiert eine entsprechende Benachrichtigung.

Die Logik wird durch den folgenden Code veranschaulicht.

distance = wait_for_distance() # Lies die aktuelle Wassertiefe, wenn Distance gleich None ist: log_error('Distance error!')notify_in_background(calc_alert(SENSOR_ERROR)) send(cloud, variables, distance, error_code=SENSOR_ERROR, force=True)

Wir haben einen Betriebswasserstandsbereich, der eingehalten werden sollte, wenn der Sensor an seinem Platz ist. Wir testen, ob der aktuelle Wasserstand in diesen Bereich fällt:

# Abstand vom Sensor zum Wasserstand# bezogen auf den Wassertank der Kaffeemaschine MIN_DISTANCE = 2 # cm MAX_DISTANCE = 8 # cm

# Entfernung liegt außerhalb des erwarteten Bereichs: Beginnen Sie nicht mit dem Gießen

if distance > MAX_DISTANCE * 2: log_error('Distance is out of range: %.2f' % Distance) weiter

Wir schalten die Pumpe aus, wenn sie beim Auftreten eines Fehlers aktiv war.

if is_pump_on() and prev_distance < STOP_PUMP_DISTANCE + DISTANCE_DELTA: log_error('[!] Notstopp der Pumpe. Kein Signal von einem Distanzsensor')

toggle_pump(STOP_PUMP)

Wir bearbeiten auch den Fall, wenn die Flasche kein Wasser mehr hat. Wir prüfen, ob sich der Wasserstand bei laufender Pumpe nicht ändert. Wenn dies der Fall ist, wartet das System 5 Sekunden und prüft dann, ob die Pumpe ausgeschaltet ist. Ist dies nicht der Fall, führt das System eine Notabschaltung der Pumpe durch und sendet eine Fehlermeldung.

PUMP_STOP_TIMEOUT = 5 # secsemergency_stop_time = Keine

def set_emergency_stop_time (jetzt is_pouring):

global Emergency_stop_time Emergency_stop_time = now + PUMP_STOP_TIMEOUT if / is_pouring else None

def check_water_source_empty(jetzt):

return Emergency_stop_time und jetzt > Emergency_stop_time

# --------- Hauptschleife -----------

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

global pump_disabled

if check_water_source_empty(now): log_error('[!] Notstopp der Pumpe. / Wasserquelle ist leer') toggle_pump(STOP_PUMP) pump_disabled = True

Oben sehen Sie ein Beispiel für ein Meldungsprotokoll, das während eines Notstopps generiert wird.

Schritt 4: Das System rund um die Uhr laufen lassen

Betreiben des Systems rund um die Uhr
Betreiben des Systems rund um die Uhr

Der Code auf dem Gerät ist debuggt und läuft ohne Probleme. Wir haben es als Dienst gestartet, sodass es neu gestartet wird, wenn der Raspberry Pi neu gestartet wird. Der Einfachheit halber haben wir ein Makefile erstellt, das bei der Bereitstellung hilft, den Dienst ausführt und Protokolle anzeigt.

. 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

Installieren:

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

Lauf:

sudo python3 $(MAIN_FILE)

Anfang:

sudo systemctl start $(SERVICE_NAME)

Status:

sudo systemctl-Status $(SERVICE_NAME)

halt:

sudo systemctl stop $(SERVICE_NAME)

Protokoll:

sudo journalctl -u Kaffeepumpe --seit heute

einsetzen:

rsync -av Kaffeepumpensensor-Setup Makefile *.sh pi@XX. XX. XXX. XXX:~/

Sie finden diese Datei und alle benötigten Skripte in unserem Repository.

Schritt 5: Cloud-Monitoring

Cloud-Monitoring
Cloud-Monitoring
Cloud-Monitoring
Cloud-Monitoring
Cloud-Monitoring
Cloud-Monitoring
Cloud-Monitoring
Cloud-Monitoring

Wir haben Cloud4RPi verwendet, um ein Control Panel zu implementieren. Wir haben zuerst Widgets hinzugefügt, um die wesentlichen Parameter des Systems anzuzeigen.

Das Widget für die STATUS-Variable kann übrigens je nach Wert verschiedene Farbschemata verwenden (siehe Bild oben).

Wir haben ein Diagramm-Widget hinzugefügt, um dynamische Daten anzuzeigen. In der Abbildung unten sehen Sie den Moment, in dem die Pumpe ein- und ausgeschaltet wurde, und die jeweiligen Wasserstände.

Analysiert man eine längere Zeitspanne, sieht man Peaks – dann lief die Pumpe.

Cloud4RPi ermöglicht es Ihnen auch, verschiedene Glättungsstufen einzustellen.

Schritt 6: Es funktioniert

Image
Image

Es klappt! Das gesamte Bedienfeld sieht wie unten gezeigt aus.

Derzeit läuft unsere automatische Pumpe seit mehreren Wochen und wir mussten nur noch Wasserflaschen austauschen. Der vollständige Code für unser Projekt ist in unserem GitHub-Repository verfügbar.

Empfohlen: