使用 ESP32 在 Arduino IDE 上重置 MFRC 522 身份验证

MFRC 522 Authentication RESET on Arduino IDE with ESP32

我一直在为一个项目修补 MFRC-522 (RC-522) RFID 模块。

我正在使用旧密钥测试身份验证,以检查某个扇区(在我的例子中是扇区 2)的 RFID 密钥 A 是否与原始密钥不同,如果是,那么我将继续,否则我将继续想"register"通过更改密钥卡。

我一开始就被抓到检查不同的密钥身份验证,如果我测试了一个工作密钥然后一个不正确的密钥,它按预期工作,但如果我先用不正确的密钥测试,它甚至不允许用于验证的正确密钥。

如果我 运行 序列中所有内容下面的代码是

PCD_Authenticate() failed NEW(read): Timeout in communication.
PCD_Authenticate() failed OLD(read): Timeout in communication.

重复但是如果我翻转 old() 和 neww() 我得到

OLD WORKS
PCD_Authenticate() failed NEW(read): Timeout in communication.

为什么会这样?

#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN         22          // Configurable, see typical pin layout above
#define SS_PIN          21         // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

MFRC522::MIFARE_Key old_key = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
MFRC522::MIFARE_Key new_key = {0x23,0x54,0x64,0x3a,0x32,0x66};

void setup() {
    Serial.begin(115200);       // Initialize serial communications with the PC
    while (!Serial);        // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
    SPI.begin();            // Init SPI bus
    mfrc522.PCD_Init();     // Init MFRC522
    delay(4);               // Optional delay. Some board do need more time after init to be ready, see Readme
    mfrc522.PCD_DumpVersionToSerial();  // Show details of PCD - MFRC522 Card Reader details
    Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
    // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
        return;
    }

    // Select one of the cards
    if ( ! mfrc522.PICC_ReadCardSerial()) {
        return;
    }

    neww();
    old(); 
}


void old(){
  //authentication of the desired block for access
  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 15, &old_key, &(mfrc522.uid));

  if (status != MFRC522::STATUS_OK) {
         Serial.print("PCD_Authenticate() failed OLD(read): ");
         Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)status));
         return;
  }else {Serial.println("OLD WORKS");}
  //delay(1000);
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1(); 
}

void neww() {
  //authentication of the desired block for access
byte  status_new = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 15, &new_key, &(mfrc522.uid));

  if (status_new != MFRC522::STATUS_OK) {
         Serial.print("PCD_Authenticate() failed NEW(read): ");
         Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)status_new));
         return;
  } else {Serial.println("NEW WORKS");}
  //delay(1000);
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1(); 
}
}

因此,在仔细阅读数据表后,我得出的结论是卡的状态尚未准备好进行下一次读取,因此我提出了一个对我的案例有所帮助的全能解决方案,The Serial印刷品用于调试,因此如果使用代码,请随时将其注释掉。

  bool reselect_Card() {
  //-------------------------------------------------------
  // Can also be used to see if card still available,
  // true means it is false means card isnt there anymore
  //-------------------------------------------------------
        byte s;
        byte req_buff[2];
        byte req_buff_size=2;
        mfrc522.PCD_StopCrypto1();
        s = mfrc522.PICC_HaltA();
          Serial.print("Halt Status: ");
          Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)s));
       delay(100);
       s = mfrc522.PICC_WakeupA(req_buff,&req_buff_size);
          Serial.print("Request: ");
          Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)s));
          Serial.print("ATQA : ");
          Serial.println(dump_byte_array_to_string(req_buff,req_buff_size)); 
       delay(100);
       s = mfrc522.PICC_Select( &(mfrc522.uid),0);
          Serial.print("Selected : ");
          Serial.println(mfrc522.GetStatusCodeName((MFRC522::StatusCode)s)); 
       if( mfrc522.GetStatusCodeName((MFRC522::StatusCode)s) == F("Timeout in communication.") ) { return false;} 
       return true;
}