#define __ATmega2560__ // Define que estamos utilizando o ATmega2560
#define __AVR_ATmega2560__ // Define que estamos utilizando o ATmega2560
#ifndef F_CPU
#define F_CPU 16000000UL // Define a frequência do microcontrolador (16 MHz)
#endif
#include <avr/io.h>
#include <stdbool.h>
#include <util/delay.h>
#include <string.h>
#include <stdint.h>
#include "usart.h"
#define LED_PIN PB7
#define SPEAKER_PIN PB6
#define PIR_PIN PC7
#define SENSOR_PIN PC6
#define ROW1_PIN 22
#define ROW2_PIN 23
#define ROW3_PIN 24
#define ROW4_PIN 25
#define COL1_PIN 26
#define COL2_PIN 27
#define COL3_PIN 28
typedef enum {
STAND_BY,
ALARME_ARMADO,
ALARME_DISPARADO
} Estado;
Estado estadoAtual = STAND_BY;
bool alarmeAtivado = false;
bool alarmeDisparado_msg = false;
char senha[5] = "1234";
char entrada[5];
int posicao = 0;
char lerKeypad();
char mapearTecla(int linha, int coluna);
void verificarSenha();
void redefinirSenha();
void dispararAlarme();
void piscarled();
bool debounceSensor();
void processarEntradaKeypad();
void piscarled() {
for (int i = 0; i < 3; i++) {
PORTB |= (1 << LED_PIN);
_delay_ms(100);
PORTB &= ~(1 << LED_PIN);
_delay_ms(100);
}
}
void configura_pinos() {
DDRB |= (1 << LED_PIN);
DDRC |= (1 << SPEAKER_PIN);
DDRC &= ~(1 << PIR_PIN);
DDRC &= ~(1 << SENSOR_PIN);
DDRA |= 0x0F;
DDRA &= ~0xF0;
PORTA |= 0xF0;
}
int main (void) {
USART0_configura();
configura_pinos();
while (1) {
switch (estadoAtual) {
case STAND_BY:
if (!alarmeAtivado) {
USART0_transmite_string_FLASH(PSTR("\nInsira a senha para ativar o alarme.\n"));
alarmeAtivado = true; // Garante que a mensagem seja exibida apenas uma vez
}
processarEntradaKeypad();
break;
case ALARME_ARMADO:
if (!alarmeAtivado) {
piscarled();
USART0_transmite_string_FLASH(PSTR("\nALARME LIGADO\n"));
alarmeAtivado = true;
}
if (debounceSensor() || ((PINC & (1 << PIR_PIN)) != 0)) {
estadoAtual = ALARME_DISPARADO;
alarmeAtivado = false;
alarmeDisparado_msg = true;
}
break;
case ALARME_DISPARADO:
if (alarmeDisparado_msg) {
USART0_transmite_string_FLASH(PSTR("Movimento detectado! Insira a senha para desarmar.\n"));
alarmeDisparado_msg = false;
}
dispararAlarme();
processarEntradaKeypad();
break;
}
}
}
char lerKeypad() {
static char ultimaTecla = '\0';
static bool teclaPressionada = false;
for (int linha = 0; linha < 4; linha++) {
PORTA = ~(1 << linha);
_delay_us(100);
uint8_t colunas = PINA & 0xF0;
if (colunas != 0xF0) {
_delay_ms(40);
colunas = PINA & 0xF0;
if (colunas != 0xF0) {
for (int coluna = 0; coluna < 3; coluna++) {
if ((colunas & (1 << (coluna + 4))) == 0) {
char teclaAtual = mapearTecla(linha, coluna);
if (!teclaPressionada && teclaAtual != ultimaTecla) {
_delay_ms(50);
if ((PINA & (1 << (coluna + 4))) == 0) {
ultimaTecla = teclaAtual;
teclaPressionada = true;
return teclaAtual;
}
}
}
}
}
} else {
teclaPressionada = false;
}
}
ultimaTecla = '\0';
return '\0';
}
char mapearTecla(int linha, int coluna) {
char matriz[4][3] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
return matriz[linha][coluna];
}
void processarEntradaKeypad() {
char tecla = lerKeypad();
if (tecla != '\0') {
if (tecla == '#') {
if (posicao == 4) {
verificarSenha();
} else {
USART0_transmite_string_FLASH(PSTR("\nSenha incompleta!\n"));
posicao = 0;
memset(entrada, 0, sizeof(entrada));
}
} else if (tecla == '*') {
if (estadoAtual == STAND_BY && posicao == 4) {
redefinirSenha();
} else {
USART0_transmite_string_FLASH(PSTR("\nEntrada inválida para redefinir senha!\n"));
posicao = 0;
memset(entrada, 0, sizeof(entrada));
}
} else if (posicao < 4) {
entrada[posicao] = tecla;
posicao++;
USART0_transmite_string_FLASH(PSTR("*"));
}
}
}
void verificarSenha() {
entrada[posicao] = '\0';
if (strcmp(entrada, senha) == 0) {
if (estadoAtual == STAND_BY) {
estadoAtual = ALARME_ARMADO;
alarmeAtivado = false; // Garante que o LED pisque ao entrar no estado armado
} else if (estadoAtual == ALARME_DISPARADO) {
estadoAtual = STAND_BY;
piscarled(); // Pisca o LED antes de desligá-lo
PORTB &= ~(1 << LED_PIN); // Desliga o LED
alarmeAtivado = false; // Garante que a mensagem seja exibida ao retornar ao estado STAND_BY
USART0_transmite_string_FLASH(PSTR("\nAlarme desativado!\n"));
}
} else {
USART0_transmite_string_FLASH(PSTR("\nSenha incorreta!\n"));
}
posicao = 0;
memset(entrada, 0, sizeof(entrada));
}
void redefinirSenha() {
USART0_transmite_string_FLASH(PSTR("\nDigite a nova senha:\n"));
posicao = 0;
while (posicao < 4) {
char tecla = lerKeypad();
if (tecla != '\0') {
entrada[posicao] = tecla;
posicao++;
USART0_transmite_string_FLASH(PSTR("*"));
}
}
entrada[posicao] = '\0';
strcpy(senha, entrada);
USART0_transmite_string_FLASH(PSTR("\nNova senha salva com sucesso!\n"));
posicao = 0;
memset(entrada, 0, sizeof(entrada));
}
void dispararAlarme() {
static bool alarmeDisparando = true;
if (alarmeDisparando) {
for (int i = 0; i < 5; i++) {
PORTC |= (1 << SPEAKER_PIN);
_delay_ms(200);
PORTC &= ~(1 << SPEAKER_PIN);
_delay_ms(200);
}
PORTB |= (1 << LED_PIN);
alarmeDisparando = false;
}
}
bool debounceSensor() {
bool estadoInicial = (PINC & (1 << SENSOR_PIN)) != 0;
_delay_ms(50);
bool estadoFinal = (PINC & (1 << SENSOR_PIN)) != 0;
return estadoInicial && estadoFinal;
}