#include <SPI.h>
#include <MFRC522.h>
#define MFRC522_SS 10 // Pino SS (Slave Select)
#define MFRC522_RST 9 // Pino de reset
#define MFRC522_INT 2 // Pino de interrupção
#define CARD_ID_MAX_LEN 6
#define CARD_ID_MIN_LEN 4
struct SystemInfo {
uint16_t battery_percent;
bool is_charging;
bool new_card;
byte card_uuid[CARD_ID_MAX_LEN];
bool new_save_result;
void reset() {
new_card = false;
memset(card_uuid, 0, sizeof(card_uuid));
}
};
SystemInfo si;
// Array para armazenar o NUID do cartão
byte nuidPICC[CARD_ID_MAX_LEN];
MFRC522 rfid(MFRC522_SS, MFRC522_RST); // Instância da classe MFRC522
volatile bool new_card = false;
void scan_irq() {
new_card = true;
}
void setup_rfid() {
SPI.begin(); // Inicia o barramento SPI
rfid.PCD_Init(); // Inicia o MFRC522
// Configura o pino de interrupção
pinMode(MFRC522_INT, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(MFRC522_INT), scan_irq, FALLING);
// Configura o registro para permitir interrupções
byte regVal = 0xA0; // IRQ de recepção
rfid.PCD_WriteRegister(rfid.ComIEnReg, regVal);
// Verifica a versão do MFRC522
byte readReg = rfid.PCD_ReadRegister(rfid.VersionReg);
Serial.print("RFID Ver: 0x");
Serial.println(readReg, HEX);
if (rfid.PCD_PerformSelfTest()) {
Serial.println("Self test passed");
} else {
Serial.println("Self test failed");
}
}
void activateRec(MFRC522 mfrc522) {
mfrc522.PCD_WriteRegister(mfrc522.FIFODataReg, mfrc522.PICC_CMD_REQA);
mfrc522.PCD_WriteRegister(mfrc522.CommandReg, mfrc522.PCD_Transceive);
mfrc522.PCD_WriteRegister(mfrc522.BitFramingReg, 0x87);
}
void clearInt(MFRC522 mfrc522) {
mfrc522.PCD_WriteRegister(mfrc522.ComIrqReg, 0x7F);
}
unsigned long reset_cached_card = 0;
bool read_card() {
if (!rfid.PICC_ReadCardSerial()) {
Serial.println("PICC_ReadCardSerial failed");
return false;
}
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
Serial.print("PICC type: ");
Serial.println(rfid.PICC_GetTypeName(piccType));
int rfid_uid_len = rfid.uid.size;
if (rfid_uid_len < CARD_ID_MIN_LEN) {
Serial.print("ID too short (");
Serial.print(rfid_uid_len);
Serial.println("), bailing");
return false;
}
if (memcmp(rfid.uid.uidByte, nuidPICC, std::min(rfid_uid_len, CARD_ID_MAX_LEN)) != 0) {
reset_cached_card = millis() + 300000;
Serial.println("A new card has been detected.");
rfid.PICC_DumpToSerial(&rfid.uid);
// Armazena o NUID no array nuidPICC
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
Serial.print("The NUID tag is: ");
Serial.println(toHex(rfid.uid.uidByte, rfid.uid.size).c_str());
return true;
} else {
Serial.println("Card read previously.");
return false;
}
}
void card_reader_loop(SystemInfo &system_info) {
if (reset_cached_card != 0 && millis() > reset_cached_card) {
Serial.println("Resetting cached RFID ID");
memset(nuidPICC, 0, sizeof(nuidPICC));
reset_cached_card = 0;
}
if (new_card) {
if (read_card()) {
system_info.new_card = true;
memset(system_info.card_uuid, 0, sizeof(system_info.card_uuid));
memcpy(system_info.card_uuid, nuidPICC, sizeof(system_info.card_uuid));
}
clearInt(rfid);
// Halt PICC
rfid.PICC_HaltA();
new_card = false;
// Stop encryption on PCD
rfid.PCD_StopCrypto1();
}
activateRec(rfid);
}
void setup() {
Serial.begin(115200);
Serial.println("Hello, Arduino Uno!");
setup_rfid();
}
void loop() {
Serial.println("Loop ...");
delay(100); // Ajuste o delay conforme necessário
card_reader_loop(si);
}
String toHex(byte *buffer, byte bufferSize) {
char s[bufferSize * 3 + 2] = {};
for (byte i = 0; i < bufferSize; i++) {
snprintf(s + i * 3, 4, "%02x ", buffer[i]);
}
return s;
}