#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
// Pinos RFID e Periféricos
#define SS_1_PIN 53
#define RST_1_PIN 5
#define SS_2_PIN 4
#define RST_2_PIN 6
#define LED_VERDE 8
#define LED_VERMELHO 9
#define BUZZER 7
#define PIN_SERVO 11
#define PIN_BOTAO 10
MFRC522 mfrc522_1(SS_1_PIN, RST_1_PIN);
MFRC522 mfrc522_2(SS_2_PIN, RST_2_PIN);
Servo cancela;
byte tagCadastrada[] = {0xC0, 0xFF, 0xEE, 0x99};
int ultimoLeitor = 0;
bool primeiraLeituraValida = false;
unsigned long tempoUltimaLeitura = 0;
const long timeout = 30000;
const int POS_ABERTA = 90;
const int POS_FECHADA = 0;
void setup() {
Serial.begin(9600);
SPI.begin();
mfrc522_1.PCD_Init();
mfrc522_2.PCD_Init();
pinMode(LED_VERDE, OUTPUT);
pinMode(LED_VERMELHO, OUTPUT);
pinMode(BUZZER, OUTPUT);
pinMode(PIN_BOTAO, INPUT_PULLUP);
cancela.attach(PIN_SERVO);
cancela.write(POS_ABERTA);
}
void loop() {
if (ultimoLeitor != 0 && (millis() - tempoUltimaLeitura > timeout)) {
ultimoLeictor = 0;
}
if (mfrc522_1.PICC_IsNewCardPresent() && mfrc522_1.PICC_ReadCardSerial()) {
processarFluxo(1, mfrc522_1);
mfrc522_1.PICC_HaltA();
}
if (mfrc522_2.PICC_IsNewCardPresent() && mfrc522_2.PICC_ReadCardSerial()) {
processarFluxo(2, mfrc522_2);
mfrc522_2.PICC_HaltA();
}
}
void processarFluxo(int leitorID, MFRC522 &mfrc) {
bool tagAtualValida = compararUID(mfrc.uid.uidByte, mfrc.uid.size);
if (ultimoLeitor == 0) {
ultimoLeitor = leitorID;
primeiraLeituraValida = tagAtualValida;
tempoUltimaLeitura = millis();
}
else if (ultimoLeitor != leitorID) {
if (primeiraLeituraValida && tagAtualValida) {
// SUCESSO: Cadastro OK
if (ultimoLeitor == 1 && leitorID == 2) Serial.print("ENTRADA | TAG: ");
else Serial.print("SAIDA | TAG: ");
imprimirTag(mfrc.uid.uidByte, mfrc.uid.size);
digitalWrite(LED_VERDE, HIGH);
delay(2000);
digitalWrite(LED_VERDE, LOW);
}
else {
// ERRO: Tag não autorizada
Serial.print("ACESSO NEGADO | TAG: ");
imprimirTag(mfrc.uid.uidByte, mfrc.uid.size);
digitalWrite(LED_VERMELHO, HIGH);
tone(BUZZER, 200);
// CONDIÇÃO ESPECIAL: Se for Saída (2 para 1), NÃO fecha a cancela
if (ultimoLeitor == 2 && leitorID == 1) {
delay(2500); // Apenas sinaliza o erro por 2.5s
noTone(BUZZER);
digitalWrite(LED_VERMELHO, LOW);
}
else {
// Se for Entrada (1 para 2) ou qualquer outro erro, TRAVA TUDO
cancela.write(POS_FECHADA);
delay(2500);
noTone(BUZZER);
digitalWrite(LED_VERMELHO, LOW);
// Espera botão para liberar
while(digitalRead(PIN_BOTAO) == HIGH) {
delay(10);
}
cancela.write(POS_ABERTA);
}
}
ultimoLeitor = 0;
}
}
void imprimirTag(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? "0" : "");
Serial.print(buffer[i], HEX);
if (i < bufferSize - 1) Serial.print(":");
}
Serial.println();
}
bool compararUID(byte *buffer, byte bufferSize) {
if (bufferSize != 4) return false;
for (byte i = 0; i < 4; i++) {
if (buffer[i] != tagCadastrada[i]) return false;
}
return true;
}