Add PN532 self recovery to door firmware
This commit is contained in:
@@ -13,8 +13,18 @@
|
||||
Adafruit_PN532 nfc(PN532_IRQ_PIN, PN532_RESET_PIN, &Wire);
|
||||
|
||||
static unsigned long lastReadAt = 0;
|
||||
static unsigned long lastWifiAttemptAt = 0;
|
||||
static unsigned long lastPn532InitAt = 0;
|
||||
static unsigned long lastPn532HealthAt = 0;
|
||||
static String lastCredential = "";
|
||||
static bool wifiScanPrinted = false;
|
||||
static bool pn532Ready = false;
|
||||
static uint16_t emptyReadCount = 0;
|
||||
|
||||
const unsigned long WIFI_RETRY_MS = 15000;
|
||||
const unsigned long PN532_INIT_RETRY_MS = 5000;
|
||||
const unsigned long PN532_HEALTH_CHECK_MS = 120000;
|
||||
const uint16_t PN532_EMPTY_READ_REINIT_COUNT = 300;
|
||||
|
||||
String bytesToHex(const uint8_t *data, uint8_t length) {
|
||||
String out;
|
||||
@@ -114,6 +124,10 @@ void printWifiScan() {
|
||||
void connectWifi() {
|
||||
if (WiFi.status() == WL_CONNECTED) return;
|
||||
|
||||
unsigned long now = millis();
|
||||
if (lastWifiAttemptAt && now - lastWifiAttemptAt < WIFI_RETRY_MS) return;
|
||||
lastWifiAttemptAt = now;
|
||||
|
||||
WiFi.persistent(false);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.setSleep(false);
|
||||
@@ -140,7 +154,59 @@ void connectWifi() {
|
||||
}
|
||||
}
|
||||
|
||||
bool initializePn532(bool force = false) {
|
||||
unsigned long now = millis();
|
||||
if (!force && lastPn532InitAt && now - lastPn532InitAt < PN532_INIT_RETRY_MS) return pn532Ready;
|
||||
lastPn532InitAt = now;
|
||||
pn532Ready = false;
|
||||
|
||||
Serial.println("Initializing PN532...");
|
||||
pinMode(PN532_RESET_PIN, OUTPUT);
|
||||
digitalWrite(PN532_RESET_PIN, LOW);
|
||||
delay(25);
|
||||
digitalWrite(PN532_RESET_PIN, HIGH);
|
||||
delay(120);
|
||||
|
||||
Wire.end();
|
||||
delay(25);
|
||||
Wire.begin(PN532_SDA_PIN, PN532_SCL_PIN);
|
||||
Wire.setClock(100000);
|
||||
Wire.setTimeOut(60);
|
||||
|
||||
nfc.begin();
|
||||
uint32_t version = nfc.getFirmwareVersion();
|
||||
if (!version) {
|
||||
Serial.println("PN532 not found. Will retry without stopping controller.");
|
||||
return false;
|
||||
}
|
||||
|
||||
nfc.SAMConfig();
|
||||
emptyReadCount = 0;
|
||||
lastPn532HealthAt = now;
|
||||
pn532Ready = true;
|
||||
Serial.println("PN532 ready.");
|
||||
return true;
|
||||
}
|
||||
|
||||
void maintainPn532() {
|
||||
unsigned long now = millis();
|
||||
if (!pn532Ready) {
|
||||
initializePn532();
|
||||
return;
|
||||
}
|
||||
|
||||
if (now - lastPn532HealthAt < PN532_HEALTH_CHECK_MS) return;
|
||||
lastPn532HealthAt = now;
|
||||
|
||||
uint32_t version = nfc.getFirmwareVersion();
|
||||
if (!version) {
|
||||
Serial.println("PN532 health check failed; reinitializing.");
|
||||
initializePn532(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool readCardUid(uint8_t *uid, uint8_t *uidLength) {
|
||||
if (!pn532Ready && !initializePn532()) return false;
|
||||
return nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, uidLength, 350);
|
||||
}
|
||||
|
||||
@@ -173,7 +239,16 @@ String readMifareSecret(uint8_t *uid, uint8_t uidLength) {
|
||||
String readCredential() {
|
||||
uint8_t uid[7] = { 0 };
|
||||
uint8_t uidLength = 0;
|
||||
if (!readCardUid(uid, &uidLength)) return "";
|
||||
if (!readCardUid(uid, &uidLength)) {
|
||||
emptyReadCount++;
|
||||
if (emptyReadCount >= PN532_EMPTY_READ_REINIT_COUNT) {
|
||||
Serial.println("PN532 idle/read timeout threshold reached; reinitializing.");
|
||||
initializePn532(true);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
emptyReadCount = 0;
|
||||
|
||||
#if CARD_MODE == CARD_MODE_MIFARE_CLASSIC_BLOCK
|
||||
String secret = readMifareSecret(uid, uidLength);
|
||||
@@ -215,20 +290,12 @@ void setup() {
|
||||
|
||||
connectWifi();
|
||||
|
||||
Wire.begin(PN532_SDA_PIN, PN532_SCL_PIN);
|
||||
nfc.begin();
|
||||
uint32_t version = nfc.getFirmwareVersion();
|
||||
if (!version) {
|
||||
Serial.println("PN532 not found. Check wiring and mode switches.");
|
||||
while (true) delay(1000);
|
||||
}
|
||||
|
||||
nfc.SAMConfig();
|
||||
Serial.println("PN532 ready.");
|
||||
initializePn532(true);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
connectWifi();
|
||||
maintainPn532();
|
||||
|
||||
String credential = readCredential();
|
||||
if (!credential.length()) {
|
||||
|
||||
Reference in New Issue
Block a user