Você está na página 1de 62

Smart House

D. M. A. F. Silva
G. S. S. Santos

Resumo: Este artigo busca explicar o funcionamento de uma casa inteligente, contendo diversas funcionalidades
relacionadas a uma inteligència artificial.

Palavras-Chave— ​FireBase, microcontrollers, ESP32, 3D Printer, APP, Smart, House, IA, raspberry.

I. I​NTRODUÇÃO

Desde seu princípio a tecnologia tem como foco trazer praticidade, comodidade, segurança e economia.
Pensando nisso, a ideia de automatizar uma residência busca o mesmo objetivo. A automação residencial vem
ganhando espaço no mercado nos últimos tempos, não pela modernidade e status, mas sim pela questão da segurança
e praticidade proporcionada às pessoas, principalmente as deficientes, que não podem se locomover o tempo todo
para executar tarefas simples, como abrir uma janela, porta ou acender uma luz.
Conceitos como casas e prédios inteligentes estão sendo definidos pela aplicação de mecanismos
automáticos e, algumas vezes, pela aplicação de técnicas de Inteligência Artificial. As atuais pesquisas na área de
automação predial se concentram, em sua maioria, na rede de comunicação entre de sensores e atuadores, nos
protocolos usados nessa comunicação e ainda em sistemas de gerenciamento e otimização do uso e aproveitamento de
recursos (Mariotoni; Andrade, 2002). A arquitetura de tais sistemas geralmente é dedicada e centralizada.
Nesse contexto a finalidade deste trabalho é montar um sistema IOT, pois vai integrar sensores e atuadores
em banco de dados que estará nas nuvens, possibilitando o monitoramento e controle através do aplicativo mobile e
comandos de voz.

II. Materiais e Métodos

Para a pesquisa utilizamos o Google Acadêmico e fóruns tanto nacionais como internacionais com as
informações necessárias para o desenvolvimento dos softwares. Além de datasheets para o uso correto dos devidos
módulos.

II.I Hardware
Figura 1: Materiais utilizados

No projeto utilizamos o Kit de voz da google conectado a um raspberry tendo a funcionalidade de atuar como o
IA da casa inteligente, podendo interagir com os moradores; microcontroladores ESP32 para a recepção de dados e
controle da casa; módulo de sensor de som e fitas led rgb endereçadas para o equalizador do som; leds brancos para
iluminação; isopor e acrílicos para a formação da maquete; fios jumpers, canaletas e protoboards para conexões e
afiações; fonte de 12 para a alimentação de todo o sistema eletrônico; um módulo de câmera open mv para a leitura
de placas e acionamento do portão; portão com um pequeno motor de 9v para abertura e fechamento; DHT22 para
monitoramento da temperatura e umidade ambiente

II.II Software

Figura 2: Software utilizados


Para o desenvolvimento do software que atuará no microcontrolador utilizamos a Arduino IDE(1), que é a
mais famosa atualmente, possuindo uma enorme diversidade de bibliotecas para o uso de módulos e funções. Uma das
grandes vantagens da plataforma Arduino está no seu ambiente de desenvolvimento, que usa uma linguagem baseada
no C/C++, linguagem bem difundida, usando uma estrutura simples.
Para a criação do aplicativo foi usada a plataforma App Inventor(3), que por meio de programação visual é
capaz de forma simples e rápida construir pequenos aplicativos com várias funcionalidades, sendo escolhida
principalmente por conta da fácil comunicação com o banco de dados FireBase. O App Inventor é um software web
criado pela universidade americana ​Massachusetts Institute of Technology (MIT) que permite desenvolver
aplicativos Android usando um navegador da Web e um telefone ou emulador conectados.
Você cria aplicativos selecionando componentes para o seu aplicativo e montando blocos que especificam
como os componentes devem se comportar. Toda criação do aplicativo é feita de forma visual, juntando peças com
peças como se fosse um quebra-cabeça. Seu aplicativo aparece no telefone à medida que você adiciona peças a ele,
para que você possa testar seu projeto à medida que você cria. Quando terminar o projeto, você pode empacotar tudo e
produzir um aplicativo executável para instalar em outros celulares.
O Firebase(2) é uma plataforma de desenvolvimento mobile (e web) adquirida pela Google em 2014. Com
foco em ser um back-end completo e de fácil usabilidade, essa ferramenta disponibiliza diversos serviços diferentes
que auxiliam no desenvolvimento e gerenciamento de aplicativos. Para utilizar o Firebase, um console web foi criado
para facilitar a implementação. Neste, o desenvolvedor adiciona um projeto e inclui os serviços que desejar, cada um
com uma explicação de como proceder. Nem todos os serviços são grátis, porém é possível criar um plano conforme
as necessidades do desenvolvedor, caso ele precise de algo a mais do que já é oferecido gratuitamente. Portanto, foi
utilizado a ferramenta database, isto é, o banco de dados da Firebase que é simples e fácil comunicação com o
aplicativo.
Para poder utilizar o Raspberry pi 3 de forma fácil e gráfica, foi utilizado o sistema operacional ​Raspbian(5)
que é um sistema operacional gratuito baseado no Debian otimizado para o hardware Raspberry Pi. Um sistema
operacional é o conjunto de programas e utilitários básicos que fazem o Raspberry Pi funcionar. No entanto, o
Raspbian fornece mais do que um sistema operacional puro: ele vem com mais de 35.000 pacotes, software
pré-compilado empacotado em um bom formato para facilitar a instalação no seu Raspberry Pi.
No sistema operacional Raspbian encontra-se o software Geany(4) que ​é um ​editor de texto
multiplataforma desenvolvido em ​GTK que possui funções básicas para um ​ambiente de desenvolvimento integrado
(​IDE​). Foi desenvolvido com o intuito de prover um ​IDE leve, rápido e com poucas dependências. De fato, pode
rodar em qualquer plataforma que tenha suporte às ​bibliotecas GTK, uma vez que requer apenas as bibliotecas de
tempo de execução (runtime) GTK. Dessa forma, foi utilizado essa IDE para programar códigos em Python que é a
linguagem escolhida para os códigos no raspberry neste projeto.

III. C​ONCEITOS ​B​ÁSICOS


Aqui será explicado os pilares para a compreensão do trabalho:

III.I Automação

São aqueles nos quais um processo é executado por uma máquina sem a participação direta de um operário,
logo é realizado a automatização do processo de acender/desligar as luzes, fechar/abrir portas, controle da piscina,
temperatura e garagem. Além disso, existe automação em processos simples, como agendar, música e informações
que podem ser perguntadas para a casa com auxílio de inteligência artificial.
O processo de automação é implementada por meio de um programa de instruções combinado a um
programa de controle que executa as instruções. A linguagem de programação utilizada no Arduino IDE é a
linguagem ​C/C++ (com pequenas modificações), que é uma linguagem muito tradicional e conhecida que é
utilizada para instruir o ESP32 (microcontrolador) que executará as instruções do algoritmo.
Com o intuito de facilitar o controle e supervisão, fizemos um aplicativo mobile para controle da casa, além
disso é possível executar esses comandos através de comandos de voz com o raspberry.

I.I. Internet das Coisas

A “Internet das Coisas” se refere a uma revolução tecnológica que tem como objetivo conectar os itens
usados do dia a dia à rede mundial de computadores. Cada vez mais surgem eletrodomésticos, meios de transporte
e até mesmo tênis, roupas e maçanetas conectadas à Internet e a outros dispositivos, como computadores e
smartphones​. O termo ​Internet of Things (​ traduzido Internet das coisas) ou IOT, foi introduzido pelo co-fundador
dos laboratórios Auto-ID, Kevin Ashton para descrever um sistema onde a Internet está conectada ao mundo físico
através da computação ubíqua.
De acordo com a Gartner[4], haverá, em 2020, mais de 26 bilhões de dispositivos conectados à internet,
tirando ​tablets, smartphones e computadores​. Assim como diz Lucas Egidio [5], “Portanto, a unificação entre o
mundo real e o mundo virtual ˜ e não só possível, como está a poucos passos de ser atingida”.
No projeto, os sensores enviam informação para o microcontrolador ESP32 e por conseguinte o ESP32 é
comunicado a internet para enviar informações através do Banco de Dados Firebase que ficará armazenado nas
nuvens.

I.II. Microcontroladores

Com a chegada da tecnologia os microcontroladores tem se evoluído com o tempo começando pelo PIC
que era apenas um CI com portas digitais que eram programáveis, e atualmente chegando a aparelhos com WiFi e
até evoluindo com inteligência artificial. Microcontrolador é um microcomputador com um circuito integrado a
qual contém processador, memória (sendo ela RAM e ROM) e periféricos de entrada e saída de dados que são
programáveis, sendo diferentes dos microprocessadores que não possuem periféricos programáveis, sendo eles
externos de acordo com Marconi de Oliveira Júnior[6].
Atualmente existem placas de aprendizagem como a placa Arduino que foi feita exclusivamente para
motivos educacionais, pois em 2005 o professor Massimo Banzi na Itália queria ensinar eletrônica e programação
para seus alunos e os microcontroladores na época eram muito caros, pois então daí surgiu a placa e o software
Arduino[7].
Com a vinda da Indústria 4.0 e o crescimento do IOT eles vêm sendo utilizados cada vez mais eles estão
sendo utilizados e se aprimorando, a cada tecnologia nova surgindo no mercado, sendo hoje não tão difícil ter
acesso a um microcontrolador como antigamente, pois, com a vinda da internet sua aprendizagem fica mais fácil.
Dentre eles os que mais se destacam atualmente seriam os: PIC, ESP, Arduino e CLP.
Portanto, é utilizado o microcontrolador ESP32 por apresentar comunicação wifi, 36 portas de entrada,
comunicação SPI e i2c, portas ADC de 12 bits e entre outros que facilita a execução do projeto.

III.V. Sensores e atuadores

Sensores são componentes eletrônicos que possuem a capacidade de identificar os fenômenos físicos e
químicos do mundo real. Visto que o microcontrolador é um computador simples, ele só pode processar sinais
elétricos inseridos nas suas portas. Dessa maneira, para que capte grandezas físicas (temperatura, umidade e
tempo) e transforme em dados compreensíveis ao ESP32 são utilizados os sensores.
Assim que os sensores são lidos, o dispositivo tem a informação necessária para decidir como reagir. O
processo de tomada de decisão é realizado pelo microcontrolador e a reação é executada por atuadores. Nesse
projeto possui sensores de nível de água tipo bóia que irá monitorar o nível da água da caixa d’água e sensor de
temperatura DHT22, além disso contém um câmera OpenCV que é utilizado como sensor para verificação de
imagens.
Como atuadores é utilizado servo motor para abrir portas, motor para abrir o portão da garagem, motor
bomba d’água para encher caixa d’água e lâmpadas.

I. PASSOS DO PROJETO

Primeiramente, o projeto surgiu como uma ideia de elaborar uma casa automatizada e prática com o Kit
Voice da Google que permite que você construa seu próprio processador de linguagem natural e conecte-o ao
serviço Google Assistant ou Cloud Speech-to-Text, permitindo fazer perguntas e emitir comandos de voz em seus
programas. Tudo isso se encaixa em um pequeno cubo de papelão, alimentado por um Raspberry Pi.

I.I. RASPBERRY

II.I INSTALAÇÃO

O primeiro passo para o projeto foi preparar o microprocessador Raspberry pi 3 para adicionar o Kit voice da
Google. Portanto, foi esses seguintes passos:

1. Formatar o Cartão SD
Utilizamos um cartão SD de 32Gb de classe 10 e foi formatado o cartão para tipo FAT32 com o software SD
Card Formatter que pode ser instalado neste link “​https://www.sdcard.org/downloads/formatter/eula_windows/​”.
2. Instalação do Sistema Operacional do raspberry
Primeiramente deve fazer o download do pacote NOOBS que é um instalador fácil do sistema operacional
que contém ​Raspbian​, pode ser encontrado neste link “​https://www.raspberrypi.org/downloads/noobs/​” para
download.

Após download do pacote zip deve fazer a extração do arquivo.


Então, recorte os arquivos dentro da pasta e cole no cartão SD formatado.

Finalmente, energize o raspberry com uma fonte com corrente mínima de 3A/5v, utilize um cabo HDMI e
um monitor para poder visualizar a parte gráfica do raspberry, além disso é necessário mouse e teclado com entradas
USB que será acoplado no raspberry. Portanto, insira o cartão SD com os arquivos do instalador do Raspbian.
Após ligar a fonte, espere iniciar o Raspberry e deve aparecer as opções de instalação. Selecione o Wifi e
configure, depois escolha a opção do sistema operacional Raspbian e faça a instalação.
3. Configurações básicas
Deve acessar o menu do Raspberry (CLICAR NA FRAMBOESA NO CANTO SUPERIOR) e acessar
‘Preferences’ e logo após ‘Raspberry pi configuration’. Portanto, configure as informações básicas, como
língua, horário e WiFi.
II.II Kit voice da Google

O projeto utilizou o Kit Voice da Google para fazer a conversa de homem e máquina, além disso
possibilita a interação com Assistent SDK da google, isto é, a inteligência artificial da google. E também utiliza
o Kit Voice para fazer a transformação de voz para texto e dessa forma executar comandos. Os passos que foram
seguidos serão demonstrado aqui e é referente ao site “​https://aiyprojects.withgoogle.com/voice-v1/​”:

1. OBTENHA A IMAGEM DO SISTEMA VOICE KIT


Primeiro deve acessar o site “​https://github.com/google/aiyprojects-raspbian/releases​” e fazer download da
imagem do sistema do Voice Kit em algum computador.

Logo após faça a instalação do aplicativo “Etcher” em algum computador para fazer atualização da imagem
do Cartão SD. Então, insira o cartão SD neste computador e atualize a imagem com o arquivo img.xz que já foi feito
download anteriormente.
2. MONTE O HARDWARE
O Kit Voice contém estes periféricos:
Após a verificação dos componentes deve montar a caixa, faça os seguintes passos:
Inicializando a caixa:
3. TESTES NECESSÁRIOS
4. COMUNICAÇÃO SSH
Para facilitar o processo de credenciais e chaves, faça uma comunicação SSH com raspberry e algum
computador que tenha Google Chrome como navegador, siga esses passos:
5. OBTER CREDENCIAIS
Para executar os arquivos da imagem Kit voice da Google, precisa-se de uma “chave” e para isso é preciso
fazer credenciais no console Cloud da Google e ativar as API’s que iremos usar. Portanto, siga esses passos com o
computador que esteja fazendo a comunicação SSH com o raspberry:
6. API Cloud Speech-Text
Nesse projeto será utilizado a API Speech-Text que tem a capacidade de transformar a voz em texto,
posteriormente podemos utilizar para comandos. Primeiramente devemos ativar o faturamento, pois esta API é paga,
logo em seguida ativar a API e adicionar sua credencial. Então faça (Recomendo que faça essa parte no próprio
raspberry, porém é possível executar esta parcela na máquina que possui a comunicação SSH):
Para os próximos passos é necessário que o aplicativo da API Assistant SDK e Speech-Text esteja
funcionando, pois iremos mesclar essas APIs e adicionar comandos. Portanto faça um backup do aplicativo, pois
iremos utilizar este aplicativo como base.
7. Elaborando o aplicativo
Para facilitar a documentação, irei mostrar o código que é feito em Python na IDE Geany no Raspberry que
foi salvo no arquivo da copia, isto é, “cloudspeech_demo.py”.

##########################CÓDIGO#############################

#Bibliotecas padrões necessárias


import argparse
import locale
import logging
import signal
import sys

#Bibliotecas de tempo utilizadas


import time
from datetime import datetime

#Biblioteca para executar arquivos .mp3


import pygame

#bibliotecas do raspberry e API da google


from aiy​.​assistant​.​grpc import AssistantServiceClientWithLed
from aiy​.​board import Board​,​ Led
from aiy​.​cloudspeech import CloudSpeechClient
import aiy​.​voice​.​tts

#biblioteca do protocolo MQTT (comunicação com esp32)


import paho​.​mqtt​.​client as mqtt

#Definição do protocolo MQTT


MQTT_HOST ​=​ ​"test.mosquitto.org"​ #broker utilizado
MQTT_PORT ​=​ ​1883​ #porta padrão utilizado
MQTT_KEEPALIVE_INTERVAL ​=​ ​10
MQTT_TOPIC ​=​ ​"ifmt/casa"​ #tópico que irá escrever utilizado
MQTT_MSG ​=​ ​"hello MQTT"

#Variável que contém a data/hora


now ​=​ datetime​.​now​()

#inicializando o pygame
pygame​.​init​()

'''Função que irá executar a API Assistant SDK da Google, ou seja, uma assistente pessoal para fazer
perguntas​,​ agendar e entre outras'''
def start_conversation​():
with Board​()​ as board​:
assistant ​=​ AssistantServiceClientWithLed​(​board​=​board​,
volume_percentage​=​100​,
language_code​=​'pt BR'​)
​while​ True​:
print​(​'Conversação iniciada!'​)
assistant​.​conversation​()

'''UM dicionário(que contém os comandos) que foi criado para auxiliar a API Speech-Text, pois irá
verificar se foi dita essas frases e irá retornar as respectivas chaves'''
def get_hints​(​language_code​):
​return​ ​{​'ligar luz da sala'​:​ 'D'​,
'apagar luz da sala'​:​ 'd'​,
'ligar luz da suíte'​:​ 'E'​,
'apagar luz da suíte'​:​ 'e'​,
'ligar luz da cozinha'​:​ 'F'​,
'apagar luz da cozinha'​:​ 'f'​,
'ligar luz da garagem'​:​ 'G'​,
'apagar luz da garagem'​:​ 'g'​,
'ligar luz do banheiro'​:​ 'H'​,
'apagar luz do banheiro'​:​ 'h'​,
'ligar luz do quarto'​:​ 'I'​,
'apagar luz do quarto'​:​ 'i'​,
'abrir casa'​:​ 'L'​,
'fechar casa'​:​ 'l'​,
'abrir quarto'​:​ 'B'​,
'fechar quarto'​:​ 'b'​,
'abrir sala'​:​ 'A'​,
'fechar sala'​:​ 'a'​,
'poste azul'​:​ 'M'​,
'poste verde' ​:​ 'N'​,
'poste vermelho'​:​ 'O'​,
'poste branco'​:​ 'P'​,
'desligar poste' ​:​ 'm'​}

#Função que irá utilizar o método .locale para descobrir a linguagem utilizada (pt-br)
def locale_language​():
language​,​ _ ​=​ locale​.​getdefaultlocale​()
​return​ language

# Define o evento a ser publicado


def on_publish​(​client​,​ userdata​,​ mid​):
print ​(​"Message publicada..."​)

#Função principal (main)


def main​():
​#variávei booleanas para auxiliar as quais processos já foram
confirma ​=​ False
passo2 ​=​ False

​#Variável que será para se tornar cliente no broker definido


mqttc ​=​ mqtt​.​Client​()

​# Registra a função de retorno de chamada de publicação


mqttc​.​on_publish ​=​ on_publish

​#Conectando com MQTT broker


mqttc​.​username_pw_set​(​None​,​ None​)

​#argumento de nível para trazer informações detalhadas de bugs


logging​.​basicConfig​(​level​=​logging​.​DEBUG​)

'''Função que permite definir manipuladores personalizados a serem executado


quando um sinal é recebido​.​'''
signal​.​signal​(​signal​.​SIGTERM​,​ lambda signum​,​ frame​:​ sys​.​exit​(​0​))

​#Criando um objeto analisador e informar quais argumentos esperar. O analisador pode então ser
usado para processar os argumentos da linha de comando quando o programa for executado.
parser ​=​ argparse​.​ArgumentParser​(​description​=​'Example de serviço assistente.'​)

​#Adicionando os argumentos ao objeto analisador


parser​.​add_argument​(​'--language'​,​ ​default​=​locale_language​())

​#Definindo a variável que analisa as linhas de comandos do analisador, no caso é a linguagem local
args ​=​ parser​.​parse_args​()

​#Demonstra na tela a linguagem utilizada (pt-br)


logging​.​info​(​'Inicializando com a linguagem...'​,​ args​.​language​)

​#Definindo a variável que contém o dicionário dos comandos


hints ​=​ get_hints​(​args​.​language​)

​#Definindo a variável que contém a inicialização da API Speech-Text


client ​=​ CloudSpeechClient​()

​#Demonstra na tela os elementos do dicionário(hints) dos comandos


logging​.​info​(​'Comandos'​)
​for​ hint in hints​:
logging​.​info​(​hint​.​title​())

​#abrindo os arquivos Board() com o arquivo board que será finalizado após o término do bloco
with Board​()​ as board​:
​#definindo as configurações da API Assistant SDD, como linguagem, saída e volume
assistant ​=​ AssistantServiceClientWithLed​(​board​=​board​,
volume_percentage​=​100​,
language_code​=​args​.​language​)

​#Inicializando o loop
​while​ True​:
​#conectando ao broker
mqttc​.​connect​(​MQTT_HOST​,​ MQTT_PORT​,​ MQTT_KEEPALIVE_INTERVAL​)

​#obtendo as horas
horas ​=​ str​(​now​.​hour​)
horas ​=​ horas​.​strip​()
horas ​=​ ​int​(​horas​)

​#Obtendo a fala que foi dita na placa em texto através da API Speech-Text
text ​=​ client​.​recognize​(​language_code​=​args​.​language​,
hint_phrases​=​hints​)

​#Caso não tenha dito nada


​if​ text is None​:
logging​.​info​(​'Você não disse nada.'​)
​continue

​#Colocando todas as letras minúsculas na string da voz


text ​=​ text​.​lower​()

​#Demonstrando na tela o que foi dito


logging​.​info​(​'Você disse: "%s"' ​%​ text​)

​#Retornando valor do item com a chave especificada no dicionário caso a string 'text'
possui um comando do dicionário hints{}
hint ​=​ hints​.​get​(​text​)

​#Caso o que foi dito for 'olá', irá começar os processos:


​if​ 'olá' in text​:
​#Respondendo o usuário de acordo com horário local
print​(​horas​)
​if​ ​(​horas ​>=​ ​6​)​ ​and​ ​(​horas ​<​ ​13​):

pygame​.​mixer​.​music​.​load​(​'/home/pi/AIY-projects-python/src/examples/voice/bomdia.
mp3'​)
pygame​.​mixer​.​music​.​play​()
time​.​sleep​(​3​)
print​(​'Bom dia'​)
​ lif ​(​horas ​>=​ ​13​)​ ​and​ ​(​horas ​<​ ​18​):
e

pygame​.​mixer​.​music​.​load​(​'/home/pi/AIY-projects-python/src/examples/voice/renomea
r.mp3'​)
pygame​.​mixer​.​music​.​play​()
time​.​sleep​(​3​)
print​(​'Boa tarde'​)
​ lif​ ​(​horas ​>=​ ​18​)​ ​and​ ​(​horas ​<​ ​23​):
e

pygame​.​mixer​.​music​.​load​(​'/home/pi/AIY-projects-python/src/examples/voice/boanoit
e.mp3'​)
pygame​.​mixer​.​music​.​play​()
time​.​sleep​(​3​)
print​(​'Boa noite'​)
​ ####################################################
#

​#Confirmando que o primeiro(cumprimento) passo foi executado


confirma ​=​ True

​#Caso o usuário já passou pelo primeiro passo, faça:


​if​ confirma ​==​ True​:
print​(​'fale'​)
​#obtendo nova ordem do usuário e colocando na variável text2
text2 ​=​ client​.​recognize​(​language_code​=​args​.​language​,
hint_phrases​=​hints​)
​#caso o usuário dizer nada
​if​ text2 is None​:
logging​.​info​(​'Você não disse nada.'​)
​continue
​#Manipulando o string text2
text2 ​=​ text2​.​lower​()
logging​.​info​(​'Você disse: "%s"' ​%​ text2​)
​#Tornando a variável que confirma o primeiro passo em False, ou seja, pronto para
executar novamente o processo
confirmar ​=​ False

​#Comparando se o usuário disse alguma ordem no dicionário


​if​ text2 in hints​.​keys​()​ ​and​ confirmar ​==​ False​:
print​(​'ok'​)
print​(​hints​[​text2​])​ #demonstra qual ordem foi dita
MQTT_MSG ​=​ hints​[​text2​]​ #armazena a chave ​do​ elemento que foi dito
mqttc​.​publish​(​MQTT_TOPIC​,​MQTT_MSG​)​ #envia por mqtt a chave ​do​ comando dito
#pergunta ao usuário se precisa de algo
pygame​.​mixer​.​music​.​load​(​'/home/pi/AIY-projects-python/src/examples/voice/precisa.mp3
'​)
pygame​.​mixer​.​music​.​play​()
time​.​sleep​(​5​)

​#Variável que confirma que o passo de comandos foi feito


passo2 ​=​ True

​#Se caso o que foi dito não for comando, irá começar a conversação com a Assistant
SDK, pois supõe que o usuário tenha outra intenção como perguntas sobre clima, tempo ou até mesmo
histórica
​else​:
​#inicializa a função de conversação
assistant​.​conversation​()

​#Caso o usuário tenha dito algum comando, faça:


​if​ passo2 ​==​ True​:
print​(​'fale'​)
​#obtendo nova ordem do usuário
text3 ​=​ client​.​recognize​(​language_code​=​args​.​language​,
hint_phrases​=​hints​)
​#caso não for dito nada pelo usuário
​if​ text3 is None​:
logging​.​info​(​'Você não disse nada.'​)
​continue

​#manipulando a string do que foi dito


text3 ​=​ text3​.​lower​()
logging​.​info​(​'Você disse: "%s"' ​%​ text3​)

​#Tornando a variável que confirma o segundo passo em False, ou seja, pronto para
executar novamente o processo
passo2 ​=​ False

​#Comparando se o usuário disse alguma ordem no dicionário, se True, faça:


​if​ text3 in hints​.​keys​()​ ​and​ passo2 ​==​ False​:
#Demonstrando o chave ​do​ comando dito
print​(​hints​[​text3​])
#Armazenando a chave ​do​ comando especificado
MQTT_MSG ​=​ hints​[​text3​]
​#Enviando a chave por via MQTT para o esp32
mqttc​.​publish​(​MQTT_TOPIC​,​MQTT_MSG​)

#Agradece o usuário
pygame​.​mixer​.​music​.​load​(​'/home/pi/AIY-projects-python/src/examples/voice/obrigado.mp
3'​)
pygame​.​mixer​.​music​.​play​()
time​.​sleep​(​3​)

​#Caso o usuário disse 'não', encerra o processo


​ elif​ text3 in 'não'​:

pygame​.​mixer​.​music​.​load​(​'/home/pi/AIY-projects-python/src/examples/voice/obrigado.mp
3'​)
pygame​.​mixer​.​music​.​play​()
time​.​sleep​(​3​)
​continue

​#senão nenhuma das opções foram ditas, será iniciado a conversação com Assistant SDK
​else​:
​#inicializa a função conversação
assistant​.​conversation​()

​#Reseta todas as variáveis para um novo processo


text ​=​ ''
text2 ​=​ ''
text3 ​=​ ''
confirma ​=​ False
passo2 ​=​ False

​#Desconecta o cliente do MQTT


mqttc​.​disconnect​()
if​ __name__ ​==​ '__main__'​:
main​()
##########################################################################

II.III. ESP32

No projeto foi utilizado o microcontrolador ESP32 que receberá as ordens do raspberry via MQTT e
executará as ordens, ou recebe as ordens pelo aplicativo mobile via o banco de dados Firebase. Todo o código foi
escrito em C++ na IDE Arduino. Este é o código:

##########################CÓDIGO#############################

//Biblioteca necessários para conexão da internet e protocolo MQTT


#include <WiFi.h>
#include <PubSubClient.h>
//Biblioteca dos leds RGB
#include <Adafruit_NeoPixel.h>
//biblioteca do bando Firebase
#include "FirebaseESP32.h"
//Biblioteca do motor servo
#include <ESP32_Servo.h>
//Biblioteca do sensor dht
#include <SimpleDHT.h>

//Definindo o pino do sensor DHT e criando o objeto do sensor DHT


uint8_t dados ​=​ ​26​;
SimpleDHT22 dht22​(​dados​);

//Criando os objetos dos motores servos


Servo servo_sala​;
Servo servo_quarto​;
Servo servo_casa​;

//Criando objeto da fila de led RGB contendo 10 leds


Adafruit_NeoPixel luzes ​=​ Adafruit_NeoPixel​(​10​,​ ​15​,​ NEO_GRB ​+​ NEO_KHZ800​);

//Configurações do WIFI
#define WIFI_SSID "Elevador_Server" ​// insira seu nome do wifi
#define WIFI_PASSWORD "LAB@E117" ​//insira a senha do wifi

//Configurações do protocolo MQTT


const​ ​int​ mqttPort ​=​ ​1883​;​ ​//port
const​ ​char​*​ mqtt Topic Sub ​=​ ​"ifmt/casa"​;​ ​//tópico que será assinado
const​ ​char​*​ mqttServer ​=​ ​"test.mosquitto.org"​;​ ​//server
char​ valor​[​20​];​ ​//vetor que armazena a mensagem recebida

//Tornando o eps32 em client


WiFiClient espClient​;
PubSubClient client​(​espClient​);

//Definições do banco de dados Firebase, hospedagem e token


#define FIREBASE_HOST "https:​//magdaia-mgkjts.firebaseio.com/"
#define FIREBASE_AUTH "aNsWlbtHzsatYWSsB6hYVXwrQHARfv18Oo3gnN2e"
//Criando o objeto banco de dados
FirebaseData firebaseData​;

//Criando as string que armazena os nomes das tabelas do banco de dados


String tabela_led ​=​ ​"/led"​;
String tabela_servo ​=​ ​"/motores"​;
String tabela_abajur ​=​ ​"/abajur"​;
String tabela_sensor ​=​ ​"/temperatura"​;
String tabela_caixa ​=​ ​"/caixa"​;
String tabela_poste ​=​ ​"/poste"​;
String high ​=​ ​"1"​;
String low ​=​ ​"0"​;

//Variáveis para a execução da caixa d'água


int​ Bomba ​=​ ​18​;
int​ BotaoBomba​,​ BotaoModo​,​ auxnivel​;
unsigned​ ​long​ tempo​;
int​ nivel ​=​ ​0​;
//Definições das portas do sensores da caixa d'água
#define sens1 19
#define sens2 21
#define sens3 1
#define sens4 3

//Variáveis para determinar a cor dos poste(RGB)


const​ ​int​ azul ​=​ ​12​;​ ​//M
const​ ​int​ verde ​=​ ​13​;​ ​//N
const​ ​int​ vermelho ​=​ ​14​;​ ​//O

//Definindo as portas dos LEDS e motores da Casa,respectivamente as suas variáveis booleanas para
ajudar no processo
#define garagem 28 ​//C
bool​ estado_garagem ​=​ ​false​;
#define porta_sala 22 ​//A
bool​ estado_sala ​=​ ​false​;
int​ posicao_sala ​=​ ​0​;
#define porta_quarto 26 ​//B
bool​ estado_quarto ​=​ ​false​;
int​ posicao_quarto ​=​ ​0​;
#define porta_casa 25 ​//L
bool​ estado_casa ​=​ ​false​;
int​ posicao_casa ​=​ ​0​;
#define fita_led 15 ​//K
bool​ estado_fita ​=​ ​false​;
#define led_sala 33 ​//D
bool​ estado_lsala ​=​ ​false​;
#define led_quarto1 32 ​//E
bool​ estado_lquarto1 ​=​ ​false​;
#define led_cozinha 35 ​//F
bool​ estado_lcozinha ​=​ ​false​;
#define led_garagem 34 ​//G
bool​ estado_lgaragem ​=​ ​false​;
#define led_banheiro 39 ​//H
bool​ estado_lbanheiro ​=​ ​false​;
#define led_quarto2 36 ​//I
bool​ estado_lquarto2 ​=​ ​false​;

//Definindo uma porta para o sensor da câmera


#define openmv 23 ​//J
void​ setup​()​ ​{
​//Definindo os números das portas e modos
pinMode​(​sens1​,​ INPUT​);
pinMode​(​sens2​,​ INPUT​);
pinMode​(​sens3​,​ INPUT​);
pinMode​(​sens4​,​ INPUT​);
pinMode​(​Bomba​,​ OUTPUT​);
pinMode​(​azul​,​ OUTPUT​);
pinMode​(​verde​,​ OUTPUT​);
pinMode​(​vermelho​,​ OUTPUT​);
pinMode​(​porta_sala​,​ OUTPUT​);
pinMode​(​porta_quarto​,​ OUTPUT​);
pinMode​(​porta_casa​,​ OUTPUT​);
pinMode​(​led_sala​,​ OUTPUT​);
pinMode​(​led_quarto1​,​ OUTPUT​);
pinMode​(​led_quarto2​,​ OUTPUT​);
pinMode​(​led_cozinha​,​ OUTPUT​);
pinMode​(​led_garagem​,​ OUTPUT​);
pinMode​(​led_banheiro​,​ OUTPUT​);
pinMode​(​openmv​,​ INPUT​);

​//inicializando a serial
Serial​.​begin​(​9600​);

luzes​.​begin​();​ ​//inicializando a fita led rgb

​//inicializando os servos
servo_sala​.​attach​(​porta_sala​);
servo_quarto​.​attach​(​porta_quarto​);
servo_casa​.​attach​(​porta_casa​);

​//conectando ao WIFI
WiFi​.​begin​(​WIFI_SSID​,​ WIFI_PASSWORD​);
​while​ ​(​WiFi​.​status​()​ ​!=​ WL_CONNECTED​)​ ​{
delay​(​300​);​ ​//delay de 300ms para uma nova tentativa de conexão
​ }

​//Definindo as configuração do broker MQTT


client​.​setServer​(​mqttServer​,​ mqttPort​);
client​.​setCallback​(​callback​);

​//Conectando os esp32 como cliente no broker


​while​ ​(!​client​.​connected​())​ ​{
Serial​.​println​(​"Conectando ao Broker MQTT..."​);
​if​ ​(​client​.​connect​(​"ESP_Casa"​))​ ​{
Serial​.​println​(​"Conectado"​);
​}​ ​else​ ​{
Serial​.​print​(​"falha estado "​);
Serial​.​print​(​client​.​state​());
delay​(​2000​);
​}
​ }

​//subscreve no tópico
client​.​subscribe​(​mqttTopicSub​);

​//Inicializando o firebase
Firebase​.​begin​(​FIREBASE_HOST​,​ FIREBASE_AUTH​);
Firebase​.​reconnectWiFi​(​true​);​ ​//reconexão com Wifi seja verdadeira
​//No banco de dados 'firebaseData', na tabela 'string', no registro '/string' e acionando no campo a
variável 'float'
​//enviarString(bancodedados, tabela + registro, campo(string));
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ ​"/led_sala"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ ​"/led_quarto1"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ ​"/led_quarto2"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ ​"/led_cozinha"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ ​"/led_garagem"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ ​"/led_banheiro"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ ​"/led_poste"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_servo ​+​ ​"/porta_sala"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_servo ​+​ ​"/porta_quarto"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_servo ​+​ ​"/porta_casa"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_caixa ​+​ ​"/nivel"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_caixa ​+​ ​"/botao"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_caixa ​+​ ​"/botao"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_abajur ​+​ ​"/ledred"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_abajur ​+​ ​"/ledgreen"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_abajur ​+​ ​"/ledblue"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_abajur ​+​ ​"/automatico"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_sensor ​+​ ​"/umidade"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_poste ​+​ ​"/verde"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_poste ​+​ ​"/vermelho"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_poste ​+​ ​"/azul"​,​ ​"0"​);
Firebase​.​setString​(​firebaseData​,​ tabela_poste ​+​ ​"/branco"​,​ ​"0"​);
}

//Função que recebe a mensagem no tópico escrito


void​ callback​(​char​*​ topic​,​ byte​*​ payload​,​ ​unsigned​ ​int​ length​)​ ​{
​//armazena msg recebida em uma string
payload​[​length​]​ ​=​ '\0'​;
String strMSG ​=​ String​((​char​*)​payload​);
Serial​.​print​(​"Mensagem chegou do tópico: "​);
Serial​.​println​(​topic​);
strMSG​.​toCharArray​(​valor​,​ ​20​);​ ​//armazenando a mensagem recebida na char valor
Serial​.​print​(​"Mensagem:"​);
Serial​.​print​(​strMSG​);
Serial​.​println​();
}

//Função para reconexão ao MQTT


void​ reconect​()​ ​{
​// Loop caso não tenha conectado
​while​ ​(!​client​.​connected​())​ ​{
Serial​.​print​(​"Tentando reconexão com MQTT "​);
​// caso estiver conectado
​if​ ​(​client​.​connect​(​"ESP_Casa"​))​ ​{
Serial​.​println​(​"conectado"​);

client​.​subscribe​(​"ifmt/casa"​);
​}​ ​else​ ​{
Serial​.​print​(​"falhou, rc="​);
Serial​.​print​(​client​.​state​());
Serial​.​println​(​"Recomeçar em 5 segundos"​);
​// Tempo de 5 segundos
delay​(​5000​);
​ }
​}
}

//-------------------------------------------------------------------------------//
//Função para as cores dos poste
void​ vermelhoFuncao​()​ ​{
digitalWrite​(​azul​,​ LOW​);
digitalWrite​(​verde​,​ LOW​);
digitalWrite​(​vermelho​,​ HIGH​);
}
void​ azulFuncao​()​ ​{
digitalWrite​(​azul​,​ HIGH​);
digitalWrite​(​verde​,​ LOW​);
digitalWrite​(​vermelho​,​ LOW​);
}
void​ verdeFuncao​()​ ​{
digitalWrite​(​azul​,​ LOW​);
digitalWrite​(​verde​,​ HIGH​);
digitalWrite​(​vermelho​,​ LOW​);
}
void​ brancoFuncao​()​ ​{
digitalWrite​(​azul​,​ HIGH​);
digitalWrite​(​verde​,​ HIGH​);
digitalWrite​(​vermelho​,​ HIGH​);
}
void​ desligarFuncao​()​ ​{
digitalWrite​(​azul​,​ LOW​);
digitalWrite​(​verde​,​ LOW​);
digitalWrite​(​vermelho​,​ LOW​);
}
//-------------------------------------------------------------------------------//

//Função dos postes


void​ iluminacao​()​ ​{
​//Recebe os valore dos registro corresponde iluminação dos poste
Firebase​.​getString​(​firebaseData​,​ tabela_poste ​+​ ​"/branco"​);
String estado_branco ​=​ firebaseData​.​stringData​();​ ​//armazena nas variáveis os valores dos campos
Firebase​.​getString​(​firebaseData​,​ tabela_poste ​+​ ​"/vermelho"​);
String estado_vermelho ​=​ firebaseData​.​stringData​();
Firebase​.​getString​(​firebaseData​,​ tabela_poste ​+​ ​"/azul"​);
String estado_azul ​=​ firebaseData​.​stringData​();
Firebase​.​getString​(​firebaseData​,​ tabela_poste ​+​ ​"/verde"​);
String estado_verde ​=​ firebaseData​.​stringData​();
​//liga a luz poste conforme está escrito na tabela /poste
​if​ ​(​estado_vermelho ​==​ high​)​ ​{
vermelhoFuncao​();
​}
​if​ ​(​estado_azul ​==​ high​)​ ​{
azulFuncao​();
​}
​if​ ​(​estado_verde ​==​ high​)​ ​{
verdeFuncao​();
​}
​if​ ​(​estado_branco ​==​ high​)​ ​{
brancoFuncao​();
​}
}

//Função do DHT
void​ temperatura​()​ ​{
​int​ status​;
​float​ temp​,​ umid​;​ ​//variáveis auxiliares para a leitura do sensor
status ​=​ dht22​.​read2​(​dados​,​ ​&​temp​,​ ​&​umid​,​ NULL​);​ ​//Leitura da temperatura e umidade do sensor DHT22
String temperatura ​=​ String​(​temp​);
String umidade ​=​ String​(​umid​);
​//Envia os valores da umidade/temperatura para a tabela /DHT
Firebase​.​setString​(​firebaseData​,​ tabela_sensor ​+​ ​"/temperatura"​,​ temperatura​);
Firebase​.​setString​(​firebaseData​,​ tabela_sensor ​+​ ​"/umidade"​,​ umidade​);
}

//Função da caixa d'água


void​ caixa​()​ ​{
​//recebe o valor da caixa d'água (para ligar a bomba ou não)
Firebase​.​getString​(​firebaseData​,​ tabela_caixa ​+​ ​"/led_botao"​);
String estado_botao_caixa ​=​ firebaseData​.​stringData​();
​//Verifica o nív ​ el que está a caixa d'água através dos sensores
​if​ ​(​digitalRead​(​sens4​)​ ​==​ ​1​)​ ​{
nivel ​=​ ​20​;
​if​ ​(​digitalRead​(​sens3​)​ ​==​ ​1​)​ ​{
nivel ​=​ ​40​;
​if​ ​(​digitalRead​(​sens2​)​ ​==​ ​1​)​ ​{
nivel ​=​ ​80​;
​if​ ​(​digitalRead​(​sens1​)​ ​==​ ​1​)​ ​{
nivel ​=​ ​100​;
​}
​}
​}
​}
​else​ nivel ​=​ ​0​;
​//Envia para o banco de dados o nív ​ el que está a caixa d'água
Firebase​.​setString​(​firebaseData​,​ tabela_caixa ​+​ ​"/nivel"​,​ String​(​nivel​));

​//Caso o botão para encher for acionado, irá encher até que a caixa d'água estiver cheia (ní​vel 100)
​if​ ​(​estado_botao_caixa ​==​ high​)​ ​{
​if​ ​(​nivel ​<​ ​100​)​ ​{
​if​ ​(​estado_botao_caixa ​==​ high​)​ ​{
digitalWrite​(​Bomba​,​ HIGH​);
​}
​else​ ​{
digitalWrite​(​Bomba​,​ LOW​);
​ }
​}
​if​ (
​ ​nivel ​==​ ​100​)​ ​{
digitalWrite​(​Bomba​,​ LOW​);
​}
​}
​ el estiver menor que 20
​//Caso botão estiver desligado, a caixa d'água irá encher se o nív
​if​ ​(​estado_botao_caixa ​==​ low​)​ ​{
​if​ ​(​nivel ​<=​ ​20​)​ ​{
digitalWrite​(​Bomba​,​ HIGH​);
​}
​if​ ​(​nivel ​==​ ​100​)​ ​{
digitalWrite​(​Bomba​,​ LOW​);
​}
​ }
}

//Função que altera o valores no banco de dados conforme a mensagem recebida pelo MQTT
void​ casos​()​ ​{
​switch​ ​(​valor​[​0​])​ ​{
​//Caso os valor for igual, irá alterar no banco de dados conforme a ordem dada
​case​ 'A'​:
Firebase​.​setString​(​firebaseData​,​ tabela_servo ​+​ ​"/porta_sala"​,​ ​"1"​);
​break​;
​case​ 'a'​:
Firebase​.​setString​(​firebaseData​,​ tabela_servo ​+​ ​"/porta_sala"​,​ ​"0"​);
​break​;

​case​ 'B'​:
Firebase​.​setString​(​firebaseData​,​ tabela_servo ​+​ "​ /porta_quarto"​,​ "​ 1"​);
​break​;
​case​ 'b'​:
Firebase​.​setString​(​firebaseData​,​ tabela_servo +​ ​ "​ /porta_quarto"​,​ "​ 0"​);
​break​;

​case​ 'L'​:
Firebase​.​setString​(​firebaseData​,​ tabela_servo ​+​ "​ /porta_casa"​,​ "​ 1"​);
​break​;
​case​ 'l'​:
Firebase​.​setString​(​firebaseData​,​ tabela_servo +​ ​ "​ /porta_casa"​,​ "​ 0"​);
​break​;

​case​ 'D'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ "​ /led_sala"​,​ "​ 1"​);
​break​;
​case​ 'd'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led +​ ​ "​ /led_sala"​,​ "​ 0"​);
​break​;

​case​ 'E'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ "​ /led_quarto1"​,​ "​ 1"​);
​break​;
​case​ 'e'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led +​ ​ "​ /led_quarto1"​,​ "​ 0"​);
​break​;

​case​ 'F'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ "​ /led_cozinha"​,​ "​ 1"​);
​break​;
​case​ 'f'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led +​ ​ "​ /led_cozinha"​,​ "​ 0"​);
​break​;

​case​ 'G'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ ​"/led_garagem"​,​ ​"1"​);
​break​;
​case​ 'g'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ ​"/led_garagem"​,​ ​"0"​);
​break​;

​case​ 'H'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ "​ /led_banheiro"​,​ "​ 1"​);
​break​;
​case​ 'h'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led +​ ​ "​ /led_banheiro"​,​ "​ 0"​);
​break​;

​case​ 'I'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led ​+​ "​ /led_quarto2"​,​ "​ 1"​);
​break​;
​case​ 'i'​:
Firebase​.​setString​(​firebaseData​,​ tabela_led +​ ​ "​ /led_quarto2"​,​ "​ 0"​);
​break​;

​case​ 'K'​:
Firebase​.​setString​(​firebaseData​,​ tabela_abajur ​+​ "​ /automatico"​,​ "​ 1"​);
​break​;
​case​ 'k'​:
Firebase​.​setString​(​firebaseData​,​ tabela_abajur +​ ​ "​ /automatico"​,​ "​ 0"​);
​break​;

​case​ 'M'​:
Firebase​.​setString​(​firebaseData​,​ tabela_poste ​+​ "​ /azul"​,​ "​ 1"​);
​break​;
​case​ 'm'​:
Firebase​.​setString​(​firebaseData​,​ tabela_poste +​ ​ "​ /azul"​,​ "​ 0"​);
​break​;

​case​ 'N'​:
Firebase​.​setString​(​firebaseData​,​ tabela_poste ​+​ "​ /verde"​,​ "​ 1"​);
​break​;
​case​ 'n'​:
Firebase​.​setString​(​firebaseData​,​ tabela_poste +​ ​ "​ /verde"​,​ "​ 0"​);
​break​;

​case​ 'O'​:
Firebase​.​setString​(​firebaseData​,​ tabela_poste ​+​ "​ /vermelho"​,​ "​ 1"​);
​break​;
​case​ 'o'​:
Firebase​.​setString​(​firebaseData​,​ tabela_poste +​ ​ "​ /vermelho"​,​ "​ 0"​);
​break​;

​case​ 'P'​:
Firebase​.​setString​(​firebaseData​,​ tabela_poste ​+​ "​ /branco"​,​ "​ 1"​);
​break​;
​case​ 'p'​:
Firebase​.​setString​(​firebaseData​,​ tabela_poste +​ ​ "​ /branco"​,​ "​ 0"​);
​break​;
​default​:
​break​;
​}
}

//Função do portão da garagem


void​ portao​()​ ​{
​//recebe o valor alto, caso a câmera identificou a imagem(QR-CODE) correta
​int​ sinal_openmv ​=​ digitalRead​(​openmv​);
delay​(​20​);
​//Caso o sinal for positivo, irá acionar o portão
​if​ ​(​sinal_openmv ​==​ HIGH ​)​ ​{
digitalWrite​(​garagem​,​ HIGH​);
​}
​if​ ​(​sinal_openmv ​==​ LOW​)​ ​{
digitalWrite​(​garagem​,​ LOW​);
​}

}
//Função que recebe os valores do banco de dados e executa as suas ordens
void​ app​()​ ​{
​//Recebe o valor do registro /led sala
Firebase​.​getString​(​firebaseData​,​ tabela_led ​+​ ​"/led_sala"​);
String estado_led_sala ​=​ firebaseData​.​stringData​();​ ​//Armazena na String o campo desse registro
​//Executa a operação conforme o que está escrito na tabela, isto é, abrir (high) ou fechar (low)
​if​ ​((​estado_led_sala ​==​ high​))​ ​{
digitalWrite​(​led_sala​,​ HIGH​);
​}
​if​ ​((​estado_led_sala ​==​ low​))​ ​{
digitalWrite​(​led_sala​,​ LOW​);
​}

Firebase​.​getString​(​firebaseData​,​ tabela_led ​+​ ​"/led_quarto1"​);


String estado_led_quarto1 ​=​ firebaseData​.​stringData​();
​if​ ​(​estado_led_quarto1 ​==​ high​)​ ​{
digitalWrite​(​led_quarto1​,​ HIGH​);
​ }
​if​ ​(​estado_led_quarto1 ​==​ low​)​ ​{
digitalWrite​(​led_quarto1​,​ LOW​);
​ }

Firebase​.​getString​(​firebaseData​,​ tabela_led ​+​ ​"/led_quarto2"​);


String estado_led_quarto2 ​=​ firebaseData​.​stringData​();
​if​ ​(​estado_led_quarto2 ​==​ high​)​ ​{
digitalWrite​(​led_quarto2​,​ HIGH​);
​ }
​if​ ​(​estado_led_quarto2 ​==​ low​)​ ​{
digitalWrite​(​led_quarto2​,​ LOW​);
​ }

Firebase​.​getString​(​firebaseData​,​ tabela_led ​+​ ​"/led_cozinha"​);


String estado_led_cozinha ​=​ firebaseData​.​stringData​();
​if​ ​(​estado_led_cozinha ​==​ high​)​ ​{
digitalWrite​(​led_cozinha​,​ HIGH​);
​ }
​if​ ​(​estado_led_cozinha ​==​ low​)​ ​{
digitalWrite​(​led_cozinha​,​ LOW​);
​ }

Firebase​.​getString​(​firebaseData​,​ tabela_led ​+​ ​"/led_garagem"​);


String estado_led_garagem ​=​ firebaseData​.​stringData​();
​if​ ​(​estado_led_garagem ​==​ high​)​ ​{
digitalWrite​(​led_garagem​,​ HIGH​);
​ }
​if​ ​(​estado_led_garagem ​==​ low​)​ ​{
digitalWrite​(​led_garagem​,​ LOW​);
​ }

Firebase​.​getString​(​firebaseData​,​ tabela_led ​+​ ​"/led_banheiro"​);


String estado_led_banheiro ​=​ firebaseData​.​stringData​();
​if​ ​(​estado_led_banheiro ​==​ high​)​ ​{
digitalWrite​(​led_banheiro​,​ HIGH​);
​ }
​if​ ​(​estado_led_banheiro ​==​ low​)​ ​{
digitalWrite​(​led_banheiro​,​ LOW​);
​ }

Firebase​.​getString​(​firebaseData​,​ tabela_servo ​+​ ​"/porta_sala"​);


String estado_porta_sala ​=​ firebaseData​.​stringData​();
​if​ ​(​estado_porta_sala ​==​ high​)​ ​{
​int​ posicao_sala ​=​ ​90​;
servo_sala​.​write​(​posicao_sala​);
​ }
​if​ ​(​estado_porta_sala ​==​ low​)​ ​{
​int​ posicao_sala ​=​ ​0​;
servo_sala​.​write​(​posicao_sala​);
​ }

Firebase​.​getString​(​firebaseData​,​ tabela_servo ​+​ ​"/porta_quarto"​);


String estado_porta_quarto ​=​ firebaseData​.​stringData​();
​if​ ​(​estado_porta_quarto ​==​ high​)​ ​{
posicao_quarto ​=​ ​90​;
servo_quarto​.​write​(​posicao_quarto​);
​ }
​if​ ​(​estado_porta_quarto ​==​ low​)​ ​{
posicao_quarto ​=​ ​0​;
servo_quarto​.​write​(​posicao_quarto​);
​ }

Firebase​.​getString​(​firebaseData​,​ tabela_servo ​+​ ​"/porta_casa"​);


String estado_porta_casa ​=​ firebaseData​.​stringData​();
​if​ ​(​estado_porta_casa ​==​ high​)​ ​{
posicao_casa ​=​ ​90​;
servo_casa​.​write​(​posicao_casa​);
​ }
​if​ ​(​estado_porta_casa ​==​ low​)​ ​{
posicao_sala ​=​ ​0​;
servo_sala​.​write​(​posicao_sala​);
​ }
}

//Função da fita led RGB


void​ fita​()​ ​{
​//Recebe os valores dos registros da tabela abajur
Firebase​.​getString​(​firebaseData​,​ tabela_abajur ​+​ ​"/ledred"​);
String estado_ledred ​=​ firebaseData​.​stringData​();​ ​//Armazena os valores dos campos na String
Firebase​.​getString​(​firebaseData​,​ tabela_abajur ​+​ ​"/ledgreen"​);
String estado_ledgreen ​=​ firebaseData​.​stringData​();
Firebase​.​getString​(​firebaseData​,​ tabela_abajur ​+​ ​"/ledblue"​);
String estado_ledblue ​=​ firebaseData​.​stringData​();
Firebase​.​getString​(​firebaseData​,​ tabela_abajur ​+​ ​"/automatico"​);
String estado_automatico ​=​ firebaseData​.​stringData​();

​/*Executa a ação conforme os valore das tabelas de /abajur, ou seja, caso esteja na tabela abajur o
registro for do
ledblue for "1" irá acender a fita com a cor vermelha*/
​if​ ​(​estado_automatico ​==​ high​)​ ​{
​if​ ​((​millis​()​ ​-​ tempo​)​ ​>​ ​0​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ ​100​)
​{
luzes​.​setPixelColor​(​0​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));​//
inicialização das cores
luzes​.​show​();​// isso envia as cores atualizadas do pixel para o hardware
​}

​if​ ( ​ (​millis​()​ ​-​ tempo​)​ ​>​ ​100​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ 2
​ 00​)
​ {
luzes​.​setPixelColor​(​1​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));​//
inicialização das cores
luzes​.​show​();​// isso envia as cores atualizadas do pixel para o hardware
​}

​if​ ( ​ (​millis​()​ ​-​ tempo​)​ ​>​ ​200​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ 3
​ 00​)
​ {
luzes​.​setPixelColor​(​2​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));​//
inicialização das cores
luzes​.​show​();​// isso envia as cores atualizadas do pixel para o hardware
​}

​if​ ( ​ (​millis​()​ ​-​ tempo​)​ ​>​ ​300​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ 4
​ 00​)
​ {
luzes​.​setPixelColor​(​3​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));​//
inicialização das cores
luzes​.​show​();​// isso envia as cores atualizadas do pixel para o hardware
​}

​if​ ( ​ (​millis​()​ ​-​ tempo​)​ ​>​ ​400​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ 5
​ 00​)
​ {
luzes​.​setPixelColor​(​4​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));​//
inicialização das cores
luzes​.​show​();​// isso envia as cores atualizadas do pixel para o hardware
​}
​if​ ( ​ (​millis​()​ ​-​ tempo​)​ ​>​ ​500​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ ​600​)
​ {
luzes​.​setPixelColor​(​5​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));
luzes​.​show​();
​ }

​if​ ( ​ (​millis​()​ ​-​ tempo​)​ ​>​ ​600​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ ​700​)
​ {
luzes​.​setPixelColor​(​6​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));
luzes​.​show​();
​ }
​if​ ​((​millis​()​ ​-​ tempo​)​ ​>​ ​700​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ ​800​)
​ {
luzes​.​setPixelColor​(​7​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));
luzes​.​show​();​ ​}

​if​ ( ​ (​millis​()​ ​-​ tempo​)​ ​>​ ​800​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ ​900​)
​ {
luzes​.​setPixelColor​(​8​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));
luzes​.​show​();
​ }

​if​ ( ​ (​millis​()​ ​-​ tempo​)​ ​>​ ​900​ ​&&​ ​(​millis​()​ ​-​ tempo​)​ ​<=​ ​1000​)
​ {
luzes​.​setPixelColor​(​9​,​ luzes​.​Color​(​random​(​10​,​ ​255​),​ random​(​10​,​ ​255​),​ random​(1
​ 0​,​ 2
​ 55​)));
luzes​.​show​();
​ }

​if​ (
​ (​millis​()​ ​-​ tempo​)​ ​>​ ​1000​)​ ​{
tempo ​=​ millis​();
​}
​}
​if​ ( ​ ​estado_ledred ​==​ high​)​ ​{
​for​ ​(​int​ z ​=​ ​0​;​ z ​<=​ ​9​;​ z​++)​ ​{
luzes​.​setPixelColor​(​z​,​ luzes​.​Color​(​255​,​ ​0​ , ​ ​ ​0​));
luzes​.​show​();
​}
​ }
​if​ ​(​estado_ledgreen ​==​ high​)​ ​{
​for​ ​(​int​ z ​=​ ​0​;​ z ​<=​ ​9​;​ z​++)​ ​{
luzes​.​setPixelColor​(​z​,​ luzes​.​Color​(​0​,​ ​255​ , ​ ​ ​0​));
luzes​.​show​();
​}
​ }
​if​ ​(​estado_ledblue ​==​ high​)​ ​{
​for​ ​(​int​ z ​=​ ​0​;​ z ​<=​ ​9​;​ z​++)​ ​{
luzes​.​setPixelColor​(​z​,​ luzes​.​Color​(​0​,​ ​0​ ​,​ 2 ​ 55​));
luzes​.​show​();
​}
​ }
}

//Função do loop eterno


void​ loop​()​ ​{
​//Irá executar todas as funções das casas
temperatura​();
iluminacao​();
caixa​();
portao​();
casos​();
​//Refaz a conexão com MQTT caso desconecte
​if​ ​(!​client​.​connected​())​ ​{
reconect​();
​}
​//Estabelece o esp32 como cliente no broker e espera a publicação no tópico assinado
client​.​loop​();
}

########################################################################
● Imagem da casa

Imagens - Parte interna da casa com esp32 no centro

Imagens - Câmera do portão


Imagens - Parte superior da casa

II.IV Funcionamento do aplicativo

Imagens - Tela inicial


Ao iniciar o aplicativo, irá abrir uma tela inicial contendo um menu na barra superior e logo abaixo um
pequeno resumo sobre o projeto. Ao pressionar o botão do menu aparecerá três botões que levam a outras telas, que
contém as funções de controle e monitoramento da casa.

Imagem - Criação do menu superior que ficará em todas as telas.

Imagem - Programação do botão para iniciar uma conexão com o banco de dados (armazenando um dado), para que
ele possa iniciar a recepção de dados na tela de monitoramento (Temperatura). Também contendo a mesma criação
do menu superior, utilizada anteriormente.
Imagem - Comandos que irão buscar os registros (variáveis) contidos no banco de dados, ainda na tela de
monitoramento..
ProjectBucket = nome da tabela.
Rótulo = nome do registo.
Value = valor armazenado no registo.

Imagem - Declaração de todas as variáveis contidas na tela FireBase.

Imagem - Progamação dos botões que irão abrir e fechar o portão, armazenando um valor (1 ou 2) em seus
registros para abertura e fechamento, respectivamente, ativando um temporizador que irá armazenar o valor “0”
após 5 segundos, para desativar o motor.
Imagem - Comando que irá ligar e desligar as luzes. Para cada área tem os comandos acima, mudando apenas os
nomes dos rótulos. Ex: led_cozinha, led_banheiro etc.

Imagem - Programação dos botões que irão ligar e desligar todos as luzes da casa, contendo os nomes de todos os
rótulos.
Imagem - Botões para ligar os leds rbg do abajur em uma determinada cor, ou fazer com que ele fique piscando em
cores aleatórias. Estes blocos são repetidos 5 vezes, cada um para uma cor diferente, aleatório ou desligado (1 para
ligado, 0 para desligado);

Imagem - Comandos para ligar ou desligar as cores acesas da fita led. O comando é repetido 4 vezes, cada um com
um rótulo com nome e cor diferentes. Ex: fitaRed, fitaGreen, etc.
Imagem - Comandos para mudança das cores dos leds rgb dos postes de toda maquete, sendo repetido 5 vezes com
estados diferentes.

Imagem - Programação do botão que irá ativar o reconhecimento de voz, que dependendo do texto de fala obtido ele
irá armazenar um valor em determinado rótulo.
Imagem - Mudar a imagem do nível da caixa d’agua dependendo do valor do rótulo no banco de dados, que será
alterado pelo ESP32.
Design aplicativo
FireBase

Imagem - Ao abrir o site FireBase basta logar com sua conta do google e clicar no local indicado na imagem

Imagem - Após isso, basta pressionar o botão “Criar um projeto”.


Imagem - Aparecerá um campo para adicionar o nome do projeto, após isso clicar em continuar.

Imagem - Ativar o Google analytics a pressionar continuar.


Imagem - Mudar a localização para “Brasil”, marcar todos os campos e Criar Projeto.

Imagem - Após realizar a configuração inicial, basta abrir a tela do projeto e clicar na engrenagem de configuração,
e ir em Configurações do projeto.
Imagem - Token que será adicionado no App Inventor

Imagem - chave que será usada no programa em C, para o ESP acessar o banco de dados.
Imagem - Criação do banco de dados FireBase.

Imagem - Selecionar o modo de teste e pressionar o botão “Próximo”.


Imagem - selecionar o local nam5(us-central) e concluir.

Imagem - acessando o banco de dados e obtendo o link para adicionar no AppInventor.


Imagem - Adicionando o FireBase ao aplicativo na plataforma AppInventor e logo após adicionar o token e link
obtidos na configuração do banco de dados.

II.V. COMUNICAÇÃO
O projeto contém vários tipos de comunicação, porém existe a centralização de informação que é o banco de
dados Firebase. Em síntese:
III. Conclusão
O projeto é executável, barato e prático. Portanto, apresenta vários pontos para acrescentar, como API
Text-Speech para poder fazer uma melhor comunicação com o usuário e Unificar apenas um tipo de ponte para
todos as comunicação, isto é, retirar o MQTT e colocar apenas o Banco de dados como centralizador, além disso
dividir as tarefas do esp32 utilizando os dois núcleos para acelerar o processo e comunicação.. Após essas
mudanças, acrescentar mais sensores e aplicabilidades se torna rápido e prático.

Referências

1. CONSTANTINO. S. FILHO, A automação nos anos 2000 uma análise das novas fronteiras da
automação,​ http://alvarestech.com/temp/smar/www.delt.ufmg.br/seixas/Pagin
aII/Download/DownloadFiles/Conai2000Automacao.PDF
2. EGIDIO, Lucas; UKEI, Tiago.; Internet das Coisas (IOT): Uma análise de aplicabilidade. Workshop de Sistemas
Embarcados da ES670, 2015. UNICAMP, 10 de JUN de 2015.
3. ESPRESSIF SYSTEMS, ESP32 Series. 2019 Disponível em: <
https://​www.​espressif​.com/sites/default/files/documentation/esp3​ 2_datasheet_en.pdf​> Acesso em: 21 Mar. 2019.
4. TAKIUCHI , MELO E TONIDANDEL; domótica inteligente: automação baseada em comportamento. 2004 Disponivel
em <​https://fei.edu.br/~flaviot/pub_arquivos/cba2004_Final.pdf​> acesso em 25/11/2019.
5.

Você também pode gostar