Controllo accessi in aree ristrette

SOMMARIO

Si propone di realizzare un semplice dispositivo di controllo accessi su aree ristrette (per esempio le stanze di un hotel o un insieme di uffici), con il quale un Superuser può, in modo semplice, abilitare o revocare l'ingresso ad un certo numero di RFID Cards. Il progetto utilizza lo stesso hardware descritto nel progetto Controllo accessi di un gruppo di armadietti (cui si rimanda per gli aspetti realizzativi), modificandone il Contesto d'uso, il Principio di funzionamento e, conseguentemente, il codice di Programmazione.

CONTESTO D'USO

Si immagina di elettrificare un gruppo di porte d'ingresso ad aree ristrette (stanze d'albergo, uffici, laboratori, ecc.), dotandole, sulla serratura di un blocco a solenoide.
Sono presenti un micro-bottone di Cancellazione (che deve risultare accessibile solo in fase di installazione o rimuovendo una copertura di protezione) e due led, un Led Verde e un Led Rosso, entrambi visibili all'esterno.

PRINCIPIO DI FUNZIONAMENTO

  • Il Superuser possiede una Passepartout Card per un accesso incondizionato al dispositivo e tre Card di Programmazione:
    • la Master Card che fa entrare o uscire il dispositivo dalla Fase di Programmazione;
    • la Add Card che abilita una User Card
    • la Remove Card che disabilita una User Card
  • in fase iniziale (o dopo la pressione per più di 5 secondi del Tasto di Cancellazione), il dispositivo richiede in sequenza che vengano avvicinate la Master, Add, Remove e Passepartout Card
  • per abilitare una o più User Card, va realizzata la sequenza:
    • 1) avvicinare la Master Card
    • 2) avvicinare la User Card da abilitare
    • 3) avvicinare la Add Card
    • 4) ripetere i punti 2) e 3) per quante User Card si vogliono abilitare
    • 5) avvicinare nuovamente la Master Card
  • per disabilitare una o più User Card, va realizzata la sequenza:
    • 1) avvicinare la Master Card
    • 2) avvicinare la User Card da disabilitare
    • 3) avvicinare la Remove Card
    • 4) ripetere i punti 2) e 3) per quante User Card si vogliono disabilitare
    • 5) avvicinare nuovamente la Master Card
Si possono memorizzare in modo non volatile (utilizzando la EEPROM del micorocontrollore) le quattro card speciali e fino a 250 User Cards per dispositivo.

PROGRAMMAZIONE

Il codice che realizza il funzionamento descritto precedentemente è mostrato qui di seguito:

/*
--------------------------------------------------------------
   Controllo Accessi con Master, Add Card, Remove e Pass Card 
--------------------------------------------------------------
Si usa una Master Card per programmare le Add Card e le Remove Card 
Queste permettono di registrare quali utenti di card possono accedere o no
Si memorizzano i risultati nella EEPROM di capacità 1kBytes
*/
#include <EEPROM.h>// Libreria di gestione EEPROM
#include <SPI.h> // Protocollo SPI
#include <MFRC522.h> // Libreria per il dispositivo Mifare RC522
constexpr uint8_t Led_Rosso = 4;
constexpr uint8_t Led_Verde = 3;
constexpr uint8_t Cancella = 2;// Tasto di cancellazione programmazione
constexpr uint8_t Consenso = 7;// Pin di consenso
boolean match = false;// initializza card match a falso
boolean programMode = false;// initializza programming mode a falso
boolean userCardSelect = false;// initializza userCardSelect a falso
boolean replaceMaster = false;
uint8_t successRead;// Variabile in caso di Lettura corretta dal Lettore RFID
byte storedCard[4];// ID letto dalla EEPROM
byte readCard[4];// ID letto dal Modulo RFID
byte masterCard[4];// ID della Master Card letto dalla EEPROM posizione 0 (2-5)
byte addCard[4];// ID della Add Card letto dalla EEPROM posizione 1 (6-9)
byte deleteCard[4];// ID della Add Card letto dalla EEPROM posizione 2 (10-13)
byte passCard[4];// ID della Pass Card letto dalla EEPROM posizione 3 (14-17)
byte userCard[4];// ID utente 
// La lista delle ID Utenti registrati a partire dalla locazione 18  
// Inizializza il Lettore RFID MFRC522
MFRC522 mfrc522(10, 9);
//////////// INIZIALIZZAZIONE ////////////
void setup() {
  //Configurazione del microcontrollore
  pinMode(Led_Rosso, OUTPUT);
  pinMode(Led_Verde, OUTPUT);
  pinMode(Cancella, INPUT_PULLUP);// Abilita il pull-up
  pinMode(Consenso, OUTPUT);
// Configurazione dei Pin al Reset
  digitalWrite(Consenso, LOW);// Serratura bloccata
  digitalWrite(Led_Rosso, HIGH);// Led Rosso spento
  digitalWrite(Led_Verde, HIGH);// Led Verde spento
//Configurazione Protocolli
  Serial.begin(9600); // Initializza la comunicazione seriale
  SPI.begin(); // Protocollo SPI per dialogo con RFID MFRC522
  mfrc522.PCD_Init(); // Initializza il lettore RFID MFRC522
//Guadagno Antenna al massimo aumenta la distanza di lettura
  mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
  Serial.println(F("Controllo Accessi: Versione 1.0"));
//Se è premuto il Tasto Cancellazione si cancella la EEPROM
  if (digitalRead(Cancella) == LOW) {
// inizio della procedura di cancellazione
    digitalWrite(Led_Rosso, LOW); 
    Serial.println(F("Premuto Tasto cancellazione dati memorizzati"));
    Serial.println(F("Per confermare tenere il tasto premuto per 10 secondi"));
    Serial.println(F("Questo rimuoverà tutti i dati in modo irreversibile"));
    bool buttonState = monitorCancella(5000); // Attesa di 5 secondi
// Se dopo 5 secondi il tasto è ancora premuto cancella la EEPROM
    if (buttonState == true && digitalRead(Cancella) == LOW) {    
      Serial.println(F("Inizio cancellazione dati memorizzati"));
// Loop di controllo fine EEPROM
      for (uint16_t x = 0; x < EEPROM.length(); x = x + 1) {    
        if (EEPROM.read(x) == 0) {              
//Se fine EEPROM è zero, la EEPROM è vuota 
// non fare nulla, la EPPROM è vuota, esci per risparmiare tempo 
// e cicli di scrittura della EEPROM
        }
        else {
// in questo caso scrivi zero per cancellare, impiegando 3.3mS
          EEPROM.write(x, 0);       
        }
      }
      Serial.println(F("Dati correttamente cancellati"));
// Lampeggio del Led Rosso di conferma cancellazione 
      digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
      delay(200);
      digitalWrite(Led_Rosso, LOW); // accendi il Led Rosso
      delay(200);
      digitalWrite(Led_Rosso, HIGH); // spegni il led Rosso
      delay(200);
      digitalWrite(Led_Rosso, LOW); // accendi il Led Rosso
      delay(200);
      digitalWrite(Led_Rosso, HIGH); // spegni il Led Rosso
    }
    else {
// Non si è atteso abbastanza tempo con il tasto premuto
      Serial.println(F("Cancellazione annullata")); 
      digitalWrite(Led_Rosso, HIGH);
    }
  }
// Controlla che le Program Cards siano definite,
// se no permetti all'utente di definirle
// Oppure si entra qui per ridefinire le Program Cards
// Si possono mantenere tutti gli altri dati registrati nella EEPROM
//  scrivendo 170 nella EEPROM all'indirizzo 1. 
// L'indirizzo 1 della EEPROM contiene il flag '170'
  if (EEPROM.read(1) != 170) {
    Serial.println(F("Program Cards non definite"));
    Serial.print(F("Per registrare le Program Cards avvicinare "));
    Serial.println(F("le card al lettore adesso"));
// Master Card
    Serial.println(F("In attesa della Master Card..."));
    do {
// se la lettura è avvenuta correttamente successRead = 1 altrimenti = 0
      successRead = getID();            
// Lampeggio del Led Rosso in attesa della lettura della Master Card
      digitalWrite(Led_Rosso, LOW);    // accendi il Led Rosso
      delay(200);
      digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
      delay(200);
    }
// il programma non va avanti fino a che non viene letta la Master Card correttamente
    while (!successRead);    
// Memorizzazione della Master Card ID nella EEPROM a partire dall'indirizzo 2  
    for ( uint8_t j = 0; j < 4; j++ ) {       
      EEPROM.write( 2 + j, readCard[j] );
    }
// Add Card
    Serial.println(F("In attesa della Add Card..."));
    do {
// se la lettura è avvenuta correttamente successRead = 1 altrimenti = 0
      successRead = getID();            
// Lampeggio del Led Verde in attesa della lettura della Add Card
      digitalWrite(Led_Verde, LOW);    // accendi il Led Verde
      delay(200);
      digitalWrite(Led_Verde, HIGH);  // spegni il Led Verde
      delay(200);
    }
// il programma non va avanti fino a che non viene letta la Add Card correttamente
    while (!successRead);   
// Memorizzazione della Add Card ID nella EEPROM a partire dall'indirizzo 6
    for ( uint8_t j = 0; j < 4; j++ ) {       
      EEPROM.write( 6 + j, readCard[j] );
    }
// Delete Card
    Serial.println(F("In attesa della Delete Card..."));
    do {
// se la lettura è avvenuta correttamente successRead = 1 altrimenti = 0
      successRead = getID();            
// Lampeggio del Led Rosso in attesa della lettura della Delete Card
      digitalWrite(Led_Rosso, LOW);    // accendi il Led Rosso
      delay(200);
      digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
      delay(200);
    }
// il programma non va avanti fino a che non viene letta la Delete Card correttamente
    while (!successRead);     
// Memorizzazione della Delete Card ID nella EEPROM a partire dall'indirizzo 10  
    for ( uint8_t j = 0; j < 4; j++ ) {       
      EEPROM.write( 10 + j, readCard[j] );
    }
// Pass Card
    Serial.println(F("In attesa della Pass Card..."));
    do {
// se la lettura è avvenuta correttamente successRead = 1 altrimenti = 0
      successRead = getID();            
// Lampeggio del Led Verde in attesa della lettura della Pass Card
      digitalWrite(Led_Verde, LOW);    // accendi il Led Verde
      delay(200);
      digitalWrite(Led_Verde, HIGH);  // spegni il Led Verde
      delay(200);
    }
// il programma non va avanti fino a che non viene letta la Pass Card correttamente
    while (!successRead);   
// Memorizzazione della Pass Card ID nella EEPROM a partire dall'indirizzo 14
    for ( uint8_t j = 0; j < 4; j++ ) {       
      EEPROM.write( 14 + j, readCard[j] );
    }
// Scrive nella EEPROM che le Program Cards sono state definite
    EEPROM.write(1, 170);   
    Serial.println(F("Program Cards definite correttamente"));
  }
  Serial.println(F("-------------------"));
  Serial.println(F("Master Card ID"));
  for ( uint8_t i = 0; i < 4; i++ ) { // Leggi la Master Card dalla EEPROM
    masterCard[i] = EEPROM.read(2 + i); // salva l'ID nel vettore masterCard
    Serial.print(masterCard[i], HEX);
  }
  Serial.println();
  Serial.println(F("-------------------"));  
  Serial.println(F("Add Card ID"));
  for ( uint8_t i = 0; i < 4; i++ ) { // Leggi la Add Card dalla EEPROM
    addCard[i] = EEPROM.read(6 + i); // salva l'ID nel vettore addCard
    Serial.print(addCard[i], HEX);
  }
  Serial.println();
  Serial.println(F("-------------------"));
  Serial.println(F("Delete Card ID"));
  for ( uint8_t i = 0; i < 4; i++ ) { // Leggi la Delete Card dalla EEPROM
    deleteCard[i] = EEPROM.read(10 + i); // salva l'ID nel vettore deleteCard
    Serial.print(deleteCard[i], HEX);
  }
  Serial.println();
  Serial.println(F("-------------------"));  
  Serial.println(F("Pass Card ID"));
  for ( uint8_t i = 0; i < 4; i++ ) {// Leggi la Delete Card dalla EEPROM
    passCard[i] = EEPROM.read(14 + i);// salva l'ID nel vettore passCard
    Serial.print(passCard[i], HEX);
  }
  Serial.println(); // solo per debug
  Serial.println(F("-------------------"));
  Serial.println(F("Sistema di Controllo Accessi pronto"));
  Serial.println(F("In attesa di leggere una card"));
  cycleLeds(); // Segnala l'attesa con un lampeggio in sequenza dei Led Rosso, Verde
}
///////////// FINE INIZIALIZZAZIONE ///////////// 
///////////// PROGRAMMA PRINCIPALE ///////////// 
void loop () {
  do {
// mette successRead = 1 se si arriva una lettura dal lettore altrimenti = 0
    successRead = getID();  
// Se adesso viene premuto il Tasto Cancellazione per più di 10 secondi 
// si comanda la cancellazione del solo ID di Master Card
// Controlla che il Tasto Cancellazione sia premuto
    if (digitalRead(Cancella) == LOW) { 
// In caso di Tasto premuto
// interruzione delle operazioni per cancellare la Master Card
      digitalWrite(Led_Rosso, LOW);  
      digitalWrite(Led_Verde, HIGH);  // spegne il Led Verde
      Serial.println(F("Premuto il Tasto Cancellazione"));
      Serial.print(F("Gli ID delle Programs Cards saranno "));
      Serial.println(F("cancellati fra dieci secondi!"));
      bool buttonState = monitorCancella(5000); // Attesa dei 5 secondi
// se il Tasto è ancora premuto, cancella gli ID delle Program Cards
      if (buttonState == true && digitalRead(Cancella) == LOW) {
// Cancella il flag di Program Cards definito all'indirizzo 1 della EEPROM    
        EEPROM.write(1, 0); 
        Serial.println(F("Gli ID di Program Cards cancellati dal dispositivo"));
        Serial.print(F("Eseguire il Reset per riprogrammare "));
        Serial.println(F("gli ID delle Program Cards"));
        do  {
// Lampeggio del Led Rosso in attesa del Reset
          digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
          delay(200);
          digitalWrite(Led_Rosso, LOW);   // accendi il Led Rosso
          delay(200);          
        }
        while (1);
      } 
// Non si è atteso abbastanza tempo con il tasto premuto
      Serial.println(F("Cancellazione ID di Program Cards annullata"));
    }
    if (programMode) {
// Lampeggio in sequenza dei Led per segnalare la condizione di Modo Programmazione
      cycleLeds();              
    }
    else {
// Nel Modo Operativo Normale i Led sono spenti
      normalModeOn();     
    }
  }
// il programma non va avanti se non ottiene una lettura corretta dal Lettore RFID
  while (!successRead);   
  if (programMode) {
    // Modo Programmazione attivo
//Se card letta è la Master Card, esce dal Modo Programmazione
    if (isMaster(readCard) ) { 
// La card letta è la Master Card 
      Serial.println(F("Letta la Master Card"));
      Serial.println(F("Fine Modo Programmazione"));
      Serial.println(F("-----------------------------"));
      programMode = false;
      return;
    }
    else if(checkTwo(readCard, addCard)) {
      if(userCardSelect) {
         if(findID(userCard)) {
// Carta già presente
          Serial.println(F("Card già presente"));      
        }
        else {
// Carta non presente da aggiungere
          writeID(userCard); // aggiunge l'ID nella lista                
        }
        userCardSelect = false;       
      }
      Serial.print(F("Avvicina al lettore la card Utente "));
      Serial.println(F("da aggiungere o rimuovere"));
      Serial.print(F("Successivamente avvicina al lettore la Add Card "));
      Serial.println(F("per aggiungere o la Delete Card per rimuovere la user Card"));              
    }
    else if(checkTwo(readCard, deleteCard)) {
      if(userCardSelect) {    
        if(findID(userCard)) {
// Carta presente da rimuovere
          Serial.println(F("Card presente in lista da rimuovere..."));
          deleteID(userCard); // cancella l'ID dalla lista           
        }
        else {
// Carta non presente
          Serial.println(F("Card non presente"));
        }
        userCardSelect = false;
      }
      Serial.print(F("Avvicina al lettore una card Utente "));
      Serial.println(F("da aggiungere o rimuovere"));
      Serial.print(F("Successivamente avvicina al lettore la Add Card "));
      Serial.println(F("per aggiungere o la Delete Card per rimuovere la user Card"));               
    }    
    else if(checkTwo(readCard, passCard)) {
// La card letta è la Passpartout;
      Serial.println(F("Card Passpartout non necessario memorizzarla"));
      Serial.print(F("Avvicina al lettore una card Utente "));
      Serial.println(F("da aggiungere o rimuovere"));
      Serial.print(F("Successivamente avvicina al lettore la Add Card "));
      Serial.println(F("per aggiungere o la Delete Card per rimuovere la user Card"));
    }
    else {
// La card letta è una userCard
      Serial.println(F("letta userCard "));
      for ( uint8_t i = 0; i < 4; i++ ) {
        userCard[i] = readCard[i];   // salva i valori letti nel vettore userCard
      }
      userCardSelect = true; 
      Serial.print(F("Avvicina al lettore la Add Card "));
      Serial.println(F("per aggiungere o la Delete Card per rimuovere la user Card"));
    }
    Serial.print(F("Avvicina al lettore la Master Card "));
    Serial.println(F("di nuovo per uscire dal Modo Programmazione"));
    Serial.println(F("-----------------------------"));
  }
  else {
// Modo Programmazione non attivo
// Se la card letta è la Master Card, entra in Modo Programmazione
    if ( isMaster(readCard)) { 
// La card letta è la Master Card
      programMode = true;
      userCardSelect = false;  // initializza userCardSelect a falso
      Serial.println(F("Benvenuto in Modo Programmazione"));
      uint8_t count = EEPROM.read(0); // contatore count di lista
      Serial.print(F("Ci sono ")); // indica il numero di ID memorizzati
      Serial.print(count);
      Serial.print(F(" ID(s) memorizzati"));
      Serial.println();
      Serial.print(F("Avvicina al lettore la card Utente "));
      Serial.println(F("da aggiungere o rimuovere"));
      Serial.print(F("Successivamente avvicina al lettore la Add Card "));
      Serial.println(F("per aggiungere o la Delete Card per rimuovere la user Card"));     
      Serial.print(F("Avvicina al lettore la Master Card di nuovo "));
      Serial.println(F("per uscire dal Modo Programmazione"));
      Serial.println(F("-----------------------------"));
    }
    else {
// La card letta NON è la Master Card
      if(checkTwo(readCard, passCard)) {
// La card letta è la Passpartout
        Serial.println(F("Card Passpartout, porta sbloccata"));
        granted(1000); // dà il consenso all'apertura per 1 secondo   
      }
// Controlla se la card letta è nella lista memorizzata   
      else if (findID(readCard)) { 
// La card letta è nella lista memorizzata
        Serial.println(F("Card autorizzata, porta sbloccata"));
        granted(1000); // dà il consenso all'apertura per 1 secondo
      }
      else {      
// La card letta NON è nella lista memorizzata
        Serial.println(F("Card non autorizzata"));
        denied();
      }
    }
  }
}
/////////// Accesso concesso /////////// 
void granted ( uint16_t setDelay) {
  digitalWrite(Led_Rosso, HIGH);  //spegni il Led Rosso
  digitalWrite(Led_Verde, LOW);   // Accendi il Led Verde
  digitalWrite(Consenso, HIGH);     // Sblocca la porta
  delay(setDelay);          // Tieni il consenso per il tempo selezionato
  digitalWrite(Consenso, LOW);    // Blocca la porta
  delay(1000);            // aspetta un secondo
}
/////////// Accesso negato ///////////
void denied() {
  digitalWrite(Led_Verde, HIGH);   // spegni il Led Verde 
  digitalWrite(Led_Rosso, LOW);   //  accendi il Led Rosso
  delay(1000); // aspetta un secondo
}
/////////// Acquisisci l'ID di una card /////////// 
uint8_t getID() {
// Prepara la lettura di un ID
  if ( ! mfrc522.PICC_IsNewCardPresent()) { // se non c'è una card esci
    return 0; // segnala lettura non eseguita
  } 
//fino a che la lettura non è terminata correttamente esci
  if ( ! mfrc522.PICC_ReadCardSerial()) {  
    return 0; // segnala lettura non esguita
  }
// Si legge la card a 4 bytes
// Non supporta la lettura della card a 7 bytes
  Serial.println(F(" Card ID letto:"));
  for ( uint8_t i = 0; i < 4; i++) {
    readCard[i] = mfrc522.uid.uidByte[i];
    Serial.print(readCard[i], HEX);
  }
  Serial.println();
  mfrc522.PICC_HaltA(); // termina lettura
  return 1;
}
/////////// Lampeggio in sequenza (Modo Programmazione) /////////// 
void cycleLeds() {
  digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
  digitalWrite(Led_Verde, LOW);   // accendi il Led Verde
  delay(200);
  digitalWrite(Led_Rosso, LOW);    // accendi il Led Rosso
  digitalWrite(Led_Verde, HIGH);   // spegni il Led Verde
  delay(200);
}
/////////// Led in Modo Normale /////////// 
void normalModeOn () {
  digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
  digitalWrite(Led_Verde, HIGH);  // spegni il Led Verde
  digitalWrite(Consenso, LOW);    // porta bloccata
}
/////////// Read an ID from EEPROM /////////// 
void readID( uint8_t number ) {
// Posizione di partenza start = posizione nella lista * 4 a partire dall'indirizzo 2
  uint8_t start = (number * 4 ) + 14;    
  for ( uint8_t i = 0; i < 4; i++ ) {
// Salva i valori letti al vettore storedCard
     storedCard[i] = EEPROM.read(start + i); 
  }      
}
/////////// Aggiungi un ID alla EEPROM ///////////
void writeID( byte a[] ) {
// Prima di scrivere l'ID nella EEPROM si controlla che non ci sia già! 
  if (!findID(a)) {
// Metti in num il numero di elementi memorizzati nella lista,
// considerato che nella posizione 0 è memorizzato l'ID della Master Card 
    uint8_t num = EEPROM.read(0); 
    uint8_t start = ( num * 4 ) + 18;  // Calcola la prima locazione libera
    num++; // Incrementa il contatore di una locazione
    if(num<250) { 
      EEPROM.write( 0, num ); // Aggiorna il valore del contatore nell'indirizzo 0
      for ( uint8_t j = 0; j < 4; j++ ) {
        // scrivi i valori nella giusta locazione della EEPROM   
        EEPROM.write( start + j, a[j] ); 
      }
      successWrite();
      Serial.println(F("ID della card letta aggiunto correttamente"));      
    }
    else {
      failedWrite();
      Serial.println(F("Memoria piena"));
    }    
  }
  else {
    failedWrite();
    Serial.println(F("Memorizzazione ID card letta fallita"));
  }
}
/////////// Rimuovi un ID dalla EEPROM ///////////
void deleteID( byte a[] ) {
// Prima di cancellarlo, verifica che sia in lista!
  if ( !findID( a ) ) {     
    failedWrite();      // se non c'è
    Serial.println(F("Cancellazione ID card letta fallita"));
  }
  else {
// Metti in num il numero di elementi memorizzati nella lista,
// considerato che nella posizione 0 è memorizzato l'ID della Master Card
    uint8_t num = EEPROM.read(0); 
    uint8_t slot; // posizione della card da rimuovere
    uint8_t start; // = ( num * 4 ) + 6; // Calcola la prima locazione libera 
    uint8_t looping; // numero ripetizioni
    uint8_t j;
    uint8_t count = EEPROM.read(0); // contatore di card memorizzate
    slot = findIDSLOT(a);   // calcola la posizione della card da rimuovere
    start = (slot * 4) + 14;
    looping = ((num - slot) * 4);
    num--;      // Decrement the counter by one
    EEPROM.write( 0, num );   // aggiorna il contatore all'indirizzo 0
    for ( j = 0; j < looping; j++ ) {
// sposta in su di 4 posizioni gli elementi di lista successivi a quello da rimuovere
      EEPROM.write( start + j, EEPROM.read(start + 4 + j));   
    }
    for ( uint8_t k = 0; k < 4; k++ ) { 
      EEPROM.write( start + j + k, 0);
    }
    successDelete();
    Serial.println(F("ID rimosso correttamente dalla lista memorizzata"));
  }
}
/////////// Controlla i bytes di due vettori ///////////
boolean checkTwo ( byte a[], byte b[] ) {
  if ( a[0] != 0 )      // verifica che a non sia nullo
    match = true;       // Assumi che siano uguali
  for ( uint8_t k = 0; k < 4; k++ ) {   
    if ( a[k] != b[k] )     // a != b match = false
      match = false;
  }
  if (match) {  
    return true;
  }
  else  {
    return false;
  }
}
/////////// Trova la Posizione di un ID nella lista ///////////
uint8_t findIDSLOT( byte find[] ) {
  uint8_t count = EEPROM.read(0);       // contatore di ID
  for ( uint8_t i = 1; i <= count; i++ ) { // esamina la lista memorizzata in EEPROM
    readID(i);                // metti in storedCard l'ID corrente della lista
    if ( checkTwo( find, storedCard ) ) {   // confronta ciascun elelmento della lista con l'ID  da trovare 
      // trovato!
      return i;         // restituisci la posizione
      break;          // fermati
    }
  }
}
/////////// Trova l'ID nella EEPROM ///////////
boolean findID( byte find[] ) {
  uint8_t count = EEPROM.read(0);     // contatore di ID
  for (uint8_t i = 1; i<= count; i++) { // esamina la lista memorizzata in EEPROM 
    readID(i);
// Confronta ciascun elelmento della lista con l'ID  da trovare     
    if (checkTwo(find, storedCard)){   
      return true;
      break;  // trovato 
    }
    else{    // non trovato
    }
  }
  return false;
}
/////////// Lampeggio di conferma scrittura nella EEPROM ///////////
// Lampeggio di tre volte per il Led Verde
void successWrite() {
  digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
  digitalWrite(Led_Verde, HIGH);  // spegni il Led Verde
  delay(200);
  digitalWrite(Led_Verde, LOW);   //accendi il Led Verde
  delay(200);
  digitalWrite(Led_Verde, HIGH);  // spegni il Led Verde
  delay(200);
  digitalWrite(Led_Verde, LOW);  // accendi il Led Verde
  delay(200);
  digitalWrite(Led_Verde, HIGH);  // spegni il Led Verde
  delay(200);
  digitalWrite(Led_Verde, LOW);   // accendi il Led Verde
  delay(3000);
}
/////////// Lampeggio di fallimento scrittura nella EEPROM ///////////
// Lampeggio di tre volte per il Led Giallo
void failedWrite() {
  digitalWrite(Led_Rosso, LOW);   // accendi il Led Rosso
  delay(200);
  digitalWrite(Led_Rosso, HIGH);   // spegni il Led Rosso
  delay(200);
  digitalWrite(Led_Rosso, LOW);   // accendi il Led Rosso
  delay(200);
  digitalWrite(Led_Rosso, HIGH);    // spegni il Led Red
  delay(200);
  digitalWrite(Led_Rosso, LOW);   // accendi il Led Red
  delay(3000);
}
/////////// Lampeggio di conferma rimozione ID dalla EEPROM ///////////
// Lampeggio di tre volte per il Led Rosso
void successDelete() {
  digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
  digitalWrite(Led_Verde, HIGH); // spegni il Led Verde
  delay(200);
  digitalWrite(Led_Rosso, LOW);   // accendi il Led Rosso
  delay(200);
  digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
  delay(200);
  digitalWrite(Led_Rosso, LOW);   // accendi il Led Rosso
  delay(200);
  digitalWrite(Led_Rosso, HIGH);  // spegni il Led Rosso
  delay(200);
  digitalWrite(Led_Rosso, LOW);   // accendi il Led Rosso
  delay(3000); 
}
/////////// Controlla che la readCard sia masterCard ///////////
boolean isMaster( byte test[] ) {
  if ( checkTwo( test, masterCard ) )
    return true;
  else
    return false;
}
/////////// Test del Tasto di Cancellazione ///////////
bool monitorCancella(uint32_t interval) {
  uint32_t now = (uint32_t)millis();
  while ((uint32_t)millis() - now < interval)  {
    // check on every half a second
    if (((uint32_t)millis() % 500) == 0) {
      if (digitalRead(Cancella) != LOW)
        return false;
    }
  }
  return true;
}

Una volta testato il dispositivo e compresone il funzionamento è possibile eliminare dal codice tutti i messaggi verso la seriale del PC.