Índice:

Bomba de máquina de café inteligente controlada por Raspberry Pi & HC-SR04 Sensor ultrassônico e Cloud4RPi: 6 etapas
Bomba de máquina de café inteligente controlada por Raspberry Pi & HC-SR04 Sensor ultrassônico e Cloud4RPi: 6 etapas

Vídeo: Bomba de máquina de café inteligente controlada por Raspberry Pi & HC-SR04 Sensor ultrassônico e Cloud4RPi: 6 etapas

Vídeo: Bomba de máquina de café inteligente controlada por Raspberry Pi & HC-SR04 Sensor ultrassônico e Cloud4RPi: 6 etapas
Vídeo: ARDUINOLIVE #29 - PROJETOS PARA TCC (#arduinolive) 2024, Julho
Anonim
Bomba de máquina de café inteligente controlada por Raspberry Pi & HC-SR04 Sensor ultrassônico e Cloud4RPi
Bomba de máquina de café inteligente controlada por Raspberry Pi & HC-SR04 Sensor ultrassônico e Cloud4RPi

Em teoria, toda vez que você vai à máquina de café para tomar sua xícara matinal, há apenas uma chance em vinte de você ter de encher o tanque de água. Na prática, porém, parece que a máquina de alguma forma encontra uma maneira de sempre colocar essa tarefa em você. Quanto mais você deseja café, maior a probabilidade de receber a temida mensagem “encher o tanque de água”. Meus colegas pensam o mesmo sobre isso. Sendo os nerds que somos, decidimos implementar a tecnologia que acabaria com isso.

Suprimentos

Nosso Equipamento

Temos uma máquina de café SAECO Aulika Focus. Até hoje, usamos uma bomba manual para encher o tanque de água da máquina com uma garrafa de água padrão de 5 galões (19L).

Nossos Objetivos

  1. Use uma bomba elétrica acionada por algum tipo de controlador ou um microcomputador por meio de um relé.
  2. Tenha uma maneira de medir o nível de água no tanque da máquina de café para que nosso sistema saiba quando reabastecer.
  3. Ter meios para controlar o sistema, de preferência em tempo real a partir de um dispositivo móvel.
  4. Receba notificações (por meio do Slack ou um serviço semelhante) se algo der errado com o sistema.

Etapa 1: Escolha do equipamento

Escolhendo o Equipamento
Escolhendo o Equipamento
Escolhendo o Equipamento
Escolhendo o Equipamento
Escolhendo o Equipamento
Escolhendo o Equipamento
Escolhendo o Equipamento
Escolhendo o Equipamento

A bomba

Uma rápida pesquisa na web mostrará vários modelos de bombas elétricas projetados para sua garrafa de água de escolha. Essas bombas são geralmente controladas por um interruptor LIGA / DESLIGA (por exemplo, Hot Frost A12 ou SMixx ХL-D2). Aqui está a bomba que escolhemos para nosso projeto.

O dispositivo controlador

Tentamos vários dispositivos, mas optamos por um Raspberry Pi devido às seguintes vantagens:

  • Tem um GPIO que nos permite conectar um sensor de proximidade
  • Suporta Python

Instalamos uma nova versão do Raspbian Buster Lite e tudo o que é necessário para executar o Python 3.

Como alternamos a bomba

Para controlar a potência, escolhemos um relé de estado sólido de potência média (12V / 2A) adequado para corrente alternada. O relé conecta a bomba à saída e é controlado pelo pino digital do Raspberry Pi.

Como verificamos o nível da água

Era importante para nós não alterar a construção da máquina de café, por isso decidimos usar o sensor de proximidade ultrassônico HC-SR04 para medir o nível da água.

Imprimimos em 3D uma tampa de tanque de água personalizada com dois orifícios para os emissores do sensor. Encontramos facilmente uma biblioteca do GitHub para o sensor. Nesse ponto, todos os preparativos foram concluídos.

Etapa 2: projetando o sistema

Projetando o Sistema
Projetando o Sistema
Projetando o Sistema
Projetando o Sistema

Lógica do sistema

O sistema é projetado com a seguinte lógica simples em mente:

  • O sistema monitora constantemente a distância entre o sensor e a superfície da água.
  • Sempre que uma mudança na distância ultrapassa um valor limite, o sistema envia informações sobre seu estado para a nuvem.
  • Se a distância ultrapassar o valor máximo permitido (o tanque estiver vazio), o sistema aciona a bomba e a desliga assim que a distância for menor que o valor mínimo permitido.
  • Sempre que o estado do sistema muda (por exemplo, a bomba é ativada), ele informa a nuvem.

Em caso de erro, uma notificação é enviada para um canal do Slack.

Quando a máquina de café está ociosa, o sistema envia um ping para o serviço de nuvem com dados de diagnóstico a cada minuto. Além disso, ele envia seu estado para a nuvem a cada 5 minutos.

Quando a bomba está ativa, o sistema envia dados com mais frequência, mas não mais do que uma vez a cada meio segundo.

def send (nuvem, variáveis, dist, error_code = 0, force = False): pump_on = is_pump_on () percent = calc_water_level_percent (dist) variables ['Distance'] ['value'] = dist variables ['WaterLevel'] [' valor '] = variáveis de porcentagem [' Relay_da_bomba '] [' valor '] = variáveis da bomba_on [' Status '] [' valor '] = status_calc (código_erro, porcentagem, bomba_on)

atual = tempo ()

last_sending_time global se forçar ou atual - last_sending_time> MIN_SEND_INTERVAL: readings = cloud.read_data () cloud.publish_data (leituras) last_sending_time = current

Trabalhando com a bomba

Definimos as seguintes constantes como base para a lógica de operação da bomba.

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

# Bombear

START_PUMP = 1 STOP_PUMP = 0 PUMP_BOUNCE_TIME = 50 # milissegundos PUMP_STOP_TIMEOUT = 5 # segundos

IMPORTANTE: Se você for usar o pino 4, não se esqueça de desabilitar a opção raspi-config de 1 fio para evitar conflitos.

Na inicialização do programa, registramos um retorno de chamada e definimos o estado inicial como OFF.

Aqui está o código para a função que alterna a bomba:

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) # Start / Stop pouring

Conforme definido no código de inicialização acima, quando o relé liga, o seguinte retorno de chamada é chamado:

pump_on = False def pump_relay_handle (pin): global pump_on pump_on = GPIO.input (GPIO_PUMP) log_debug ("Relé da bomba alterado para% d"% pump_on)

No retorno de chamada, salvamos o estado atual da bomba em uma variável. No loop principal do aplicativo, podemos detectar o momento em que a bomba alterna, conforme mostrado abaixo:

def is_pump_on (): global pump_on return pump_on

se GPIO.event_detected (GPIO_PUMP):

is_pouring = is_pump_on () #… log_debug ('[!] Evento de bomba detectado:% s'% ('On' if is_pouring else 'Off')) send (cloud, variables, distance, force = True)

Medindo a distância

É muito fácil medir a distância em direção à superfície da água usando um sensor de proximidade ultrassônico. Em nosso repositório, compartilhamos alguns scripts Python que permitem que você teste um sensor.

Em aplicações reais, as leituras do sensor podem flutuar por causa do efeito de salto do sensor e das oscilações da água. Em alguns casos, as leituras podem estar completamente ausentes. Implementamos uma classe BounceFilter que acumula N valores recentes, descarta os picos e calcula a média das medições restantes. O processo de medição é implementado pelo seguinte algoritmo assíncrono.

# Mantém a última leitura de medições do sensor = BounceFilter (tamanho = 6, discard_count = 1)

reading_complete = threading. Event ()

def wait_for_distance ():

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

se não estiver lendo_complete.wait (MAX_READING_TIMEOUT):

log_info ('Tempo limite do sensor de leitura') return Nenhum return readings.avg ()

def read_distance ():

try: value = hcsr04.raw_distance (sample_size = 5) rounded = value if value for None else round (value, 1) readings.add (arredondado) exceto Exceção como err: log_error ('Erro interno:% s'% err) finalmente: reading_complete.set ()

Você pode encontrar a implementação completa do filtro nas fontes.

Etapa 3: lidar com situações de emergência

Lidando com Situações de Emergência
Lidando com Situações de Emergência
Lidando com Situações de Emergência
Lidando com Situações de Emergência
Lidando com Situações de Emergência
Lidando com Situações de Emergência

E se o sensor queimar, cair ou apontar para uma área errada? Precisávamos de uma forma de denunciar esses casos para que possamos realizar uma ação manual.

Se o sensor falhar em fornecer leituras de distância, o sistema envia o status alterado para a nuvem e gera uma notificação correspondente.

A lógica é ilustrada pelo código abaixo.

distance = wait_for_distance () # Leia a profundidade atual da água se a distância for None: log_error ('Distance error!') Notice_in_background (calc_alert (SENSOR_ERROR)) send (cloud, variables, distance, error_code = SENSOR_ERROR, force = True)

Temos uma faixa operacional do nível de água que deve ser mantida quando o sensor estiver em seu lugar. Testamos se o nível de água atual cai nesta faixa:

# Distância do sensor ao nível de água # com base no tanque de água da máquina de café MIN_DISTANCE = 2 # cm MAX_DISTANCE = 8 # cm

# A distância está fora do intervalo esperado: não comece a derramar

se a distância> MAX_DISTANCE * 2: log_error ('A distância está fora do intervalo:%.2f'% distância) continue

Desligamos a bomba se ela estava ativa quando ocorreu um erro.

if is_pump_on () e prev_distance <STOP_PUMP_DISTANCE + DISTANCE_DELTA: log_error ('[!] Parada de emergência da bomba. Sem sinal de um sensor de distância')

toggle_pump (STOP_PUMP)

Também processamos o caso quando a garrafa fica sem água. Verificamos se o nível de água não muda quando a bomba funciona. Nesse caso, o sistema espera 5 segundos e, em seguida, verifica se a bomba foi desligada. Se não tiver, o sistema implementa o desligamento de emergência da bomba e envia uma notificação de erro.

PUMP_STOP_TIMEOUT = 5 # secsemergency_stop_time = Nenhum

def set_emergency_stop_time (agora, is_pouring):

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

def check_water_source_empty (agora):

retorne Emergency_stop_time e agora> Emergency_stop_time

# --------- loop principal -----------

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 (agora): log_error ('[!] Parada de emergência da bomba. / A fonte de água está vazia') toggle_pump (STOP_PUMP) pump_disabled = True

Acima está um exemplo de um registro de mensagens gerado durante uma parada de emergência.

Etapa 4: executando o sistema 24 horas por dia, 7 dias por semana

Executando o sistema 24 horas por dia, 7 dias por semana
Executando o sistema 24 horas por dia, 7 dias por semana

O código no dispositivo é depurado e executado sem problemas. Nós o lançamos como um serviço, então ele reinicia se o Raspberry Pi for reiniciado. Por conveniência, criamos um Makefile que ajuda na implantação, execução do serviço e visualização de logs.

. PHONY: instalar executar iniciar parar status log implantar MAIN_FILE: = coffee-pump / main.py SERVICE_INSTALL_SCRIPT: = service_install.sh SERVICE_NAME: = coffee-pump.service

instalar:

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

corre:

sudo python3 $ (MAIN_FILE)

começar:

sudo systemctl start $ (SERVICE_NAME)

status:

sudo systemctl status $ (SERVICE_NAME)

Pare:

sudo systemctl stop $ (SERVICE_NAME)

registro:

sudo journalctl -u coffee-pump --desde hoje

implantar:

rsync -av café-bomba sensor-configuração Makefile *.sh pi@XX. XX. XXX. XXX: ~ /

Você pode encontrar este arquivo e todos os scripts necessários em nosso repositório.

Etapa 5: monitoramento em nuvem

Monitoramento de Nuvem
Monitoramento de Nuvem
Monitoramento de Nuvem
Monitoramento de Nuvem
Monitoramento de Nuvem
Monitoramento de Nuvem
Monitoramento de Nuvem
Monitoramento de Nuvem

Usamos Cloud4RPi para implementar um painel de controle. Primeiro, adicionamos widgets para indicar os parâmetros essenciais do sistema.

A propósito, o widget para a variável STATUS pode usar diferentes esquemas de cores com base em seu valor (veja a imagem acima).

Adicionamos um widget de gráfico para exibir dados dinâmicos. Na imagem abaixo você pode ver o momento em que a bomba foi LIGADA e DESLIGADA e respectivos níveis de água.

Se você analisar um intervalo de tempo mais longo, poderá ver picos - é quando a bomba estava funcionando.

O Cloud4RPi também permite definir diferentes níveis de suavização.

Etapa 6: Funciona

Image
Image

Funciona! O painel de controle em sua totalidade se parece com o mostrado abaixo.

Atualmente, nossa bomba automática está funcionando há várias semanas e tudo o que precisamos fazer é substituir as garrafas de água. O código completo do nosso projeto está disponível em nosso repositório GitHub.

Recomendado: