caligolas:
Dove sbaglio 
Mi dice sempre che la tessera che inserisco è valida.
Te lo spiegherò meglio qui sotto, ma, anche in questo caso, hai mescolato le cose soprattutto per quanto riguarda il discorso "String" contro "stringhe C" quindi per prima cosa ti conviene approfondire meglio (cercando in rete, ci sono parecchie pagine e tutorial) il discorso "stringhe C" ed EVITARE del tutto di usare gli oggetti String che, seppur "comodi" da usare, su Arduino sono fortemente sconsigliati.
Poi per aiutarti a comprendere meglio i tuoi stessi programmi, dovresti indentare correttamente il codice (per farlo fare un automatico dall'IDE premi Ctrl-T, e poi cerca di mantenere quello stile, e possibilmente imposta 2 caratteri per l''indentazione), cosa che aiuta anche noi a leggerli meglio visto che nel codice che hai postato ci sono "fisarmoniche" di linee di codice e graffe... 
Detto questo, veniamo al tuo codice.
Tu hai quindi sostituito le variabili String iniziali con l'array che ti ha correttamente consigliato @fratt ma poi tu dal lettore leggi in una variabile "String codiceLetto" (anche questa è da eliminare) e cerchi di confrontare queste due usando la funzione C "strcmp()" che invece serve per confrontare due stringhe "C" non oggetti della classe "String".
Poi, altro consiglio, anche se prendi codice trovato in rete non dare mai per scontato che sia perfetto al 100% e cerca di capire cosa fa e magari anche COME lo fa. Per dire, quel codice che stai cercando di creare mi pare chiaramente "derivato" da alcuni piccoli esempi postato in giro su varie pagine, ma per quelli l'uso di "String" è stato fatto esclusivamente per semplificare l'esempio, non per farne un codice realmente affidabile e/o utilizzabile.
E, infine, quando devi capire come fare qualcosa, cerca di SEPARARE i problemi e sperimentarli uno per volta. Quindi PRIMA vedi come acquisire correttamente le informazioni della card, e DOPO usare questa informazione per verificarne l'abilitazione.
Veniamo quindi a come stai leggendo il codice della card:
String codiceLetto ="";
Serial.println("Codice delle tessera letto:");
for(i = 0; i <= 4; i++)
{
codiceLetto+= String (RC522.serNum[i],HEX);
codiceLetto.toUpperCase();
}
Serial.println(codiceLetto);
L'array "serNum[]" contiene i byte ricevuti dalla card, tu qui li converti in esadecimale e alla fine li confronti con le chiavi abilitate. Teoricamente va bene, ma oltre al discorso di non mischiare "String" con "stringhe C" ossia in questo caso devi leggere il dato in una "stringa C", c'è anche il discorso che convertendo in stringa esadecimale con quel metodo non garantisci che il dato sia composto sempre esattamente da 2 caratteri esadecimali ad esempio "String(5,HEX)" restituisce "5" non "05". E tra l'altro devi pure convertire tutto in maiuscolo...
Quindi visto che i codici delle card abilitate li imposti come stringa C, dovresti usare anche come buffer una "stringa C", ossia "char []", con dimensione pari alla dimensione massima del codice (nel tuo caso 10 caratteri ovvero 5 byte) più uno, ed accumulare lì la stringa esadecimale.
Ma non è la soluzione più pratica, visto che la libreria della card usa un array di byte, per cui per il principio che è inutile fare conversioni non necessarie o non semplicissime "complicando" inutilmente il codice, dovresti ad esempio impostare i codici abilitati non come stringa, ma anche questi come byte.
In tal caso non serve più "leggere" il codice corrente dentro ad una variabile (puoi lasciare un ciclo per la sola visualizzazione su seriale del codice letto) e tutte le relative conversioni, ma ti basta confrontarlo con quelli abilitati che imposterai come:
...
#define MAX_ELENCO 3
#define DIM_CODICE 5
byte elenco[MAX_ELENCO][DIM_CODICE] = {
{0xFC, 0xA2, 0x33, 0x3B, 0x56},
{0xBA, 0xF1, 0xA5, 0x1A, 0xF4},
{0x00, 0x00, 0x00, 0x00, 0x00}
};
...
Quindi per mostrare sulla seriale il codice della tessera ti basta fare:
// Visualizza il codice della tessera
Serial.println("Tessera:");
for(byte i = 0; i <= 4; i++) {
// Se servono due caratteri aggiungo lo zero iniziale
if (RC522.serNum[i] < 16 ) Serial.print("0");
Serial.print(RC522.serNum[i], HEX);
Serial.print(" ");
}
Serial.println();
Per confrontare i codici ora ti basta "contare" quanti byte di una stessa card corrispondono al valore letto (vedi anche i commenti che ti ho messo, e ti consiglio sempre di metterli anche tu):
...
byte ok; // Indica quanti byte corrispondono
// Ciclo le card abilitate
for (byte card=0; card<MAX_ELENCO; ++card) {
// Conto quanti byte coincidono
ok = 0;
for(byte i=0; i<DIM_CODICE; i++) {
// Confronto i byte
if (RC522.serNum[i] != elenco[card][i])
break; // Se non corrisponde, passa alla card successiva
// Contiamo il byte giusto
++ok;
}
// Se l'ho trovata, esco
if (ok == DIM_CODICE)
break;
}
if (ok == DIM_CODICE){
Serial.println("autorizzata");
...
PS non ti assicuro che funzioni tutto, sta a te iniziare a capire il codice, come funziona, e se il caso anche come correggerlo.. 