#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
// Máscaras para as linhas e colunas do Keypad (4x3)
#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
// Estados do sistema
typedef enum {
STAND_BY,
ALARME_ARMADO,
ALARME_DISPARADO
} Estado;
Estado estadoAtual = STAND_BY;
bool alarmeAtivado = false; // Variável para controlar a mensagem "ALARME LIGADO"
bool alarmeDisparado_msg = false;
// Senha inicial
char senha[5] = "1234";
char entrada[5];
int posicao = 0; // Posição atual da senha digitada
// Prototipação das funções
char lerKeypad();
char mapearTecla(int linha, int coluna);
void verificarSenha();
void redefinirSenha();
void dispararAlarme();
void piscarled();
bool debounceSensor();
void piscarled() {
for (int i = 0; i < 3; i++) {
PORTB |= (1 << LED_PIN); // Liga o LED
_delay_ms(100);
PORTB &= ~(1 << LED_PIN);
_delay_ms(100);
}
}
void configura_pinos() {
DDRB |= (1 << LED_PIN);
DDRC |= (1 << SPEAKER_PIN); // Configure como saída
DDRC &= ~(1 << PIR_PIN);
DDRC &= ~(1 << SENSOR_PIN);
DDRA |= 0x0F; // Linhas como saída
DDRA &= ~0xF0; // Colunas como entrada
PORTA |= 0xF0; // Habilita pull-up nas colunas
}
int main (void) {
USART0_configura();
configura_pinos();
while (1) {
char tecla = lerKeypad();
switch (estadoAtual) {
case STAND_BY:
if (tecla != '\0') {
if (tecla == '#') {
verificarSenha();
} else if (tecla == '*') {
redefinirSenha();
} else if (posicao < 4) {
entrada[posicao] = tecla;
posicao++;
USART0_transmite_string_FLASH(PSTR("*"));
}
}
break;
case ALARME_ARMADO:
if (alarmeAtivado == 0) {
piscarled();
USART0_transmite_string_FLASH(PSTR("\nALARME LIGADO\n"));
}
alarmeAtivado = true;
if (debounceSensor() || ((PINC & (1 << PIR_PIN)) != 0)) {
estadoAtual = ALARME_DISPARADO;
alarmeAtivado = false; // Reseta a variável para o próximo uso
alarmeDisparado_msg = true;
break;
case ALARME_DISPARADO:
if (alarmeDisparado_msg == 1) {
USART0_transmite_string_FLASH(PSTR("Movimento detectado! Insira a senha para desarmar.\n"));
}
alarmeDisparado_msg = 0;
dispararAlarme();
verificarSenha();
break;
}
}
}
}
char lerKeypad() {
static char ultimaTecla = '\0';
static bool teclaPressionada = false;
for (int linha = 0; linha < 4; linha++) {
PORTA = ~(1 << linha); // Ativa a linha correspondente
_delay_us(100); // Aumenta o tempo para estabilizar
uint8_t colunas = PINA & 0xF0;
if (colunas != 0xF0) {
_delay_ms(40); // Atraso de debouncing
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) {
// Atraso de debouncing
_delay_ms(50);
if ((PINA & (1 << (coluna + 4))) == 0) {
ultimaTecla = teclaAtual;
teclaPressionada = true;
return teclaAtual; // Retorna a tecla pressionada
}
}
}
}
}
} else {
teclaPressionada = false; // Reset se não houver tecla pressionada
}
}
ultimaTecla = '\0'; // Reseta a última tecla se nenhuma tecla estiver pressionada
return '\0'; // Retorna nada se não houver tecla pressionada
}
char mapearTecla(int linha, int coluna) {
char matriz[4][3] = { // Mapeamento atualizado para 4x3
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
return matriz[linha][coluna];
}
void verificarSenha() {
entrada[posicao] = '\0';
if (strcmp(entrada, senha) == 0) {
if (estadoAtual == STAND_BY) {
estadoAtual = ALARME_ARMADO;
} else if (estadoAtual == ALARME_DISPARADO) {
estadoAtual = 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("\nSenha redefinida com sucesso!\n"));
posicao = 0;
_delay_ms(500);
USART0_transmite_string_FLASH(PSTR("Digite a nova senha:\n"));
while (posicao < 4) {
char tecla = lerKeypad();
if (tecla != '\0') {
entrada[posicao] = tecla;
posicao++;
USART0_transmite_string_FLASH(PSTR("*"));
}
}
entrada[posicao] = '\0';
strcpy(senha, entrada);
posicao = 0;
memset(entrada, 0, sizeof(entrada));
}
void dispararAlarme() {
for (int i = 0; i < 5; i++) { // Pisca o buzzer
PORTC |= (1 << SPEAKER_PIN); // Liga o buzzer
_delay_ms(200);
PORTC &= ~(1 << SPEAKER_PIN); // Desliga o buzzer
_delay_ms(200);
}
PORTB |= (1 << LED_PIN); // Liga o LED
char tecla = lerKeypad();
if (tecla != '\0') {
if (posicao == 4) { // Apenas verifica a senha se 4 dígitos foram digitados
if (tecla == '#') {
verificarSenha();
}
posicao = 0; // Reseta a posição, independentemente do sucesso
memset(entrada, 0, sizeof(entrada)); // Limpa o buffer da entrada
} else if (posicao < 4) {
entrada[posicao] = tecla;
posicao++;
USART0_transmite_string_FLASH(PSTR("*"));
}
}
}
// Função para realizar debounce no SENSOR_PIN
bool debounceSensor() {
// Lê o estado inicial do sensor
bool estadoInicial = (PINC & (1 << SENSOR_PIN)) != 0;
_delay_ms(50); // Aguarda o tempo de debounce
bool estadoFinal = (PINC & (1 << SENSOR_PIN)) != 0;
return estadoInicial && estadoFinal; // Retorna verdadeiro se o estado for mantido
}