/*
============================================================
STAZIONE DI SCRITTURA TESSERE - Sistema RFID Hotel
============================================================
Scheda: Arduino Uno R3
Componenti collegati:
- Lettore/Scrittore RFID RC522 (SPI)
- Collegamento seriale USB al PC (monitor seriale)
FUNZIONAMENTO (dialogo tramite Monitor Seriale, 9600 baud,
impostare "Newline" o "Nessun fine riga + Newline" come terminatore):
1) Il sistema attende la tessera MASTER.
2) Una volta riconosciuta, chiede di digitare la chiave da
memorizzare (max 16 caratteri) e premere INVIO.
3) Chiede di avvicinare la tessera (vergine o gia' scritta) su cui
scrivere la chiave.
4) Scrive la chiave nel blocco 4 della tessera (Mifare Classic 1K),
conferma "Card scritta." e torna al punto 1.
Nota: l'UID della tessera MASTER (MASTER_UID) deve essere identico
a quello usato nelle schede di ogni camera (room_controller.ino).
COLLEGAMENTI:
RC522 -> SDA/SS D10, RST D9, MOSI D11, MISO D12, SCK D13, 3.3V, GND
*/
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
#define KEY_LEN 16
MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
// Deve essere identico all'UID usato nelle schede delle camere
byte MASTER_UID[4] = {0x01, 0x02, 0x03, 0x04};
const byte MASTER_UID_LEN = 4;
enum StatoSistema { ATTESA_MASTER, ATTESA_CHIAVE, ATTESA_CARD_DA_SCRIVERE };
StatoSistema stato = ATTESA_MASTER;
char chiaveDaScrivere[KEY_LEN + 1];
String bufferSeriale = "";
void setup() {
Serial.begin(9600);
while (!Serial) { ; } // attende l'apertura della porta seriale (utile su alcune schede)
SPI.begin();
rfid.PCD_Init();
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; // chiave Mifare di default
Serial.println(F("=== Stazione di scrittura tessere ==="));
Serial.println(F("Avvicinare la tessera MASTER per iniziare."));
}
void loop() {
switch (stato) {
case ATTESA_MASTER:
gestisciAttesaMaster();
break;
case ATTESA_CHIAVE:
gestisciAttesaChiave();
break;
case ATTESA_CARD_DA_SCRIVERE:
gestisciScritturaCard();
break;
}
}
// ================== FASE 1: attesa Master ==================
void gestisciAttesaMaster() {
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
if (confrontaUID(rfid.uid.uidByte, rfid.uid.size, MASTER_UID, MASTER_UID_LEN)) {
Serial.println(F("Master riconosciuta."));
Serial.println(F("Inserire la chiave da memorizzare e premere INVIO:"));
bufferSeriale = "";
stato = ATTESA_CHIAVE;
} else {
Serial.println(F("Tessera non riconosciuta come Master. Riprovare."));
}
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
}
// ================== FASE 2: attesa digitazione chiave ==================
void gestisciAttesaChiave() {
while (Serial.available()) {
char c = Serial.read();
if (c == '\n' || c == '\r') {
if (bufferSeriale.length() > 0) {
bufferSeriale.trim();
if (bufferSeriale.length() > KEY_LEN) bufferSeriale = bufferSeriale.substring(0, KEY_LEN);
strncpy(chiaveDaScrivere, bufferSeriale.c_str(), KEY_LEN);
for (byte i = bufferSeriale.length(); i < KEY_LEN; i++) chiaveDaScrivere[i] = ' '; // padding con spazi
chiaveDaScrivere[KEY_LEN] = '\0';
Serial.print(F("Chiave impostata: \""));
Serial.print(chiaveDaScrivere);
Serial.println(F("\""));
Serial.println(F("Avvicinare la card da scrivere:"));
stato = ATTESA_CARD_DA_SCRIVERE;
}
bufferSeriale = "";
return;
} else {
bufferSeriale += c;
}
}
}
// ================== FASE 3: scrittura sulla tessera ==================
void gestisciScritturaCard() {
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
if (confrontaUID(rfid.uid.uidByte, rfid.uid.size, MASTER_UID, MASTER_UID_LEN)) {
Serial.println(F("Non e' possibile scrivere sulla tessera Master. Avvicinare un'altra card."));
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
return;
}
byte blocco = 4; // settore 1, blocco 0 (blocco dati, non trailer)
MFRC522::StatusCode statoAuth = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, blocco, &key, &(rfid.uid));
if (statoAuth != MFRC522::STATUS_OK) {
Serial.print(F("Autenticazione fallita: "));
Serial.println(rfid.GetStatusCodeName(statoAuth));
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
return;
}
byte datiScrittura[16];
for (byte i = 0; i < 16; i++) datiScrittura[i] = chiaveDaScrivere[i];
MFRC522::StatusCode statoScrittura = rfid.MIFARE_Write(blocco, datiScrittura, 16);
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
if (statoScrittura == MFRC522::STATUS_OK) {
Serial.println(F("Card scritta."));
} else {
Serial.print(F("Errore in scrittura: "));
Serial.println(rfid.GetStatusCodeName(statoScrittura));
}
Serial.println();
Serial.println(F("Avvicinare la tessera MASTER per iniziare una nuova scrittura."));
stato = ATTESA_MASTER;
}
// ================== UTILITA' ==================
bool confrontaUID(byte* uid1, byte len1, byte* uid2, byte len2) {
if (len1 != len2) return false;
for (byte i = 0; i < len1; i++) if (uid1[i] != uid2[i]) return false;
return true;
}
Loading
mfrc522
mfrc522