Como não basta só proteger a nossa casa, garantir que o nosso carro está sempre na garagem da manhã do dia seguinte é também uma preocupação. Neste projeto, vamos desenvolver um sistema de segurança para a garagem com a ESP32!
Para este projeto, vamos precisar dos seguintes elementos:
| Imagem | Produto | Comprar |
|---|---|---|
| ESP32 (NodeMCU) | ||
| Display LCD 20×4 I2C | ||
| Teclado Matricial 4×4 | ||
| Breadboard 830 Pinos | ||
| 4 Botões de Pressão | ||
| Buzzer Passivo | ||
| Fios de Ligação Macho-Macho | ||
| Fios de Ligação Macho-Fêmea |
Montagem do Circuito
Recorremos à comunicação I2C entre o Arduino e o LCD para minimizar a desorganização do nosso projeto. O buzzer passivo irá garantir o sinal sonoro uma vez ativado o alarme.
Vamos começar por montar o circuito com todos os componentes acima mencionados de acordo com este esquema de montagem:
Preparação do Ambiente e Envio do Código
Vamos começar por transferir as bibliotecas necessárias para o projeto:
Biblioteca LiquidCrytal_I2C.h
Biblioteca Keypad.h
Biblioteca EEPROM.h
No nosso ambiente do Arduino IDE, adicionamos as bibliotecas necessárias em “Rascunho” -> “Incluir Biblioteca” -> “Adicionar Biblioteca .ZIP” e selecionando, um por um, os ficheiros .ZIP transferidos.
Após selecionar a respetiva placa microcontroladora a utilizar, basta compilar e carregar o seguinte código:
/*Código para o Projeto: Sistema de Segurança de Garagem com Arduino
Utilizando os 4 botões de pressão, navegue pelos menus para:
-> Menu 1: Ativar/desativar o sistema de segurança
-> Menu 2: Definir o tempo de fecho da porta da garagem (utilizado no countdown para ativar o alarme)
Botão Menu ====> Botão conectado ao pino 2, utilizado para aceder ou sair dos menus
Botão Confirmação ====> Botão conectado ao pino 4, utilizado para entrar nos menuns ou confirmar escolhas
Botão Anterior ====> Botão conectado ao pino 5, utilizado para diminuir ou substrair input's do utilizador
Botão Avançar ====> Botão conectado ao pino 19, utilizado para aumentar ou acrescentar input's do utilizador
Conectar um dispositivo de saída ao pino 15 (Buzzer) para resposta sonora à atuação do alarme
www.electrofun.pt/blog/deixe-os-ladroes-longe-da-sua-garagem-sistema-de-seguranca-com-esp32-arduino
Electrofun@2022 ---> www.electrofun.pt
*/
#define pinoBotaoMenu 2
#define pinoBotaoConfirmacao 4
#define pinoBotaoAnterior 5
#define pinoBuzzer 15
#define pinoBotaoAvancar 18
#define pinoSensorPorta 19
//Inclusão de Bibliotecas
#include <LiquidCrystal_I2C.h> //Biblioteca do Display I2C
#include <Keypad.h> //Biblioteca do Teclado Matricial (4x4)
#include <EEPROM.h> //Biblioteca da memória interna do nosso ESP32
//Declaração de variáveis
const byte linhasTeclado = 4;
const byte colunasTeclado = 4;
byte pinosLinhasTeclado[linhasTeclado] = {12, 14, 27, 26};
byte pinosColunasTeclado[colunasTeclado] = {25, 33, 32, 23};
byte tamanhoCodigo = 6;
int estadoBotaoMenu, estadoBotaoConfirmacao, estadoBotaoAnterior, estadoBotaoAvancar, contagemDec;
int debouce = 200; //Esta variável é utilizada apenas para conhecimento do utilizador do motivo da função delay() no pedaço de código
int tempoAberturaPorta = 5;
long tempo;
bool estadoSensorPorta, portaAberta;
bool alarmeAtivado = false;
bool alarmeAcionado = false;
char codigoCorreto[6];
char codigoVerificar[6];
char hexaKeys[linhasTeclado][colunasTeclado] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
//Caracteres Necessários em BitMap
byte setaDireita[] = {
B10000,
B11000,
B11100,
B11111,
B11111,
B11110,
B11000,
B10000
};
byte setaEsquerda[] = {
B00001,
B00011,
B00111,
B11111,
B11111,
B01111,
B00011,
B00001
};
LiquidCrystal_I2C lcd(0x27, 20, 4);
Keypad teclado = Keypad( makeKeymap(hexaKeys), pinosLinhasTeclado, pinosColunasTeclado, linhasTeclado, colunasTeclado);
void setup() {
pinMode(pinoSensorPorta, INPUT_PULLUP);
pinMode(pinoBotaoMenu, INPUT_PULLUP);
pinMode(pinoBotaoConfirmacao, INPUT_PULLUP);
pinMode(pinoBotaoAnterior, INPUT_PULLUP);
pinMode(pinoBotaoAvancar, INPUT_PULLUP);
pinMode(pinoBuzzer, OUTPUT);
lcd.begin();
lcd.backlight();
EEPROM.begin(tamanhoCodigo);
while (!EEPROM.begin(tamanhoCodigo)) {
lcd.print("EEPROM FAILED!");
delay(5000);
lcd.clear();
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sistema de Seguranca");
lcd.setCursor(4, 1);
lcd.print("com Arduino");
lcd.setCursor(1, 3);
lcd.print("By Electrofun@2022");
delay(5000);
if (teclado.getKey() == 'A') {
alterarPalavraChave();
}
lcd.clear();
}
void loop() {
lcd.setCursor(7, 0);
lcd.print("STATUS");
lcd.setCursor(0, 2);
lcd.print("Porta Garagem");
estadoSensorPorta = digitalRead(pinoSensorPorta);
if (estadoSensorPorta == 1) {
portaAberta = 1;
lcd.setCursor(0, 3);
lcd.print("Aberta ");
} else if (estadoSensorPorta == 0) {
portaAberta = 0;
lcd.setCursor(0, 3);
lcd.print("Fechada");
}
if (alarmeAtivado == 1 && portaAberta == 1) {
alarmeAcionado = 1;
}
if (alarmeAcionado == 1) {
for (int i = 0; i < 10; i++)
{
digitalWrite(pinoBuzzer, HIGH);
delay(1);
digitalWrite(pinoBuzzer, LOW);
delay(1);
}
for (int i = 0; i < 20; i++) { digitalWrite(pinoBuzzer, HIGH); delay(2); digitalWrite(pinoBuzzer, LOW); delay(2); } } if (alarmeAtivado == 0) { alarmeAcionado = 0; } estadoBotaoMenu = digitalRead(pinoBotaoMenu); if (estadoBotaoMenu == 0) { delay(debouce); menu1(); } } void menu1() { lcd.clear(); lcd.setCursor(5, 0); lcd.print("1 - Alarme"); if (alarmeAtivado == 1) { lcd.setCursor(7, 2); lcd.print("Armado"); } else if (alarmeAtivado == 0) { lcd.setCursor(5, 2); lcd.print("Desarmado"); } lcd.createChar(1, setaEsquerda); lcd.setCursor(0, 3); lcd.write(1); lcd.createChar(2, setaDireita); lcd.setCursor(19, 3); lcd.write(2); tempo = millis(); do { estadoBotaoMenu = digitalRead(pinoBotaoMenu); estadoBotaoConfirmacao = digitalRead(pinoBotaoConfirmacao); estadoBotaoAnterior = digitalRead(pinoBotaoAnterior); estadoBotaoAvancar = digitalRead(pinoBotaoAvancar); } while ((estadoBotaoMenu == 1 && estadoBotaoConfirmacao == 1 && estadoBotaoAnterior == 1 && estadoBotaoAvancar == 1) || millis() - tempo > 10000);
if (estadoBotaoConfirmacao == 0) {
delay(debouce);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Codigo Seguranca:");
lcd.setCursor(0, 3);
for (int i = 0; i < tamanhoCodigo; i++) {
codigoVerificar[i] = teclado.waitForKey();
lcd.print(codigoVerificar[i]);
}
lcd.clear();
if (codigoVerificar[0] == EEPROM.read(0) &&
codigoVerificar[1] == EEPROM.read(1) &&
codigoVerificar[2] == EEPROM.read(2) &&
codigoVerificar[3] == EEPROM.read(3) &&
codigoVerificar[4] == EEPROM.read(4) &&
codigoVerificar[5] == EEPROM.read(5)) {
alarmeAtivado = !alarmeAtivado;
if (alarmeAtivado == true) {
contagemDec = tempoAberturaPorta + 5;
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Alarme armado em:");
do {
if (contagemDec < 10) {
lcd.setCursor(9, 2);
lcd.print("0");
lcd.setCursor(10, 2);
lcd.print(contagemDec);
} else {
lcd.setCursor(9, 2);
lcd.print(contagemDec);
}
contagemDec--;
delay(1000);
} while (contagemDec != 0);
}
lcd.clear();
return;
}
} else if (estadoBotaoAnterior == 0) {
delay(debouce);
menu2();
} else if (estadoBotaoAvancar == 0) {
delay(debouce);
menu2();
} else if (estadoBotaoMenu == 0) {
delay(debouce);
lcd.clear();
return;
}
}
void menu2() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("2 - Tempo");
lcd.setCursor(0, 1);
lcd.print("Abertura Porta");
lcd.createChar(1, setaEsquerda);
lcd.setCursor(0, 3);
lcd.write(1);
lcd.createChar(2, setaDireita);
lcd.setCursor(19, 3);
lcd.write(2);
if (alarmeAcionado == 1) {
for (int i = 0; i < 10; i++)
{
digitalWrite(pinoBuzzer, HIGH);
delay(1);
digitalWrite(pinoBuzzer, LOW);
delay(1);
}
for (int i = 0; i < 20; i++) { digitalWrite(pinoBuzzer, HIGH); delay(2); digitalWrite(pinoBuzzer, LOW); delay(2); } } tempo = millis(); do { estadoBotaoMenu = digitalRead(pinoBotaoMenu); estadoBotaoConfirmacao = digitalRead(pinoBotaoConfirmacao); estadoBotaoAnterior = digitalRead(pinoBotaoAnterior); estadoBotaoAvancar = digitalRead(pinoBotaoAvancar); } while ((estadoBotaoMenu == 1 && estadoBotaoConfirmacao == 1 && estadoBotaoAnterior == 1 && estadoBotaoAvancar == 1) || millis() - tempo > 10000);
if (estadoBotaoConfirmacao == 0) {
delay(debouce);
lcd.clear();
definirTempoAberturaPorta();
return;
}
else if (estadoBotaoAnterior == 0) {
delay(debouce);
menu1();
} else if (estadoBotaoAvancar == 0) {
delay(debouce);
menu1();
} else if (estadoBotaoMenu == 0) {
delay(debouce);
lcd.clear();
return;
}
}
void definirTempoAberturaPorta() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Defina o tempo de");
lcd.setCursor(0, 1);
lcd.print("abertura da porta:");
do {
if (tempoAberturaPorta < 10) { lcd.setCursor(9, 3); lcd.print("0"); lcd.setCursor(10, 3); lcd.print(tempoAberturaPorta); } else { lcd.setCursor(9, 3); lcd.print(tempoAberturaPorta); } estadoBotaoAnterior = digitalRead(pinoBotaoAnterior); estadoBotaoAvancar = digitalRead(pinoBotaoAvancar); if (estadoBotaoAvancar == 0) { delay(debouce); tempoAberturaPorta++; if (tempoAberturaPorta > 100) {
tempoAberturaPorta = 0;
}
} else if (estadoBotaoAnterior == 0) {
delay(debouce);
tempoAberturaPorta--;
if (tempoAberturaPorta < 0) {
tempoAberturaPorta = 99;
}
}
} while (digitalRead(pinoBotaoConfirmacao) == 1);
delay(debouce);
lcd.clear();
}
void alterarPalavraChave() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo Programador");
lcd.setCursor(0, 1);
lcd.print("Ativado!");
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Codigo Seguranca:");
lcd.setCursor(0, 3);
for (int i = 0; i < tamanhoCodigo; i++) {
codigoVerificar[i] = teclado.waitForKey();
lcd.print(codigoVerificar[i]);
}
lcd.clear();
if (codigoVerificar[0] == EEPROM.read(0) &&
codigoVerificar[1] == EEPROM.read(1) &&
codigoVerificar[2] == EEPROM.read(2) &&
codigoVerificar[3] == EEPROM.read(3) &&
codigoVerificar[4] == EEPROM.read(4) &&
codigoVerificar[5] == EEPROM.read(5)) {
lcd.setCursor(0, 0);
lcd.print("Insira novo codigo:");
lcd.setCursor(0, 3);
for (int i = 0; i < tamanhoCodigo; i++) {
codigoCorreto[i] = teclado.waitForKey();
EEPROM.write(i, codigoCorreto[i]);
lcd.print(codigoCorreto[i]);
}
EEPROM.commit();
} else {
lcd.setCursor(0, 0);
lcd.print("Codigo Errado");
lcd.setCursor(0, 2);
lcd.print("Tente Novamente!");
delay(5000);
}
lcd.clear();
}
Funcionamento
A breadboard montada acima conta com 4 botões. Da esquerda para a direita: botão de menu, utilizado para aceder ou sair ao menu das configurações; botão de confirmação, utilizado para entrar ou confirmar uma opção do menu; botão “anterior”, para diminuir valores fornecidos pelo utilizador; e botão “avançar”, para aumentar os mesmos valores.
Na sua página principal, é mostrado a estado da porta da garagem, fornecido pelo sensor de abertura de porta, nos seus estados aberto ou fechado. Pressionando o botão de menu, é possível ativar ou desativar o alarme, bem como definir o tempo que demora a porta da garagem a fechar, permitindo assim que ative o alarme e ainda haja tempo para sair da garagem.
A palavra-chave pré-definida é 000000, mas pode alterar a mesma mantendo pressionado o botão “A” do teclado matricial após ter sido reiniciada a placa microcontroladora.
Não se esqueçam de ver o nosso vídeo sobre este artigo no nosso canal do YouTube:
Para mais projetos, percorram o nosso blog, onde podem encontrar vários artigos interessantes relacionados com eletrónica, robótica e muito mais! Visitem também o nosso site, onde encontram tudo para eletrónica e robótica!
Comments
Comentários