Sommario:

Pompa per macchina da caffè intelligente controllata da Raspberry Pi e sensore a ultrasuoni HC-SR04 e Cloud4RPi: 6 passaggi
Pompa per macchina da caffè intelligente controllata da Raspberry Pi e sensore a ultrasuoni HC-SR04 e Cloud4RPi: 6 passaggi

Video: Pompa per macchina da caffè intelligente controllata da Raspberry Pi e sensore a ultrasuoni HC-SR04 e Cloud4RPi: 6 passaggi

Video: Pompa per macchina da caffè intelligente controllata da Raspberry Pi e sensore a ultrasuoni HC-SR04 e Cloud4RPi: 6 passaggi
Video: Smart Coffee Machine Pump Controlled by Raspberry Pi & HC-SR04 Ultrasonic Sensor 2024, Dicembre
Anonim
Pompa per macchina da caffè intelligente controllata da Raspberry Pi e sensore a ultrasuoni HC-SR04 e Cloud4RPi
Pompa per macchina da caffè intelligente controllata da Raspberry Pi e sensore a ultrasuoni HC-SR04 e Cloud4RPi

In teoria, ogni volta che vai alla macchina del caffè per la tua tazza mattutina, c'è solo una possibilità su venti che dovrai riempire il serbatoio dell'acqua. In pratica, però, sembra che la macchina trovi in qualche modo il modo di metterti sempre addosso questo lavoretto. Più vuoi caffè, più è probabile che tu riceva il temuto messaggio "riempire il serbatoio dell'acqua". I miei colleghi la pensano allo stesso modo su questo. Essendo i nerd che siamo, abbiamo deciso di implementare la tecnologia che avrebbe posto fine a tutto questo.

Forniture

La nostra attrezzatura

Abbiamo una macchina da caffè SAECO Aulika Focus. Fino ad oggi, abbiamo usato una pompa a mano per riempire il serbatoio dell'acqua della macchina da una bottiglia d'acqua standard da 5 galloni (19L).

I nostri obiettivi

  1. Utilizzare una pompa elettrica azionata da una sorta di controller o un microcomputer tramite un relè.
  2. Avere un modo per misurare il livello dell'acqua nel serbatoio della macchina da caffè in modo che il nostro sistema sappia quando riempirlo.
  3. Avere mezzi per controllare il sistema, preferibilmente in tempo reale da un dispositivo mobile.
  4. Ricevi notifiche (tramite Slack o un servizio simile) se qualcosa va storto con il sistema.

Passaggio 1: scelta dell'attrezzatura

Scegliere l'attrezzatura
Scegliere l'attrezzatura
Scegliere l'attrezzatura
Scegliere l'attrezzatura
Scegliere l'attrezzatura
Scegliere l'attrezzatura
Scegliere l'attrezzatura
Scegliere l'attrezzatura

La pompa

Una rapida ricerca sul web mostrerà diversi modelli di pompa elettrica progettati per la tua bottiglia d'acqua preferita. Tali pompe sono generalmente controllate da un interruttore ON/OFF (ad esempio, Hot Frost A12 o SMixx ХL-D2). Ecco la pompa che abbiamo scelto per il nostro progetto.

Il dispositivo di controllo

Abbiamo provato diversi dispositivi ma abbiamo optato per un Raspberry Pi per i seguenti vantaggi:

  • Ha un GPIO che ci permette di collegare un sensore di prossimità
  • Supporta Python

Abbiamo installato una nuova versione di Raspbian Buster Lite e tutto il necessario per eseguire Python 3.

Come attiviamo la pompa

Per controllare la potenza, abbiamo scelto un relè a stato solido di media potenza (12V/2A) adatto alla corrente alternata. Il relè collega la pompa alla presa ed è controllato dal pin digitale del Raspberry Pi.

Come controlliamo il livello dell'acqua

Per noi era importante non alterare la struttura della macchina da caffè, quindi abbiamo deciso di utilizzare il sensore di prossimità ad ultrasuoni HC-SR04 per misurare il livello dell'acqua.

Abbiamo stampato in 3D un coperchio del serbatoio dell'acqua personalizzato con due fori per gli emettitori del sensore. Abbiamo trovato facilmente una libreria GitHub per il sensore. A questo punto tutti i preparativi erano finiti.

Passaggio 2: progettazione del sistema

Progettare il sistema
Progettare il sistema
Progettare il sistema
Progettare il sistema

Logica del sistema

Il sistema è progettato con la seguente semplice logica in mente:

  • Il sistema monitora costantemente la distanza tra il sensore e la superficie dell'acqua.
  • Ogni volta che una variazione della distanza supera un valore di soglia, il sistema invia informazioni sul suo stato al cloud.
  • Se la distanza supera il valore massimo consentito (il serbatoio è vuoto), il sistema attiva la pompa e la spegne quando la distanza è inferiore al valore minimo consentito.
  • Ogni volta che lo stato del sistema cambia (ad esempio, la pompa si attiva), informa il cloud.

In caso di errore, viene inviata una notifica a un canale Slack.

Quando la macchina per il caffè è inattiva, il sistema esegue il ping del servizio cloud con i dati di diagnostica una volta ogni minuto. Inoltre, invia il suo stato al cloud ogni 5 minuti.

Quando la pompa è attiva, il sistema invia i dati più frequentemente ma non più di una volta ogni mezzo secondo.

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

corrente = ora()

globale last_sending_time se forzato o corrente - last_sending_time > MIN_SEND_INTERVAL: letture = cloud.read_data() cloud.publish_data(letture) last_sending_time = corrente

Lavorare con la pompa

Definiamo le seguenti costanti come base per la logica di funzionamento della pompa.

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

# Pompa

START_PUMP = 1 STOP_PUMP = 0 PUMP_BOUNCE_TIME = 50 # millisecondi PUMP_STOP_TIMEOUT = 5 # secondi

IMPORTANTE: se hai intenzione di utilizzare il Pin 4, non dimenticare di disabilitare l'opzione 1-Wire raspi-config per evitare conflitti.

All'avvio del programma, registriamo una richiamata e impostiamo lo stato iniziale su OFF.

Ecco il codice per la funzione che attiva la pompa:

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, valore) # Avvia/Interrompi versamento

Come definito nel codice di avvio sopra, quando il relè si attiva, viene chiamata la seguente richiamata:

pump_on = False def pump_relay_handle(pin): global pump_on pump_on = GPIO.input(GPIO_PUMP) log_debug("Relè pompa cambiato in %d" % pump_on)

Nella richiamata, salviamo lo stato corrente della pompa in una variabile. Nel ciclo principale dell'applicazione, possiamo rilevare il momento in cui la pompa si attiva come mostrato di seguito:

def is_pump_on(): global pump_on return pump_on

if GPIO.event_detected(GPIO_PUMP):

is_pouring = is_pump_on() # … log_debug('[!] Evento pompa rilevato: %s' % ('On' if is_pouring else 'Off')) send(cloud, variable, distance, force=True)

Misurare la distanza

È abbastanza facile misurare la distanza dalla superficie dell'acqua utilizzando un sensore di prossimità a ultrasuoni. Nel nostro repository, abbiamo condiviso un paio di script Python che ti consentono di testare un sensore.

Nelle applicazioni reali, le letture del sensore possono fluttuare a causa dell'effetto di rimbalzo del sensore e delle oscillazioni dell'acqua. In alcuni casi, le letture possono mancare completamente. Abbiamo implementato una classe BounceFilter che accumula N valori recenti, scarta i picchi e calcola la media delle misurazioni rimanenti. Il processo di misurazione è implementato dal seguente algoritmo asincrono.

# Mantiene le ultime misurazioni del sensorereadings = BounceFilter(size=6, scarta_count=1)

reading_complete = threading. Event()

def wait_for_distance():

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

se non reading_complete.wait(MAX_READING_TIMEOUT):

log_info('Timeout sensore di lettura') return Nessuno restituisce readings.avg()

def read_distanza():

prova: valore = hcsr04.raw_distance(sample_size=5) arrotondato = valore se il valore è Nessun altro round(valore, 1) readings.add(arrotondato) tranne Eccezione come err: log_error('Errore interno: %s' % err) finalmente: reading_complete.set()

Puoi trovare l'implementazione completa del filtro nelle fonti.

Passaggio 3: gestione delle situazioni di emergenza

Gestire le situazioni di emergenza
Gestire le situazioni di emergenza
Gestire le situazioni di emergenza
Gestire le situazioni di emergenza
Gestire le situazioni di emergenza
Gestire le situazioni di emergenza

Cosa succede se il sensore si brucia, cade o indica un'area sbagliata? Avevamo bisogno di un modo per segnalare tali casi in modo da poter intraprendere un'azione manuale.

Se il sensore non riesce a fornire le letture della distanza, il sistema invia lo stato modificato al cloud e genera una notifica corrispondente.

La logica è illustrata dal codice sottostante.

distanza = wait_for_distance() # Legge la profondità dell'acqua corrente se la distanza è None: log_error('Distance error!') notify_in_background(calc_alert(SENSOR_ERROR)) send(cloud, variable, distance, error_code=SENSOR_ERROR, force=True)

Abbiamo un intervallo operativo del livello dell'acqua che dovrebbe essere mantenuto quando il sensore è al suo posto. Verifichiamo se il livello dell'acqua corrente rientra in questo intervallo:

# Distanza dal sensore al livello dell'acqua# in base al serbatoio dell'acqua della macchina da caffè DISTANZA_MIN = 2 # cm DISTANZA_MAX = 8 # cm

# La distanza è fuori dall'intervallo previsto: non iniziare a versare

se distanza > MAX_DISTANCE * 2: log_error('La distanza è fuori intervallo: %.2f' % distanza) continua

Spegniamo la pompa se era attiva quando si è verificato un errore.

if is_pump_on() e prev_distance < STOP_PUMP_DISTANCE + DISTANCE_DELTA: log_error('[!] Arresto di emergenza della pompa. Nessun segnale da un sensore di distanza')

toggle_pump(STOP_PUMP)

Elaboriamo anche il caso quando la bottiglia finisce l'acqua. Controlliamo se il livello dell'acqua non cambia quando la pompa è in funzione. In caso affermativo, il sistema attende 5 secondi e poi verifica se la pompa si è spenta. In caso contrario, il sistema implementa l'arresto di emergenza della pompa e invia una notifica di errore.

PUMP_STOP_TIMEOUT = 5 # secsemergency_stop_time = Nessuno

def set_emergency_stop_time(now, is_pouring):

emergenza_stop_time globale Emergency_stop_time = ora + PUMP_STOP_TIMEOUT if / is_pouring else Nessuno

def check_water_source_empty (ora):

ritorna Emergency_stop_time e ora > Emergency_stop_time

# --------- ciclo principale -----------

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

globale pump_disabled

if check_water_source_empty(now): log_error('[!] Arresto di emergenza della pompa. / La sorgente d'acqua è vuota') toggle_pump(STOP_PUMP) pump_disabled = True

Sopra è riportato un esempio di registro messaggi generato durante un arresto di emergenza.

Passaggio 4: eseguire il sistema 24 ore su 24, 7 giorni su 7

Esecuzione del sistema 24 ore su 24, 7 giorni su 7
Esecuzione del sistema 24 ore su 24, 7 giorni su 7

Il codice sul dispositivo viene sottoposto a debug e viene eseguito senza problemi. L'abbiamo lanciato come servizio, quindi si riavvia se il Raspberry Pi viene riavviato. Per comodità, abbiamo creato un Makefile che aiuta con la distribuzione, l'esecuzione del servizio e la visualizzazione dei log.

. PHONY: installa esegui start stop registro di stato deploy MAIN_FILE:= coffee-pump/main.py SERVICE_INSTALL_SCRIPT:= service_install.sh SERVICE_NAME:= coffee-pump.service

installare:

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

correre:

sudo python3 $(MAIN_FILE)

cominciare:

sudo systemctl start $(SERVICE_NAME)

stato:

sudo systemctl status $(SERVICE_NAME)

fermare:

sudo systemctl stop $(SERVICE_NAME)

tronco d'albero:

sudo journalctl -u coffee-pump --da oggi

distribuire:

rsync -av sensore-setup della pompa del caffè Makefile *.sh pi@XX. XX. XXX. XXX:~/

Puoi trovare questo file e tutti gli script richiesti nel nostro repository.

Passaggio 5: monitoraggio del cloud

Monitoraggio cloud
Monitoraggio cloud
Monitoraggio cloud
Monitoraggio cloud
Monitoraggio cloud
Monitoraggio cloud
Monitoraggio cloud
Monitoraggio cloud

Abbiamo utilizzato Cloud4RPi per implementare un pannello di controllo. Per prima cosa abbiamo aggiunto dei widget per indicare i parametri essenziali del sistema.

A proposito, il widget per la variabile STATUS può utilizzare diversi schemi di colori in base al suo valore (vedi l'immagine sopra).

Abbiamo aggiunto un widget grafico per visualizzare i dati dinamici. Nell'immagine sottostante è possibile vedere il momento in cui la pompa si è accesa e spenta e i rispettivi livelli dell'acqua.

Se analizzi un intervallo di tempo più lungo, puoi vedere i picchi, ovvero quando la pompa era in funzione.

Cloud4RPi ti consente anche di impostare diversi livelli di smoothing.

Passaggio 6: funziona

Image
Image

Funziona! Il pannello di controllo nella sua interezza appare come mostrato di seguito.

Attualmente, la nostra pompa automatica è in funzione da diverse settimane e tutto ciò che dovevamo fare era sostituire le bottiglie d'acqua. Il codice completo per il nostro progetto è disponibile nel nostro repository GitHub.

Consigliato: