Оглавление:

Насос для умной кофемашины, управляемый ультразвуковым датчиком Raspberry Pi и HC-SR04 и Cloud4RPi: 6 шагов
Насос для умной кофемашины, управляемый ультразвуковым датчиком Raspberry Pi и HC-SR04 и Cloud4RPi: 6 шагов

Видео: Насос для умной кофемашины, управляемый ультразвуковым датчиком Raspberry Pi и HC-SR04 и Cloud4RPi: 6 шагов

Видео: Насос для умной кофемашины, управляемый ультразвуковым датчиком Raspberry Pi и HC-SR04 и Cloud4RPi: 6 шагов
Видео: Насос умной кофемашины, управляемый Raspberry Pi и ультразвуковым датчиком HC-SR04 2024, Июль
Anonim
Насос для умной кофемашины, управляемый ультразвуковым датчиком Raspberry Pi и HC-SR04 и Cloud4RPi
Насос для умной кофемашины, управляемый ультразвуковым датчиком Raspberry Pi и HC-SR04 и Cloud4RPi

Теоретически, каждый раз, когда вы идете к кофемашине за утренней чашкой, есть только один шанс из двадцати, что вам придется наполнить резервуар для воды. Однако на практике кажется, что машина каким-то образом находит способ всегда перекладывать эту рутинную работу на вас. Чем больше вы хотите кофе, тем больше вероятность того, что вы получите ужасное сообщение «заполните резервуар для воды». Мои коллеги относятся к этому так же. Будучи ботаниками, мы решили внедрить технологию, которая положила бы этому конец.

Запасы

Наше оборудование

У нас есть кофемашина SAECO Aulika Focus. До сих пор мы использовали ручной насос для наполнения резервуара для воды из стандартной бутылки для воды на 5 галлонов (19 л).

Наши цели

  1. Используйте электрический насос, управляемый каким-то контроллером, или микрокомпьютер через реле.
  2. Придумайте способ измерить уровень воды в баке кофемашины, чтобы наша система знала, когда ее нужно долить.
  3. Иметь средства для управления системой, желательно в режиме реального времени с мобильного устройства.
  4. Получайте уведомления (через Slack или аналогичный сервис), если что-то пойдет не так с системой.

Шаг 1: выбор оборудования

Выбор оборудования
Выбор оборудования
Выбор оборудования
Выбор оборудования
Выбор оборудования
Выбор оборудования
Выбор оборудования
Выбор оборудования

Насос

Быстрый поиск в Интернете покажет несколько моделей электрических насосов, предназначенных для выбранной вами бутылки с водой. Такие насосы обычно управляются переключателем ВКЛ / ВЫКЛ (например, Hot Frost A12 или SMixx ХL-D2). Вот насос, который мы выбрали для нашего проекта.

Устройство Контроллера

Мы попробовали несколько устройств, но остановились на Raspberry Pi из-за следующих преимуществ:

  • Он имеет GPIO, который позволяет нам подключать датчик приближения.
  • Он поддерживает Python

Мы установили свежую версию Raspbian Buster Lite и все необходимое для запуска Python 3.

Как мы включаем насос

Для управления мощностью мы выбрали твердотельное реле средней мощности (12 В / 2 А), подходящее для переменного тока. Реле подключает насос к розетке и управляется цифровым выводом Raspberry Pi.

Как мы проверяем уровень воды

Для нас было важно не изменять конструкцию кофемашины, поэтому мы решили использовать ультразвуковой датчик приближения HC-SR04 для измерения уровня воды.

Мы напечатали на 3D-принтере специальную крышку резервуара для воды с двумя отверстиями для излучателей датчика. Мы легко нашли библиотеку GitHub для датчика. На этом все приготовления были закончены.

Шаг 2: проектирование системы

Проектирование системы
Проектирование системы
Проектирование системы
Проектирование системы

Системная логика

Система разработана с учетом следующей простой логики:

  • Система постоянно контролирует расстояние между датчиком и поверхностью воды.
  • Когда изменение расстояния превышает пороговое значение, система отправляет информацию о своем состоянии в облако.
  • Если расстояние превышает максимально допустимое значение (резервуар пуст), система включает насос и выключает его, когда расстояние меньше минимально допустимого значения.
  • Всякий раз, когда состояние системы изменяется (например, включается насос), она сообщает об этом облаку.

В случае ошибки уведомление отправляется в канал Slack.

Когда кофемашина простаивает, система пингует облачный сервис с диагностическими данными один раз в минуту. Кроме того, каждые 5 минут он отправляет свое состояние в облако.

Когда насос активен, система отправляет данные чаще, но не чаще одного раза в полсекунды.

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 '] = процентные переменные [' PumpRelay '] [' value '] = pump_on переменные [' Status '] [' value '] = calc_status (error_code, проценты, pump_on)

текущий = время ()

глобальное last_sending_time, если принудительное или текущее - last_sending_time> MIN_SEND_INTERVAL: readings = cloud.read_data () cloud.publish_data (readings) last_sending_time = current

Работа с насосом

В качестве основы для логики работы насоса мы определяем следующие константы.

Количество контактов GPIO (BCM) GPIO_PUMP = 4 GPIO_TRIGGER = 17 GPIO_ECHO = 27

# Насос

START_PUMP = 1 STOP_PUMP = 0 PUMP_BOUNCE_TIME = 50 # миллисекунд PUMP_STOP_TIMEOUT = 5 # секунд

ВАЖНО: Если вы собираетесь использовать контакт 4, не забудьте отключить опцию 1-Wire raspi-config, чтобы избежать конфликтов.

При запуске программы мы регистрируем обратный вызов и устанавливаем начальное состояние OFF.

Вот код функции, которая включает насос:

def toggle_pump (значение): if pump_disabled: return if is_pump_on ()! = value: log_debug ("[x]% s"% ('START', если значение else 'STOP')) GPIO.setup (GPIO_PUMP, GPIO. OUT) GPIO.output (GPIO_PUMP, value) # Запуск / остановка заливки

Как определено в приведенном выше коде запуска, когда реле включается, вызывается следующий обратный вызов:

pump_on = False def pump_relay_handle (pin): global pump_on pump_on = GPIO.input (GPIO_PUMP) log_debug («Реле насоса изменено на% d»% pump_on)

В обратном вызове мы сохраняем текущее состояние насоса в переменной. В основном цикле приложения мы можем определить момент переключения насоса, как показано ниже:

def is_pump_on (): global pump_on return pump_on

если GPIO.event_detected (GPIO_PUMP):

is_pouring = is_pump_on () #… log_debug ('[!] Обнаружено событие насоса:% s'% ('On', если is_pouring else 'Off')) send (облако, переменные, расстояние, сила = True)

Измерение расстояния

С помощью ультразвукового датчика приближения довольно легко измерить расстояние до поверхности воды. В нашем репозитории мы поделились парой скриптов Python, которые позволяют тестировать датчик.

В реальных приложениях показания датчика могут колебаться из-за эффекта отскока датчика и колебаний воды. В некоторых случаях показания могут отсутствовать полностью. Мы реализовали класс BounceFilter, который накапливает N последних значений, отбрасывает пики и вычисляет среднее значение оставшихся измерений. Процесс измерения осуществляется по следующему асинхронному алгоритму.

# Сохраняет последние измерения сенсораreadings = BounceFilter (size = 6, discard_count = 1)

read_complete = threading. Event ()

def wait_for_distance ():

чтение_complete.clear () thread = threading. Thread (target = read_distance) thread.start ()

если не read_complete.wait (MAX_READING_TIMEOUT):

log_info ('Таймаут датчика чтения') return None return readings.avg ()

def read_distance ():

попробуйте: value = hcsr04.raw_distance (sample_size = 5) rounded = value if value is None else round (value, 1) readings.add (округленно) за исключением Exception as err: log_error ('Internal error:% s'% err) finally: read_complete.set ()

Вы можете найти полную реализацию фильтра в источниках.

Шаг 3: Действия в чрезвычайных ситуациях

Действия в чрезвычайных ситуациях
Действия в чрезвычайных ситуациях
Действия в чрезвычайных ситуациях
Действия в чрезвычайных ситуациях
Действия в чрезвычайных ситуациях
Действия в чрезвычайных ситуациях

Что делать, если сенсор перегорел, или упал, или указал не на ту область? Нам нужен был способ сообщать о таких случаях, чтобы мы могли принять меры вручную.

Если датчик не может предоставить показания расстояния, система отправляет измененный статус в облако и генерирует соответствующее уведомление.

Логика проиллюстрирована приведенным ниже кодом.

distance = wait_for_distance () # Считываем текущую глубину воды, если расстояние равно None: log_error ('Ошибка расстояния!') notify_in_background (calc_alert (SENSOR_ERROR)) send (cloud, variables, distance, error_code = SENSOR_ERROR, force = True)

У нас есть рабочий диапазон уровня воды, который следует поддерживать, когда датчик находится на своем месте. Проверяем, попадает ли текущий уровень воды в этот диапазон:

# Расстояние от датчика до уровня воды # на основе резервуара для воды кофемашины MIN_DISTANCE = 2 # см MAX_DISTANCE = 8 # см

# Расстояние вне ожидаемого диапазона: не начинать заливку

если расстояние> MAX_DISTANCE * 2: log_error ('Distance is out of range:%.2f'% distance) continue

Выключаем насос, если он был активен, когда произошла ошибка.

if is_pump_on () и prev_distance <STOP_PUMP_DISTANCE + DISTANCE_DELTA: log_error ('[!] Аварийная остановка насоса. Нет сигнала от датчика расстояния')

toggle_pump (STOP_PUMP)

Также обрабатываем случай, когда в бутылке заканчивается вода. Проверяем, не меняется ли уровень воды при работе насоса. Если да, система ждет 5 секунд, а затем проверяет, не выключился ли насос. В противном случае система выполняет аварийное отключение насоса и отправляет уведомление об ошибке.

PUMP_STOP_TIMEOUT = 5 # secsemergency_stop_time = Нет

def set_emergency_stop_time (сейчас is_pouring):

global Emergency_stop_time Emergency_stop_time = сейчас + PUMP_STOP_TIMEOUT если / is_pouring еще Нет

def check_water_source_empty (сейчас):

вернуть Emergency_stop_time и теперь> Emergency_stop_time

# --------- основной цикл -----------

если GPIO.event_detected (GPIO_PUMP): is_pouring = is_pump_on () set_emergency_stop_time (сейчас is_pouring) #…

global pump_disabled

if check_water_source_empty (now): log_error ('[!] Аварийная остановка насоса. / Источник воды пуст') toggle_pump (STOP_PUMP) pump_disabled = True

Выше приведен пример журнала сообщений, созданного во время аварийной остановки.

Шаг 4: Работа системы 24/7

Работа системы 24/7
Работа системы 24/7

Код на устройстве отлажен и работает без проблем. Мы запустили его как службу, поэтому он перезагружается при перезагрузке Raspberry Pi. Для удобства мы создали Makefile, который помогает с развертыванием, запуском службы и просмотром журналов.

. PHONY: установить запустить запуск остановить журнал состояний развернуть MAIN_FILE: = coffee-pump / main.py SERVICE_INSTALL_SCRIPT: = service_install.sh SERVICE_NAME: = coffee-pump.service

установить:

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

запустить:

sudo python3 $ (ГЛАВНЫЙ_ФАЙЛ)

Начните:

sudo systemctl start $ (SERVICE_NAME)

положение дел:

sudo systemctl status $ (SERVICE_NAME)

останавливаться:

sudo systemctl stop $ (SERVICE_NAME)

бревно:

sudo journalctl -u coffee-pump - с сегодняшнего дня

развертывать:

rsync -av настройка датчика кофейного насоса Makefile *.sh pi@XX. XX. XXX. XXX: ~ /

Вы можете найти этот файл и все необходимые скрипты в нашем репозитории.

Шаг 5: облачный мониторинг

Облачный мониторинг
Облачный мониторинг
Облачный мониторинг
Облачный мониторинг
Облачный мониторинг
Облачный мониторинг
Облачный мониторинг
Облачный мониторинг

Мы использовали Cloud4RPi для реализации панели управления. Сначала мы добавили виджеты для обозначения основных параметров системы.

Кстати, виджет для переменной STATUS может использовать разные цветовые схемы в зависимости от своего значения (см. Изображение выше).

Мы добавили виджет диаграммы для отображения динамических данных. На изображении ниже вы можете увидеть момент включения и выключения насоса и соответствующие уровни воды.

Если вы проанализируете более длительный промежуток времени, вы увидите пики - это когда насос работал.

Cloud4RPi также позволяет устанавливать различные уровни сглаживания.

Шаг 6: это работает

Image
Image

Оно работает! Панель управления в целом выглядит так, как показано ниже.

В настоящее время наша автоматическая помпа работает несколько недель, и все, что нам нужно сделать, это заменить бутылки с водой. Полный код нашего проекта доступен в нашем репозитории GitHub.

Рекомендуемые: