ESP8266 and PN532, almost there

I have a ESP8266 (Wemos D1 Mini) connected to PN532. It seams to communicate with PN532 but I can’t read any tags. My debug:

    Found chip PN532
    Firmware ver. 1.6
    NFC reader is back!
    Starting NFC...
    Found chip PN532
    Firmware ver. 1.6
    NFC init done.
    Timed out waiting for a card

The code:

    #include <SPI.h>
    #include <Adafruit_PN532.h>

    // Connect to the PN532 using a hardware SPI connection. 
    // Pins need to be connected as follows:
    //  PN532 <---> NodeMCU
    //  -------------------
    //   MOSI <---> D7
    //   MISO <---> D6
    //    SCK <---> D5
    //     SS <---> D4
    #define IO_PN532_SS     (D4)

    Adafruit_PN532 nfc(IO_PN532_SS);

    bool nfcReaderInitialized = false;

    void setup() {
      Serial.println("Initializing NFC reader...");
      if ( initializeNFCReader() ) {
        nfcReaderInitialized = true;
        Serial.println("NFC reader initialized.");
      } else {
        nfcReaderInitialized = false;
        Serial.println("No dice. Continuing anyway. Will try to reinit later.");

    void loop() {
        if ( isNFCReaderPresent() ) {
          if ( ! nfcReaderInitialized ) {
            //it's back! reinitialize it
            Serial.println("NFC reader is back!");
            nfcReaderInitialized = initializeNFCReader();
          } //end if-initialized
          String nfcID = checkNFC();

    bool initializeNFCReader() {
      Serial.println("Starting NFC...");
      if ( ! isNFCReaderPresent() ) {
        Serial.println("Didn't find PN53x board");
        Serial.println("NFC init failed!");
      } else {
        // Set the max number of retry attempts to read from a card
        // This prevents us from waiting forever for a card, which is
        // the default behaviour of the PN532.
        // configure board to read RFID tags
        Serial.println("NFC init done.");
        return true;
      return false;

    bool isNFCReaderPresent() {
      uint32_t versiondata = nfc.getFirmwareVersion();
      if ( versiondata ) {
          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);
        return true;
      return false;

    String checkNFC() {
      boolean 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)
      String strUID = "";
      // 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[0], &uidLength, 1000);
      if (success) {
        Serial.println("Found a card!");
        Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
        Serial.print("UID Value: ");
        for (uint8_t i=0; i < uidLength; i++) 
          Serial.print(" 0x");Serial.print(uid[i], HEX); 
          strUID += hexlify(uid[i]);
        // PN532 probably timed out waiting for a card
        Serial.println("Timed out waiting for a card");
      return strUID;

    String hexlify(uint8_t byte) {
      // Conver the integer to a string with the hex value:
      String hexedString = String(byte, HEX);

      // Add prepended '0' if needed:
      if (hexedString.length() == 1) {
        hexedString = "0" + hexedString;

      return hexedString;

Any ideas?

According to the library source code you’re using the wrong call:

// wait for a card to enter the field (only possible with I2C)

@pylon, thank you for the answer, could you help me, what I need to do to resolve this please?

@pylon, I just looked at the code of Adafruit_PN532.cpp, this statement is only valid, if I use I2C communication, I’m using SPI:

  // wait for a card to enter the field (only possible with I2C)
  if (spi_dev == NULL) {

I read somewhere that ESP8266 won’t work with I2C therefore my reason to use SPI.

That’s bullshit. Forget that immediately, the ESP8266 works with I2C (I have that in several of my projects).

Poll the reader for events.

I keep on trying, I think, my NFC board might be broken, it communicates with ESP8266 but no NFC read. Result, when I enable PN532DEBUG:

Sending : 0x0, 0x0, 0xFF, 0x4, 0xFC, 0xD4, 0x4A, 0x1, 0x0, 0xE1, 0x0, 
Reading:  0x0 0x0 0xFF 0x3 0xFD 0xD5 0x4B 0x0 0xE0 0x0 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA

in the code:

bool Adafruit_PN532::waitready(uint16_t timeout) {
  uint16_t timer = 0;
  while (!isready()) {
    if (timeout != 0) {
      timer += 10;
      if (timer > timeout) {
#ifdef PN532DEBUG
        return false;
  return true;

Seams like timeout on waitready(uint16_t timeout){}

Looks like the problem is solved: I used PN532 library instead of Adafruit_PN532. Pulled the example from this library iso14443a_uid, adjusted my pin-out and worked like a charm using SPI interface.

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