#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal.h>
#define SS_PIN 10
#define RST_PIN 9
#define CLK_PIN 2
#define DT_PIN 3
#define SW_PIN 4
LiquidCrystal lcd(5, 6, 7, 8, A3, A4);
#define LED_VERMELHO A0
#define LED_VERDE A1
#define BUZZER_PIN A2
MFRC522 rfid(SS_PIN, RST_PIN);
enum Estado {
DESLIGADO,
LOOP_INICIAL,
AJUSTANDO_TEMPO,
CONTAGEM_REGRESSIVA,
TEMPO_ESGOTADO,
CONFIRMACAO_PRESENCA,
ATE_MAIS
};
Estado estadoAtual = DESLIGADO;
int tempoSelecionadoMin = 0;
long tempoRestanteSegundos = 0;
unsigned long ultimoSegundo = 0;
unsigned long tempoEstado = 0;
unsigned long ultimaInteracao = 0;
unsigned long trocaMensagem = 0;
unsigned long ultimoBuzzer = 0;
bool mensagemBemVindo = true;
bool buzzerLigado = false;
bool respostaPresenca = true;
int ultimoCLK = HIGH;
void atualizarLEDs() {
if (estadoAtual == DESLIGADO) {
digitalWrite(LED_VERMELHO, HIGH);
digitalWrite(LED_VERDE, LOW);
} else {
digitalWrite(LED_VERMELHO, LOW);
digitalWrite(LED_VERDE, HIGH);
}
}
void mostrarDesligado() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Aproxime cartao");
lcd.setCursor(0,1);
lcd.print("para iniciar");
}
void mostrarBemVindo() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Bem vindo!");
}
void mostrarQuantoTempo() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Quanto tempo");
lcd.setCursor(0,1);
lcd.print("vais ficar aqui?");
}
void mostrarTempoSelecionado() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Tempo: ");
lcd.print(tempoSelecionadoMin);
lcd.print(" min");
lcd.setCursor(0,1);
lcd.print("Aperte p/ OK");
}
void mostrarTempoRestante() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Tempo restante");
long min = tempoRestanteSegundos / 60;
long sec = tempoRestanteSegundos % 60;
lcd.setCursor(0,1);
if(min < 10) lcd.print("0");
lcd.print(min);
lcd.print(":");
if(sec < 10) lcd.print("0");
lcd.print(sec);
}
void mostrarTempoEsgotado() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Ainda esta aqui?");
lcd.setCursor(0,1);
lcd.print("Sim");
}
void mostrarPresenca() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Ainda esta aqui?");
lcd.setCursor(0,1);
lcd.print(respostaPresenca ? "Sim" : "Nao");
}
void mostrarAteMais() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Ate mais!");
}
void irParaDesligado() {
estadoAtual = DESLIGADO;
noTone(BUZZER_PIN);
buzzerLigado = false;
atualizarLEDs();
mostrarDesligado();
}
bool cartaoRFIDLido() {
if (!rfid.PICC_IsNewCardPresent()) return false;
if (!rfid.PICC_ReadCardSerial()) return false;
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
return true;
}
int lerEncoderPasso() {
int clkAtual = digitalRead(CLK_PIN);
int passo = 0;
if (clkAtual != ultimoCLK && clkAtual == LOW) {
if (digitalRead(DT_PIN) != clkAtual) passo = 1;
else passo = -1;
}
ultimoCLK = clkAtual;
return passo;
}
bool botaoEncoderPressionado() {
static int leituraAnterior = HIGH;
static int estadoEstavel = HIGH;
static unsigned long ultimaMudanca = 0;
bool pressionou = false;
int leitura = digitalRead(SW_PIN);
if (leitura != leituraAnterior) ultimaMudanca = millis();
if (millis() - ultimaMudanca > 35) {
if (leitura != estadoEstavel) {
estadoEstavel = leitura;
if (estadoEstavel == LOW) pressionou = true;
}
}
leituraAnterior = leitura;
return pressionou;
}
void setup() {
pinMode(CLK_PIN, INPUT_PULLUP);
pinMode(DT_PIN, INPUT_PULLUP);
pinMode(SW_PIN, INPUT_PULLUP);
pinMode(LED_VERMELHO, OUTPUT);
pinMode(LED_VERDE, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
lcd.begin(16,2);
SPI.begin();
rfid.PCD_Init();
atualizarLEDs();
mostrarDesligado();
}
void loop() {
int passoEncoder = lerEncoderPasso();
bool botao = botaoEncoderPressionado();
if (passoEncoder != 0 || botao) {
ultimaInteracao = millis();
}
atualizarLEDs();
switch (estadoAtual) {
case DESLIGADO:
if (cartaoRFIDLido()) {
estadoAtual = LOOP_INICIAL;
ultimaInteracao = millis();
trocaMensagem = millis();
mensagemBemVindo = true;
mostrarBemVindo();
}
break;
case LOOP_INICIAL:
if (millis() - ultimaInteracao >= 60000) {
irParaDesligado();
break;
}
if (mensagemBemVindo && millis() - trocaMensagem >= 2000) {
mensagemBemVindo = false;
trocaMensagem = millis();
mostrarQuantoTempo();
}
else if (!mensagemBemVindo && millis() - trocaMensagem >= 5000) {
mensagemBemVindo = true;
trocaMensagem = millis();
mostrarBemVindo();
}
if (passoEncoder != 0) {
tempoSelecionadoMin = 0;
if (passoEncoder > 0) tempoSelecionadoMin = 1;
estadoAtual = AJUSTANDO_TEMPO;
mostrarTempoSelecionado();
}
break;
case AJUSTANDO_TEMPO:
if (millis() - ultimaInteracao >= 60000) {
estadoAtual = LOOP_INICIAL;
trocaMensagem = millis();
mensagemBemVindo = true;
mostrarBemVindo();
break;
}
if (passoEncoder != 0) {
tempoSelecionadoMin += passoEncoder;
if (tempoSelecionadoMin < 0) tempoSelecionadoMin = 0;
if (tempoSelecionadoMin > 99) tempoSelecionadoMin = 99;
mostrarTempoSelecionado();
}
if (botao) {
tempoRestanteSegundos = (long)tempoSelecionadoMin * 60L;
estadoAtual = CONTAGEM_REGRESSIVA;
ultimoSegundo = millis();
mostrarTempoRestante();
}
break;
case CONTAGEM_REGRESSIVA:
if (millis() - ultimoSegundo >= 1000) {
ultimoSegundo = millis();
if (tempoRestanteSegundos > 0) {
tempoRestanteSegundos--;
mostrarTempoRestante();
} else {
estadoAtual = TEMPO_ESGOTADO;
tempoEstado = millis();
ultimoBuzzer = millis();
mostrarTempoEsgotado();
}
}
break;
case TEMPO_ESGOTADO:
if (millis() - tempoEstado >= 60000) {
irParaDesligado();
break;
}
if (millis() - ultimoBuzzer >= 1000) {
ultimoBuzzer = millis();
buzzerLigado = !buzzerLigado;
if (buzzerLigado) tone(BUZZER_PIN, 1000);
else noTone(BUZZER_PIN);
}
if (passoEncoder != 0) {
noTone(BUZZER_PIN);
respostaPresenca = false;
estadoAtual = CONFIRMACAO_PRESENCA;
mostrarPresenca();
}
break;
case CONFIRMACAO_PRESENCA:
if (passoEncoder != 0) {
respostaPresenca = !respostaPresenca;
mostrarPresenca();
}
if (botao) {
if (respostaPresenca) {
tempoSelecionadoMin = 0;
estadoAtual = AJUSTANDO_TEMPO;
mostrarTempoSelecionado();
} else {
estadoAtual = ATE_MAIS;
tempoEstado = millis();
mostrarAteMais();
}
}
break;
case ATE_MAIS:
if (millis() - tempoEstado >= 60000) {
irParaDesligado();
}
break;
}
}Loading
mfrc522
mfrc522