Is it possible to integrate Adafruit PN532 library with ESP32 ?

Hello !

I am trying to integrate an RFID1356MIFARE with an ESP32-EVB using their UART capabilities.

I am aware that the Adafruit PN532 library doesn’t work on UART, but I have found a modified version of it: https://github.com/elechouse/PN532

I’ve tried the following code:

PN532_HSU pn532hsu(Serial1);
PN532 nfc(pn532hsu);

void setup() {
  enableCore1WDT();
  delay(100);
  Serial.begin(115200);

  nfc.begin();
  delay(100);

    uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1) delay(1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  
  // configure board to read RFID tags
  nfc.SAMConfig();
  
  Serial.println("Waiting for an ISO14443A Card ...");
  
// ...
}

void loop()
{
  delay(1);

  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
    
  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
  
  if (success) {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("  UID Value: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");
    
    if (uidLength == 4)
    {
      // We probably have a Mifare Classic card ... 
      Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
   
      // Now we need to try to authenticate it for read/write access
      // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
      Serial.println("Trying to authenticate block 4 with default KEYA value");
      uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
   
   // Start with block 4 (the first block of sector 1) since sector 0
   // contains the manufacturer data and it's probably better just
   // to leave it alone unless you know what you're doing
      success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);
   
      if (success)
      {
        Serial.println("Sector 1 (Blocks 4..7) has been authenticated");
        uint8_t data[16];
 
        // If you want to write something to block 4 to test with, uncomment
 // the following line and this text should be read back in a minute
        // data = { 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0};
        // success = nfc.mifareclassic_WriteDataBlock (4, data);

        // Try to read the contents of block 4
        success = nfc.mifareclassic_ReadDataBlock(4, data);
 
        if (success)
        {
          // Data seems to have been read ... spit it out
          Serial.println("Reading Block 4:");
          nfc.PrintHexChar(data, 16);
          Serial.println("");
   
          // Wait a bit before reading the card again
          delay(1000);
        }
        else
        {
          Serial.println("Ooops ... unable to read the requested block.  Try another key?");
        }
      }
      else
      {
        Serial.println("Ooops ... authentication failed: Try another key?");
      }
    }
    
    if (uidLength == 7)
    {
      // We probably have a Mifare Ultralight card ...
      Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)");
   
      // Try to read the first general-purpose user page (#4)
      Serial.println("Reading page 4");
      uint8_t data[32];
      success = nfc.mifareultralight_ReadPage (4, data);
      if (success)
      {
        // Data seems to have been read ... spit it out
        nfc.PrintHexChar(data, 4);
        Serial.println("");
 
        // Wait a bit before reading the card again
        delay(1000);
      }
      else
      {
        Serial.println("Ooops ... unable to read the requested page!?");
      }
    }
  }
}

The code above returns only “Didn’t find PN53x board”.

Inside the library I’ve modified PN532_HSU.cpp to force the library to work at the specified baud rate:

void PN532_HSU::begin()
{
    _serial->begin(38400, SERIAL_8N1, 36, 4);
}

If I change the code to a simple Serial read:

  start_time = millis();

  while(Serial1.available()<24 && (millis() - start_time) < MAX_MILLIS_TO_WAIT)
  {
    // hang here
  }

  if(Serial1.available()<24)
  {
    if(Serial1.available() != 0)
    {
      int foo[24];
      Serial.println("Error - < 24");

      for(int i=0; i<24; i++)
        foo[i] = Serial1.read();

      for(int i=0; i<24; i++)
        {
          Serial.print(foo[i]);
          Serial.print(" ");
        }

      Serial.println("\n");
      Serial1.flush();
    }
  }
  else
  {
    char array[24]; // change to 'int' if you want to see ASCII decimal
    for(int i=0; i<24; i++)
      array[i] = Serial1.read();
    
    for(int i=0; i<24; i++)
      {
        Serial.print(array[i]);
      }
      Serial.println();
      Serial1.flush();
      delay(1000);
  
}

I get:

13 10 45 65 65 48 52 70 48 50 67 13 10 69 82 82 58 48 120 49 52 13 10 62

// which translates to


-AA04F02C
ERR:0x14
>

// ERR:0x14 means Mifare: Authentication error (improper Key used)

Now this code only reads the tag bit by bit, but MIFARE is a little bit more complex and it requires authentication keys and all that magic which is a little above my skill level.

I found this thread Getting a PN532 NFC to work on UART - ESP32 Forum saying that the library should work over UART on an ESP32 with the modification that I’ve made.

My debug level is set to VERBOSE. I don’t get any errors with the above code. It just doesn’t work, and the only output I get is: “Didn’t find PN53x board”.

The library states that HSU uses 115200 baud rate and maybe this is the causing the issues.

What do you think ?

Thank you.

Later edit:

What if I get another 13.65Mhz card reader ? One that actually works with that library, say: PN532 NFC RFID module V4 [WIRELESS-NFC-PN532_V4] - $17.50 : Elechouse, Arduino Play House

I believe that that reader will work fairly easy on an Arduino but will work on an ESP32 ?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.