Spisu treści:

Inteligentna pompa do ekspresu do kawy sterowana przez czujnik ultradźwiękowy Raspberry Pi i HC-SR04 oraz Cloud4RPi: 6 kroków
Inteligentna pompa do ekspresu do kawy sterowana przez czujnik ultradźwiękowy Raspberry Pi i HC-SR04 oraz Cloud4RPi: 6 kroków

Wideo: Inteligentna pompa do ekspresu do kawy sterowana przez czujnik ultradźwiękowy Raspberry Pi i HC-SR04 oraz Cloud4RPi: 6 kroków

Wideo: Inteligentna pompa do ekspresu do kawy sterowana przez czujnik ultradźwiękowy Raspberry Pi i HC-SR04 oraz Cloud4RPi: 6 kroków
Wideo: ZLOT MŁODZIEŻY GRYPSUJĄCEJ 2024, Listopad
Anonim
Inteligentna pompa do ekspresu do kawy sterowana przez czujnik ultradźwiękowy Raspberry Pi i HC-SR04 oraz Cloud4RPi
Inteligentna pompa do ekspresu do kawy sterowana przez czujnik ultradźwiękowy Raspberry Pi i HC-SR04 oraz Cloud4RPi

Teoretycznie za każdym razem, gdy idziesz do ekspresu na poranną filiżankę, istnieje tylko jedna na dwadzieścia szans, że będziesz musiał napełnić zbiornik na wodę. W praktyce jednak wydaje się, że maszyna jakoś znajduje sposób, aby zawsze zrzucać na ciebie ten obowiązek. Im więcej chcesz kawy, tym bardziej prawdopodobne jest, że otrzymasz przerażający komunikat „napełnij zbiornik na wodę”. Moi koledzy myślą o tym podobnie. Będąc nerdami, jakimi jesteśmy, postanowiliśmy wdrożyć technologię, która położy temu kres.

Kieszonkowe dzieci

Nasz sprzęt

Posiadamy ekspres do kawy SAECO Aulika Focus. Do dziś używaliśmy pompy ręcznej do napełniania zbiornika wody maszyny ze standardowej butelki o pojemności 19 litrów.

Nasze cele

  1. Użyj pompy elektrycznej napędzanej jakimś sterownikiem lub mikrokomputerem przez przekaźnik.
  2. Mieć sposób na zmierzenie poziomu wody w zbiorniku ekspresu, aby nasz system wiedział, kiedy go uzupełnić.
  3. Mieć środki do kontrolowania systemu, najlepiej w czasie rzeczywistym z urządzenia mobilnego.
  4. Otrzymuj powiadomienia (przez Slack lub podobną usługę), jeśli coś pójdzie nie tak z systemem.

Krok 1: Wybór sprzętu

Wybór sprzętu
Wybór sprzętu
Wybór sprzętu
Wybór sprzętu
Wybór sprzętu
Wybór sprzętu
Wybór sprzętu
Wybór sprzętu

Pompa

Szybkie wyszukiwanie w Internecie pokaże kilka modeli pomp elektrycznych zaprojektowanych dla wybranej przez Ciebie butelki z wodą. Takie pompy są zwykle sterowane wyłącznikiem ON/OFF (na przykład Hot Frost A12 lub SMixx ХL-D2). Oto pompa, którą wybraliśmy do naszego projektu.

Urządzenie sterujące

Wypróbowaliśmy kilka urządzeń, ale zdecydowaliśmy się na Raspberry Pi ze względu na następujące zalety:

  • Posiada GPIO, które pozwala nam podłączyć czujnik zbliżeniowy
  • Obsługuje Pythona

Zainstalowaliśmy nową wersję Raspbian Buster Lite i wszystko, co jest wymagane do uruchomienia Pythona 3.

Jak przełączamy pompę

Aby kontrolować moc, wybraliśmy przekaźnik półprzewodnikowy średniej mocy (12 V/2 A) przystosowany do prądu przemiennego. Przekaźnik łączy pompę z gniazdem i jest kontrolowany przez cyfrowy pin Raspberry Pi.

Jak sprawdzamy poziom wody

Zależało nam na tym, aby nie zmieniać konstrukcji ekspresu, dlatego zdecydowaliśmy się użyć ultradźwiękowego czujnika zbliżeniowego HC-SR04 do pomiaru poziomu wody.

Wydrukowaliśmy w 3D niestandardową pokrywę zbiornika na wodę z dwoma otworami na emitery czujnika. Z łatwością znaleźliśmy bibliotekę GitHub dla czujnika. Na tym etapie wszystkie przygotowania zostały zakończone.

Krok 2: Projektowanie systemu

Projektowanie systemu
Projektowanie systemu
Projektowanie systemu
Projektowanie systemu

Logika systemu

System został zaprojektowany z myślą o następującej prostej logice:

  • System stale monitoruje odległość czujnika od powierzchni wody.
  • Za każdym razem, gdy zmiana odległości przekracza wartość progową, system wysyła informacje o swoim stanie do chmury.
  • Jeśli odległość przekroczy maksymalną dozwoloną wartość (zbiornik jest pusty), system aktywuje pompę i wyłącza ją, gdy odległość jest mniejsza niż minimalna dozwolona wartość.
  • Za każdym razem, gdy zmienia się stan systemu (np. włącza się pompa), informuje o tym chmurę.

W przypadku błędu na kanał Slack wysyłane jest powiadomienie.

Gdy ekspres do kawy jest bezczynny, system co minutę wysyła pingi do usługi w chmurze z danymi diagnostycznymi. Dodatkowo co 5 minut wysyła swój stan do chmury.

Gdy pompa jest aktywna, system wysyła dane częściej, ale nie częściej niż raz na pół sekundy.

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

aktualny = czas()

globalne last_sending_time if force lub current - last_sending_time > MIN_SEND_INTERVAL: odczyty = cloud.read_data() cloud.publish_data(readings) last_sending_time = current

Praca z pompą

Jako podstawę logiki działania pompy definiujemy następujące stałe.

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

# Pompa

START_PUMP = 1 STOP_PUMP = 0 PUMP_BOUNCE_TIME = 50 # milisekund PUMP_STOP_TIMEOUT = 5 # s

WAŻNE: Jeśli zamierzasz używać Pin 4, nie zapomnij wyłączyć opcji 1-Wire raspi-config, aby uniknąć konfliktów.

Przy starcie programu rejestrujemy callback i ustawiamy stan początkowy na OFF.

Oto kod funkcji, która przełącza pompę:

def toggle_pump(wartość): if pump_disabled: return if is_pump_on() != value: log_debug("[x] %s" % ('START' jeśli wartość inaczej 'STOP')) GPIO.setup(GPIO_PUMP, GPIO. OUT) GPIO.output(GPIO_PUMP, wartość) # Rozpocznij/Zatrzymaj nalewanie

Jak zdefiniowano w powyższym kodzie startowym, po włączeniu przekaźnika wywoływane jest następujące wywołanie zwrotne:

pump_on = False def pump_relay_handle(pin): global pump_on pump_on = GPIO.input(GPIO_PUMP) log_debug("Przekaźnik pompy zmieniony na %d" % pump_on)

W wywołaniu zwrotnym zapisujemy aktualny stan pompy do zmiennej. W głównej pętli aplikacji możemy wykryć moment przełączenia pompy, jak pokazano poniżej:

def is_pump_on(): globalna pompa_włączona powrót pompa_włączona

jeśli wykryto GPIO.event_(GPIO_PUMP):

is_pouring = is_pump_on() # … log_debug('[!] Wykryto zdarzenie pompy: %s' % ('Włączone', jeśli is_pouring inne 'Wyłączone')) send(chmura, zmienne, odległość, siła=True)

Pomiar odległości

Dosyć łatwo zmierzyć odległość od powierzchni wody za pomocą ultradźwiękowego czujnika zbliżeniowego. W naszym repozytorium udostępniliśmy kilka skryptów Pythona, które pozwalają przetestować czujnik.

W rzeczywistych zastosowaniach odczyty czujnika mogą się wahać z powodu efektu odbijania się czujnika i oscylacji wody. W niektórych przypadkach odczyty mogą być całkowicie pominięte. Wdrożyliśmy klasę BounceFilter, która gromadzi N ostatnich wartości, odrzuca szczyty i oblicza średnią z pozostałych pomiarów. Proces pomiaru realizowany jest przez następujący algorytm asynchroniczny.

# Zachowuje ostatnie odczyty pomiarów czujnika = BounceFilter(size=6, remove_count=1)

czytanie_kompletne = wątki. Zdarzenie()

def czeka_na_odległość():

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

jeśli nie read_complete.wait(MAX_READING_TIMEOUT):

log_info('Limit czasu odczytu czujnika') return Brak zwraca reads.avg()

def odczyt_odległość():

try: value = hcsr04.raw_distance(sample_size=5) rounded = value if value is None else round(value, 1) readings.add(rounded) z wyjątkiem Exception as err: log_error('Błąd wewnętrzny: %s' % err) w końcu: czytanie_kompletne.set()

Pełną implementację filtra znajdziesz w źródłach.

Krok 3: Postępowanie w sytuacjach awaryjnych

Postępowanie w sytuacjach awaryjnych
Postępowanie w sytuacjach awaryjnych
Postępowanie w sytuacjach awaryjnych
Postępowanie w sytuacjach awaryjnych
Postępowanie w sytuacjach awaryjnych
Postępowanie w sytuacjach awaryjnych

Co się stanie, jeśli czujnik się przepalił, odpadł lub wskazuje na niewłaściwy obszar? Potrzebowaliśmy sposobu zgłaszania takich przypadków, abyśmy mogli podjąć ręczne działania.

Jeśli czujnik nie dostarcza odczytów odległości, system wysyła zmieniony status do chmury i generuje odpowiednie powiadomienie.

Logikę ilustruje poniższy kod.

distance = wait_for_distance() # Odczytaj bieżącą głębokość wody, jeśli odległość jest Brak: log_error('Błąd odległości!') notify_in_background(calc_alert(SENSOR_ERROR)) send(cloud, variable, distance, error_code=SENSOR_ERROR, force=True)

Mamy działający zakres poziomu wody, który powinien być utrzymywany, gdy czujnik jest na swoim miejscu. Sprawdzamy, czy aktualny poziom wody mieści się w tym zakresie:

# Odległość czujnika od poziomu wody# na podstawie zbiornika na wodę ekspresu do kawy MIN_DISTANCE = 2 # cm MAX_DISTANCE = 8 # cm

# Odległość jest poza oczekiwanym zakresem: nie rozpoczynaj nalewania

if distance > MAX_DISTANCE * 2: log_error('Odległość jest poza zakresem: %.2f' % dystans) kontynuuj

Wyłączamy pompę, jeśli była aktywna w momencie wystąpienia błędu.

if is_pump_on() i prev_distance < STOP_PUMP_DISTANCE + DISTANCE_DELTA: log_error('[!] Awaryjne zatrzymanie pompy. Brak sygnału z czujnika odległości')

toggle_pump(STOP_PUMP)

Rozpatrujemy również sprawę, gdy w butelce zabraknie wody. Sprawdzamy, czy poziom wody nie zmienia się podczas pracy pompy. Jeśli tak, system czeka 5 sekund, a następnie sprawdza, czy pompa się wyłączyła. Jeśli tak nie jest, system realizuje awaryjne wyłączenie pompy i wysyła powiadomienie o błędzie.

PUMP_STOP_TIMEOUT = 5 # secsemergency_stop_time = Brak

def set_emergency_stop_time(teraz is_pouring):

global Emergency_stop_time alarm_stop_time = now + PUMP_STOP_TIMEOUT if / is_pouring else Brak

def check_water_source_empty(teraz):

return Emergency_stop_time i teraz > Emergency_stop_time

# --------- główna pętla -----------

jeśli GPIO.event_detected(GPIO_PUMP): is_pouring = is_pump_on() set_emergency_stop_time(teraz, is_pouring) # …

globalna pompa_wyłączona

if check_water_source_empty(now): log_error('[!] Awaryjne zatrzymanie pompy. / Źródło wody jest puste') toggle_pump(STOP_PUMP) pump_disabled = True

Powyżej znajduje się przykład dziennika komunikatów wygenerowanego podczas zatrzymania awaryjnego.

Krok 4: Uruchamianie systemu 24/7

Uruchamianie systemu 24/7
Uruchamianie systemu 24/7

Kod na urządzeniu jest debugowany i działa bez problemów. Uruchomiliśmy go jako usługę, więc uruchamia się ponownie po ponownym uruchomieniu Raspberry Pi. Dla wygody stworzyliśmy Makefile, który pomaga we wdrożeniu, uruchomieniu usługi i przeglądaniu logów.

. PHONY: zainstaluj uruchom start zatrzymaj dziennik stanu wdrożenie MAIN_FILE:= coffee-pump/main.py SERVICE_INSTALL_SCRIPT:= service_install.sh SERVICE_NAME:= coffee-pump.service

zainstalować:

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

biegać:

sudo python3 $ (MAIN_FILE)

początek:

sudo systemctl start $(SERVICE_NAME)

status:

stan sudo systemctl $(SERVICE_NAME)

zatrzymać:

sudo systemctl stop $(SERVICE_NAME)

Dziennik:

sudo journalctl -u pompa do kawy --od dzisiaj

wdrożyć:

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

Możesz znaleźć ten plik i wszystkie wymagane skrypty w naszym repozytorium.

Krok 5: Monitorowanie chmury

Monitorowanie chmury
Monitorowanie chmury
Monitorowanie chmury
Monitorowanie chmury
Monitorowanie chmury
Monitorowanie chmury
Monitorowanie chmury
Monitorowanie chmury

Do wdrożenia panelu sterowania wykorzystaliśmy Cloud4RPi. Najpierw dodaliśmy widżety, aby wskazać podstawowe parametry systemu.

Nawiasem mówiąc, widżet zmiennej STATUS może używać różnych schematów kolorów w zależności od jej wartości (patrz obrazek powyżej).

Dodaliśmy widżet wykresu do wyświetlania danych dynamicznych. Na poniższym obrazku widać moment włączenia i wyłączenia pompy oraz odpowiednie poziomy wody.

Jeśli analizujesz dłuższy okres czasu, możesz zobaczyć szczyty - wtedy pompa pracowała.

Cloud4RPi pozwala również ustawić różne poziomy wygładzania.

Krok 6: To działa

Image
Image

To działa! Panel sterowania w całości wygląda tak, jak pokazano poniżej.

Obecnie nasza automatyczna pompa pracuje już kilka tygodni i wystarczyło nam tylko wymienić bidony. Pełny kod naszego projektu jest dostępny w naszym repozytorium GitHub.

Zalecana: