Introduzione al Progetto
La crescente necessità di sistemi di sicurezza robusti ha portato allo sviluppo di tecnologie avanzate nel campo delle serrature elettroniche. Il progetto di realizzazione di una serratura elettronica attraverso l’uso di Arduino, di un lettore RFID MFRC522 e di un attuatore solenoide rappresenta un esempio di come le innovazioni nel settore possano incrementare la sicurezza degli accessi. Utilizzando il RFID (Identificazione a Radiofrequenza), è possibile migliorare notevolmente il processo di autenticazione degli utenti e facilitare l’accesso agli ambienti protetti.
Le serrature elettroniche basate su RFID offrono numerosi vantaggi rispetto alle tradizionali serrature meccaniche. Essendo in grado di memorizzare un ampio numero di codici identificativi, queste serrature consentono di gestire più facilmente gli accessi, permettendo di aggiungere o rimuovere utenti rapidamente, senza l’intervento fisico nella serratura stessa. Inoltre, la chiarezza e la precisione nel tracciamento degli accessi rendono più semplice la registrazione delle attività, aumentando così la sicurezza generale del sistema.
Il lettore RFID MFRC522, in particolare, è un componente fondamentale per il nostro progetto. La sua capacità di leggere i tag RFID a breve distanza e di comunicare con Arduino attraverso un protocollo semplice rende l’integrazione del sistema un processo agevole. Alte prestazioni e un costo contenuto fanno del MFRC522 una scelta popolare tra i creatori di progetti di sicurezza.
In questo contesto, l’implementazione di un attuatore solenoide permette di controllare fisicamente l’apertura della serratura, offrendo un ulteriore livello di sicurezza. Questo progetto non solo rappresenta un passo verso l’innovazione nella sicurezza domestica, ma serve anche come spunto per sviluppare ulteriormente tecnologie simili con l’obiettivo di migliorare la protezione degli utenti.
Materiali Necessari
Per realizzare un progetto di implementazione di una serratura RFID con Arduino, è fondamentale disporre dei materiali giusti. Ogni componente gioca un ruolo essenziale nell’operatività dell’intero sistema. In primo luogo, è necessario un Arduino, il microcontrollore che costituisce il cuore del progetto. Sono disponibili vari modelli, ma l’Arduino Uno è una scelta comune per la sua facilità d’uso e compatibilità con diversi moduli.
Un altro componente cruciale è il lettore MFRC522, un modulo RFID che consente di identificare e autenticare i tag RFID. Questo lettore è noto per la sua precisione e low cost, rendendolo ideale per le applicazioni di sicurezza. I tag RFID, di solito forniti in dotazione, devono essere scelti in base alle esigenze specifiche del progetto.
Un solenoide è necessario per il meccanismo di blocco e sblocco della serratura. Questo componente elettromeccanico riceve un impulso dal microcontrollore per attivare o disattivare il meccanismo della serratura. Per la memorizzazione dei dati, una EEPROM o una scheda SD è utile per salvare le informazioni sui tag autorizzati, come i dati di accesso e le logiche di attivazione.
Oltre ai componenti principali, è indispensabile disporre di cablaggio appropriato per collegare i vari elementi. Cavi jumper, breadboard e resistenze possono essere necessari per garantire un montaggio sicuro ed efficace. Infine, strumenti come un saldatore e un multimetro possono aiutare durante il processo di assemblaggio e collaudo.
Per quanto riguarda i costi, i componenti necessari possono essere acquistati presso rivenditori online come Amazon, eBay o negozi specializzati in elettronica. La spesa totale può variare, ma si stima che il budget complessivo per un progetto di questo tipo si aggiri attorno ai 50-100 euro, a seconda delle scelte dei componenti e delle loro specifiche.
Schema Elettrico
Lo schema elettrico per la realizzazione di una serratura RFID con Arduino è fondamentale per garantire che tutti i componenti funzionino correttamente. Per questo progetto, i principali componenti includono un lettore RFID MFRC522, un solenoide, e ovviamente una scheda Arduino. Iniziamo analizzando le connessioni essenziali.
Il lettore MFRC522 si collega all’Arduino attraverso quattro pin principali: il pin SCK (Serial Clock) va al pin 13 di Arduino, il pin MOSI (Master Out Slave In) è collegato al pin 11, mentre il pin MISO (Master In Slave Out) va al pin 12. Infine, il pin SS (Slave Select) deve essere connesso al pin 10. Questa configurazione permette ad Arduino di comunicare correttamente con il lettore RFID.
Successivamente, per il solenoide, è necessario utilizzare un relè per controllare l’apertura e la chiusura della serratura. Il relè deve essere connesso a un pin digitale di Arduino, come il pin 8. Non dimenticate di alimentare il solenoide con una fonte di alimentazione esterna, poiché richiede una tensione più alta rispetto a quella fornita dall’Arduino. Idealmente, il relay deve essere inserito in serie con il solenoide. Assicuratevi di connettere un diodo in parallelo al solenoide per proteggere il circuito da possibili picchi di tensione.”
Infine, assicuratevi di avere una buona messa a terra nel progetto; la terra comune deve essere connessa tra Arduino, il lettore RFID, e l’alimentazione del solenoide. Questo schema elettrico è cruciale per il funzionamento sicuro e affidabile della serratura RFID. Se siete nuovi all’elettronica, non esitate a fare riferimento a risorse online o a collaborare con esperti per garantire che ogni connessione sia eseguita correttamente. In questo modo, la vostra implementazione sarà molto più efficace.
Programmazione di Arduino
La programmazione di Arduino è una fase cruciale per l’implementazione di un sistema di serratura RFID efficace. In primo luogo, è fondamentale configurare il lettore RFID MFRC522, che permette di leggere le schede RFID. Per fare ciò, è necessario installare la libreria MFRC522, facilmente accessibile tramite il gestore delle librerie di Arduino IDE. Una volta importata la libreria, si può iniziare a scrivere il codice che gestirà la lettura delle schede e l’interazione con i vari componenti del sistema.
Il codice per il lettore RFID inizia con l’inizializzazione della comunicazione SPI e del lettore MFRC522. È possibile utilizzare il comando mfrc522.PCD_Init(); per avviare il lettore. Dopodiché, si può implementare un ciclo che continua a controllare la presenza di schede RFID. L’uso della funzione mfrc522.PICC_IsNewCardPresent(); permette di determinare se una nuova scheda è stata presentata al lettore. Se una scheda viene rilevata, il programma può leggere l’UID utilizzando la funzione mfrc522.PICC_ReadCardSerial();.
Una volta letta la scheda, si deve decidere se essa corrisponde a un accesso autorizzato. Se l’UID è valido, è possibile attivare il solenoide per sbloccare la serratura. Questo può essere realizzato attraverso il controllo di un pin digitale di Arduino. Strutture di controllo come if-else aiutano a implementare questa logica. Inoltre, per registrare gli accessi, il sistema può utilizzare la memoria EEPROM o una scheda SD. La libreria EEPROM consente di scrivere e leggere i dati sugli accessi, mantenendo traccia di chi ha utilizzato il sistema.
Infine, la gestione dell’anti-tamper è essenziale per la sicurezza del progetto. Utilizzando sensori di movimento o di vibrazione, è possibile attivare un allarme se tentativi non autorizzati di manomissione vengono rilevati. Questo richiede ulteriore codice per gestire l’interruzione della normale operatività in caso di allerta, garantendo così un maggior livello di sicurezza al sistema di serratura RFID.
Configurazione del Lettore RFID
La configurazione del lettore RFID MFRC522 è un passo fondamentale per garantire un corretto funzionamento nel tuo progetto di serratura RFID con Arduino. Prima di tutto, è necessario connettere il lettore RFID al tuo microcontrollore utilizzando le seguenti pin: SDA a pin 10, SCK a pin 13, MOSI a pin 11, MISO a pin 12, e IRQ può rimanere non connesso. Assicurati di collegare anche i pin VCC e GND per fornire alimentazione al lettore. Dopo aver effettuato questi collegamenti, il tuo hardware sarà pronto per essere programmato.
Una volta effettuate le connessioni hardware, il passo successivo è configurare il software. Utilizzando l’ambiente Arduino IDE, installa la libreria MFRC522, che fornisce le funzioni necessarie per comunicare con il lettore. Dopo aver installato la libreria, puoi iniziare creando uno sketch di base per leggere le schede RFID. Questo codice iniziale dovrebbe inizializzare il lettore e controllare se la comunicazione è avvenuta con successo. Puoi eseguire un semplice loop che č controlla la presenza di una scheda e stampa l’ID della scheda sul monitor seriale.
In caso di problemi di lettura, ci sono alcune considerazioni da tenere a mente. Assicurati che le schede RFID siano pulite e non danneggiate. Inoltre, verifica che il lettore sia posizionato correttamente e che non vi siano interferenze esterne, come altre sorgenti di elettricità o segnali radio. Se le letture risulteranno lente o inaffidabili, considera di regolare la distanza tra il lettore e la scheda, mantenendo una distanza ottimale di circa 2-5 cm per garantire una risposta rapida e precisa. Questa configurazione di base è essenziale per ottimizzare le performance del lettore RFID e per preparare il sistema all’integrazione con il tuo progetto di serratura.
Implementazione dell’Anti-Tamper
L’implementazione di un sistema anti-tamper è cruciale per garantire la sicurezza di una serratura RFID basata su Arduino. Questo sistema è progettato per rilevare qualsiasi tentativo di manomissione e proteggere l’integrità della serratura. Tra le diverse misure di sicurezza che possono essere integrate, l’uso di sensori di movimento, rilevatori di apertura forzata e sistemi di allerta sono alcuni degli approcci più efficaci.
I sensori di movimento possono essere posizionati strategicamente attorno alla serratura per monitorare qualsiasi movimento non autorizzato. Questi sensori reagiscono a variazioni nel campo elettromagnetico e attivano un avviso quando viene rilevato un movimento sospetto. Utilizzando dei moduli di sensori PIR, si può garantire una copertura adeguata nelle aree vulnerabili, assicurando che eventuali intrusioni non passino inosservate.
Un altro componente fondamentale è il rilevatore di apertura forzata. Questi dispositivi possono essere collegati direttamente alla serratura RFID e agiscono come un meccanismo di protezione supplementare. Quando viene rilevata una forza eccessiva sulla serratura, il sistema può attivare un allarme o bloccare ulteriormente il meccanismo di accesso, rendendo difficile l’apertura non autorizzata della porta.
In aggiunta a questi sistemi, è possibile integrare altre misure di sicurezza, come allarmi sonori o visivi, che si attivano in caso di manomissione. Questa combinazione di tecnologie non solo scoraggia i malintenzionati, ma fornisce anche un sistema di monitoraggio efficace per la protezione della serratura RFID. Implementando queste soluzioni anti-tamper, il progetto complessivo guadagna in affidabilità e sicurezza, creando una serratura più robusta e resistente a tentativi di intrusione.
Salvataggio dei Dati di Accesso
La registrazione dei dati di accesso in un sistema di serrature RFID rappresenta un aspetto cruciale per migliorare la sicurezza e il monitoraggio dell’accesso. Due delle soluzioni più comuni per il salvataggio dei dati sono l’utilizzo della EEPROM e delle schede SD. La EEPROM, disponibile sulla maggior parte delle schede Arduino, consente di immagazzinare dati in modo permanente, anche quando l’alimentazione è spenta. Ciò significa che le informazioni relative agli accessi possono essere recuperate e analizzate in qualsiasi momento, rendendo questo metodo particolarmente vantaggioso per la gestione della sicurezza.
D’altra parte, l’uso di una scheda SD per il salvataggio dei dati di accesso offre vantaggi unici, come la possibilità di memorizzare grandi quantità di informazioni in un formato facilmente leggibile. Quando si integra una scheda SD nel progetto di serratura RFID, è possibile registrare eventi come data, ora e identificativo dell’utente che ha effettuato l’accesso. Questa capacità di archiviazione estesa è utile per effettuare analisi storiche e per migliorare la comprensione delle abitudini di accesso all’impianto.
La registrazione storica degli accessi non è solo utile per motivi di sicurezza, ma può anche fornire informazioni preziose su come e quando la serratura viene utilizzata. Ad esempio, sapere quali utenti accedono più frequentemente e a quali ore può aiutare a identificare potenziali problematiche di sicurezza o necessità di aggiornamenti nei sistemi di accesso. Inoltre, in caso di incidenti o accessi non autorizzati, avere una traccia registrata aiuta a ricostruire gli eventi e a prendere decisioni informate riguardo alla sicurezza complessiva dell’area.
Test e Validazione del Sistema
Una volta assemblato il sistema di serratura RFID utilizzando Arduino e il modulo MFRC522, è fondamentale sottoporre il dispositivo a una serie di test rigorosi per assicurarne il corretto funzionamento. La validazione del sistema non solo garantisce che tutti i componenti siano operativi, ma aiuta anche a identificare eventuali problemi che possono influire sulla sicurezza e sull’efficacia del dispositivo.
Il primo passo nel processo di test è effettuare un controllo della funzionalità di lettura RFID. Utilizzando una serie di card RFID, è opportuno verificare che il lettore sia in grado di riconoscere e autenticare correttamente le diverse schede. È consigliabile anche effettuare test di diverse distanze e angolazioni per assicurarsi che il sistema mantenga una buona capacità di lettura. Questo test di lettura RFID è essenziale per garantire che autorizzazioni non valide non possano accedere al sistema.
Successivamente, è cruciale testare l’attivazione del solenoide che controlla il meccanismo di apertura della serratura. Questo coinvolge il collegamento e la programmazione corretta del solenoide in modo che si attivi ogni volta che una scheda valida viene letta. La verifica della risposta del solenoide è fondamentale per assicurarsi che la serratura possa essere aperta senza problemi. È utile osservare anche la durata del ciclo di attivazione per garantire che il sistema non si surriscaldi.
In aggiunta ai test di lettura RFID e attivazione del solenoide, è essenziale effettuare verifiche relative all’anti-tamper. Questo potrebbe includere prove di resistenza fisica alla manipolazione del dispositivo e test di allerta in caso di manomissione. Attuare un sistema di notifica che avvisi l’utente di tentativi di bypass della serratura è una strategia efficace per incrementare la sicurezza del progetto. Gli utenti sono incoraggiati a condividere le loro esperienze e risultati per contribuire a migliorare la community dedicata a questo tipo di implementazione.
Conclusioni e Possibili Miglioramenti
Il progetto di implementazione di una serratura RFID con Arduino ha dimostrato di essere un’iniziativa efficace per migliorare la sicurezza degli accessi. Utilizzando componenti come il lettore MFRC522 e un sistema anti-tamper, abbiamo costruito un dispositivo che offre un buon livello di protezione e che può essere facilmente adattato a varie esigenze. I risultati ottenuti suggeriscono che questo sistema non solo funziona bene, ma è anche accessibile per chiunque desideri intraprendere un progetto simile.
Tuttavia, esistono numerosi potenziali miglioramenti che potrebbero ulteriormente valorizzare le funzionalità di questa serratura RFID. Una delle idee più promettenti è l’integrazione con un’app mobile, che permetterebbe agli utenti di gestire l’accesso in modo più flessibile e intuitivo. Questo potrebbe includere la possibilità di autorizzare nuovi utenti da remoto, monitorare gli accessi e ricevere notifiche in tempo reale. L’interfaccia mobile potrebbe diventare un hub centrale per gestire più serrature collegate, semplificando ulteriormente l’esperienza dell’utente.
Inoltre, l’implementazione di un sistema di allerta potrebbe rivelarsi vitale per aumentare la sicurezza. Ad esempio, sensori che segnalano tentativi di manomissione o accessi non autorizzati potrebbero fornire avvisi immediati all’utente, garantendo un ulteriore livello di protezione. Infine, si potrebbe esplorare l’aggiunta di funzioni biometriche per aumentare ulteriormente la sicurezza della serratura, rendendola meno vulnerabile agli attacchi.
In conclusione, il progetto ha creato una base solida che può essere sviluppata e ampliata. Con la giusta attenzione e pianificazione, la serratura RFID con Arduino potrebbe diventare non solo un dispositivo di sicurezza, ma una soluzione altamente funzionale e innovativa per la gestione degli accessi.
Ecco uno sketch Arduino completo per serratura RFID con MFRC522, solenoide via MOSFET/relè, logging su EEPROM e microSD con RTC opzionale, gestione Master e anti‑tamper.
Requisiti librerieMFRC522 di miguelbalboa (Installabile da Library Manager).
SD e SPI (incluse nell’IDE).
EEPROM (inclusa).
Opzionale: RTClib o gestione DS3231 con libreria adatta per timestamp accurati.
Pin e wiring usatiMFRC522: SS=10, RST=9, SCK=13, MOSI=11, MISO=12, 3.3 V; usare level‑shifter per linee da Arduino a RC522.
Solenoide: MOSFET N low‑side con diodo flyback; pin SOLENOID=5 (PWM possibile), GND comune a 12 V e Arduino.
Tamper: TAMPER_COVER=6 (NC verso GND, pull‑up attivo), TAMPER_LOOP=7 (NC), Buzzer=3, LED_G=4, LED_R=2, Pulsante uscita=8.
/* Serratura RFID MFRC522 + Solenoide + EEPROM + SD + Anti-tamper
- MFRC522: SS=10, RST=9 (SPI hw)
- Solenoide su pin 5 con MOSFET e diodo flyback
- Tamper: pin 6 (cover NC), pin 7 (loop NC)
- Buzzer 3, LED_G 4, LED_R 2, Exit button 8
- SD su CS=10 (condiviso con RC522: usare SS separato se shield; qui demo con SS_RFID=10, SS_SD=4)
*/
#include <SPI.h>
#include <MFRC522.h>
#include <EEPROM.h>
#include <SD.h>
#define SS_RFID 10
#define RST_RFID 9
#define SS_SD 4
#define PIN_SOLENOID 5
#define PIN_BUZZER 3
#define PIN_LED_G 4
#define PIN_LED_R 2
#define PIN_TAMPER_COVER 6
#define PIN_TAMPER_LOOP 7
#define PIN_EXIT_BTN 8
MFRC522 mfrc522(SS_RFID, RST_RFID);
File logFile;
// Configurazione
const unsigned long UNLOCK_MS = 1500;
const unsigned long REARM_DELAY_MS = 1500;
const char* LOG_FILE = "access.csv";
// EEPROM layout
// [0] magic 'R' [1] version 1
// [2] count (n card) [3].. UID list packed: len(1), bytes(4..7)
// [250..] param, flags
const int EE_MAGIC_ADDR = 0;
const int EE_VER_ADDR = 1;
const int EE_COUNT_ADDR = 2;
const int EE_DATA_ADDR = 3;
const byte EE_MAGIC = 'R';
const byte EE_VER = 1;
// Master card (fallback se EEPROM vuota): impostare qui il proprio UID in hex
byte MASTER_UID[] = {0xDE,0xAD,0xBE,0xEF};
byte MASTER_LEN = 4;
// Stato
bool tamperActive = false;
unsigned long lastUnlockMs = 0;
// Utilità EEPROM
int eeprom_writeBytes(int addr, const byte* data, byte len){
EEPROM.update(addr++, len);
for(byte i=0;i<len;i++) EEPROM.update(addr++, data[i]);
return 1 + len;
}
int eeprom_readBytes(int addr, byte* data, byte &len){
len = EEPROM.read(addr++);
for(byte i=0;i<len;i++) data[i] = EEPROM.read(addr++);
return 1 + len;
}
void eeprom_init_if_needed(){
if(EEPROM.read(EE_MAGIC_ADDR)!=EE_MAGIC || EEPROM.read(EE_VER_ADDR)!=EE_VER){
EEPROM.update(EE_MAGIC_ADDR, EE_MAGIC);
EEPROM.update(EE_VER_ADDR, EE_VER);
EEPROM.update(EE_COUNT_ADDR, 0);
// salva Master di default
int addr = EE_DATA_ADDR;
addr += eeprom_writeBytes(addr, MASTER_UID, MASTER_LEN);
EEPROM.update(EE_COUNT_ADDR, 1);
}
}
bool uid_equals(const byte* a, byte la, const byte* b, byte lb){
if(la!=lb) return false;
for(byte i=0;i<la;i++) if(a[i]!=b[i]) return false;
return true;
}
bool list_contains(const byte* uid, byte len){
byte count = EEPROM.read(EE_COUNT_ADDR);
int addr = EE_DATA_ADDR;
for(byte i=0;i<count;i++){
byte buf[10]; byte blen=0;
addr += eeprom_readBytes(addr, buf, blen);
if(uid_equals(uid,len,buf,blen)) return true;
}
return false;
}
bool list_add(const byte* uid, byte len){
if(list_contains(uid,len)) return false;
byte count = EEPROM.read(EE_COUNT_ADDR);
int addr = EE_DATA_ADDR;
for(byte i=0;i<count;i++){
byte tmp[10]; byte tlen=0;
addr += eeprom_readBytes(addr, tmp, tlen);
}
addr += eeprom_writeBytes(addr, uid, len);
EEPROM.update(EE_COUNT_ADDR, count+1);
return true;
}
bool list_remove(const byte* uid, byte len){
byte count = EEPROM.read(EE_COUNT_ADDR);
int readAddr = EE_DATA_ADDR;
int writeAddr = EE_DATA_ADDR;
byte newCount=0;
for(byte i=0;i<count;i++){
byte buf[10]; byte blen=0;
int consumed = 1 + EEPROM.read(readAddr); // len + bytes
readAddr += eeprom_readBytes(readAddr, buf, blen);
if(!uid_equals(uid,len,buf,blen)){
// copy
EEPROM.update(writeAddr++, blen);
for(byte j=0;j<blen;j++) EEPROM.update(writeAddr++, buf[j]);
newCount++;
}
}
// opzionale: riempire il resto con 0
EEPROM.update(EE_COUNT_ADDR, newCount);
return newCount < count;
}
// SD logging
void log_open(){
SD.begin(SS_SD);
logFile = SD.open(LOG_FILE, FILE_WRITE);
if(logFile && logFile.size()==0){
logFile.println("ms,event,uid_hex,info"); // header
logFile.flush();
}
}
void log_line(const char* event, const byte* uid, byte len, const char* info){
// timestamp semplificato: millis(); per RTC, sostituire con ISO da DS3231
char uidhex[3*10]; uidhex[0]='';
for(byte i=0;i<len;i++){
char b[4]; sprintf(b, "%02X", uid[i]);
strcat(uidhex, b);
if(i<len-1) strcat(uidhex, ":");
}
if(!logFile) log_open();
if(logFile){
logFile.print(millis()); logFile.print(",");
logFile.print(event); logFile.print(",");
logFile.print(uidhex); logFile.print(",");
logFile.println(info?info:"");
logFile.flush();
}
}
// Feedback
void beep(int ms){ tone(PIN_BUZZER, 3000, ms); }
void led_ok(){ digitalWrite(PIN_LED_G,HIGH); digitalWrite(PIN_LED_R,LOW); }
void led_err(){ digitalWrite(PIN_LED_G,LOW); digitalWrite(PIN_LED_R,HIGH); }
void led_off(){ digitalWrite(PIN_LED_G,LOW); digitalWrite(PIN_LED_R,LOW); }
// Solenoide
void unlock_pulse(){
digitalWrite(PIN_SOLENOID, HIGH);
delay(UNLOCK_MS);
digitalWrite(PIN_SOLENOID, LOW);
lastUnlockMs = millis();
}
// Tamper
bool tamper_now(){
bool cover = digitalRead(PIN_TAMPER_COVER); // NC -> HIGH = aperto
bool loopb = digitalRead(PIN_TAMPER_LOOP); // NC -> HIGH = taglio
return cover || loopb;
}
// Modalità programmazione con Master: aggiunge/rimuove card successiva
void program_mode(){
led_ok(); beep(80); delay(80); beep(80);
unsigned long t0 = millis();
while(millis()-t0 < 30000){
if(tamper_now()){ tamperActive=true; led_err(); beep(400); return; }
if(digitalRead(PIN_EXIT_BTN)==LOW) { break; }
if(!mfrc522.PICC_IsNewCardPresent()) continue;
if(!mfrc522.PICC_ReadCardSerial()) continue;
byte* uid = mfrc522.uid.uidByte;
byte len = mfrc522.uid.size;
if(list_contains(uid,len)){
list_remove(uid,len);
log_line("prog_remove", uid, len, "");
beep(200);
}else{
list_add(uid,len);
log_line("prog_add", uid, len, "");
beep(50); delay(70); beep(50);
}
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
delay(500);
}
led_off();
}
void setup(){
pinMode(PIN_SOLENOID, OUTPUT);
pinMode(PIN_LED_G, OUTPUT);
pinMode(PIN_LED_R, OUTPUT);
pinMode(PIN_BUZZER, OUTPUT);
pinMode(PIN_TAMPER_COVER, INPUT_PULLUP);
pinMode(PIN_TAMPER_LOOP, INPUT_PULLUP);
pinMode(PIN_EXIT_BTN, INPUT_PULLUP);
led_off();
SPI.begin();
mfrc522.PCD_Init();
eeprom_init_if_needed();
SD.begin(SS_SD);
log_open();
// Self-test
beep(60); delay(60); beep(60);
led_ok(); delay(200); led_err(); delay(200); led_off();
log_line("boot", NULL, 0, "start");
}
void loop(){
// Tamper handling
if(tamper_now()){
if(!tamperActive){
tamperActive = true;
led_err();
beep(400);
log_line("tamper", NULL, 0, "triggered");
}
}else if(tamperActive){
// resta in errore fino a Master
}
// Exit button consente uscita senza tag (sblocco locale)
if(!tamperActive && digitalRead(PIN_EXIT_BTN)==LOW && millis()-lastUnlockMs>REARM_DELAY_MS){
unlock_pulse();
log_line("exit", NULL, 0, "button");
}
// RFID
if(!mfrc522.PICC_IsNewCardPresent()) return;
if(!mfrc522.PICC_ReadCardSerial()) return;
byte* uid = mfrc522.uid.uidByte;
byte len = mfrc522.uid.size;
// Master?
bool isMaster = uid_equals(uid,len,MASTER_UID,MASTER_LEN) || list_contains(uid,len) && uid_equals(uid,len,MASTER_UID,MASTER_LEN);
// Nota: sopra si può sostituire con un flag dedicato per la prima entry EEPROM come Master
if(uid_equals(uid,len,MASTER_UID,MASTER_LEN)){
// Master gestisce tamper reset e program mode
if(tamperActive){
tamperActive = false;
led_off();
beep(150);
log_line("tamper_clear", uid, len, "");
}else{
program_mode();
}
}else if(!tamperActive && millis()-lastUnlockMs>REARM_DELAY_MS){
if(list_contains(uid,len)){
led_ok();
unlock_pulse();
beep(60);
log_line("grant", uid, len, "");
led_off();
}else{
led_err();
beep(200);
log_line("deny", uid, len, "unknown");
delay(400);
led_off();
}
}else{
// tamper o rearm
log_line(tamperActive?"blocked_tamper":"blocked_rearm", uid, len, "");
}
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
delay(150);
}
