DEIXE os LADRÕES LONGE da sua GARAGEM! SISTEMA DE SEGURANÇA com ESP32 (ARDUINO)
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!