首页 > 解决方案 > 带有 ESP32 的 Arduino IDE 上的 MFRC 522 身份验证重置

问题描述

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

我正在使用旧密钥测试身份验证,以检查扇区(在我的情况下为扇区 2)的 RFID 密钥 A 是否与原始密钥不同,如果是,那么我会继续,如果不是,我想“注册"通过更改密钥来获得卡片。

一开始我在检查不同的密钥身份验证时被抓住了,如果我测试了一个工作密钥然后一个不正确的密钥,它会按预期工作,但是如果我先用不正确的密钥进行测试,它甚至不允许正确的密钥进行身份验证.

如果我以串行方式运行下面的代码

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(); 
}
}

标签: rfidarduino-ideesp32

解决方案


所以,在仔细阅读了数据表之后,我得出结论,卡的状态还没有准备好进行下一次阅读,所以我提出了一个全能的解决方案来帮助我的情况,串行打印是为了调试所以如果使用代码,请随时将它们注释掉。

  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;
}

推荐阅读