Some of the more common questions on the forums related to the PN532 NFC/RFID Breakout and NFC Shield.
Can I have multiple shields on one Arduino?
Nope, the I2C library can have only one address per bus and the address is not adjustable! So one shield per Arduino please!
Can I read or write to Mifare tags with the PN532 and Adafruit Libraries?
Absolutely! The Adafruit libraries include functions to authenticate, read and write individual blocks to Mifare Classic cards. Before you can read or write a block you need to authenticate it with the appropriate key, and once the block is authenticated you can read and write to your hearts content)!

For example, the key functions in the I2C library (which was written to go along with the NFC shield since it defaults to I2C) are:
uint8_t mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t uidLen,
                                         uint32_t blockNumber, uint8_t keyNumber,
                                         uint8_t * keyData);
uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data);
uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data);
This is all you need to start reading and writing data, and you can verify the data using one of many Android applications that support working with Mifare cards (a search for NFC will turn up plenty).
What level of NDEF support is included in the libraries?
At the moment, all NDEF features are experimental and incomplete. Only very basic test code has been written to format a card for NDEF messages in a way that any NFC-enabled Android phone should be able to understand it, and it was written and an extremely simple proof of concept.

We would like to improve NDEF support for Mifare tags in the near future and some initial planning has gone into this, but at the moment our suggestion is to stick to plain text and 'vanilla' Mifare Classic reads and writes. You can read and write Mifare Classic and Mifare Ultralight blocks from Android, and you don't need to used the more complicated NDEF standard to simply pass data back and forth via a Mifare Classic or Ultralight card.
Note: Please use the limited NDEF code with care. Formatting cards for NDEF support is currently a one way operation, and should only be performed on cards you can dedicate to NDEF use.
Does the PN532 support peer to peer communication to talk with my smartphone?

Yes, the PN532 supports peer to peer communication, but the SW support for this isn't implemented in the Adafruit libraries.

Peer to peer communication with Android is possible, for example, but the actual implementation is quite complicated on the PN532 side. You need to go through a lot of SW layers to communicate with Android in a way that it understands -- it would require developing a full NDEF stack for the messages, SNEP and LLCP stacks, etc. -- which is unfortunately well beyond the scope of what we can offer on a development board at this price point.

All of the HW requirements for this are met with the Adafruit shield and breakout board, but the stack implementation is non trivial and would require us to charge a significant premium for these boards if we implemented this.

We've focused our energy on providing a reliable, proven, properly-tuned HW reference, and enough of a SW building block to get everyone started, but there are too many holes to fill in to cover everything NFC can do with a development board at this price point.

Does the PN532 support tag emulation?
Yes, but in reality it's impossible to implement since it requires an external 'secure element' that is very difficult to source (under export control and general NDA from the few manufacturers of them). If you can get one we'd love to see it, though!
Can the PN532 read Tag-It tags from TI?

No. The PN532 is designed to be used with ISO14443 tags, with Mifare Classic probably the most common general-purpose tag type in use.

Can I set a delay calling readPassiveTargetID()?
Note: This question only applies to the I2C Library. The SPI library doesn't handle the timing the same way.

readPassiveTargetID() intentionally waits around in a blocking delay until a card enters the magnetic field. The reason for this blocking delay is to ensure a well-understood command/response flow. Once the magnetic field is activated and a read request is sent via readPassiveTargetID, you can keep sending new commands to the PN532, but the moment a card or tag enters the field, the PN532 will send a response to the initial read request, even if it's in the middle of some other response or activity. To avoid having to debug this in SW, a blocking delay was implemented to keep the command/response pattern as clear as possible.

As a workaround to this blocking-delay limitation, setPassiveActivationRetries(maxRetries) was added to the latest NFC libraries to allow you to set a specific timeout after read requests.

By default, the PN532 will wait forever for a card to enter the field. By specifying a fixed number of retries via MxRtyPassiveActivation (see UM section 7.3.1 describing the RFConfiguration register, specifically CfgItem 5) the PN532 will abort the read request after specified number of attempts, and you can safely send new commands without worrying about mixing up response frames. To wait forever, set MxRtyPassiveActivation to 0xFF. To timeout after a fixed number of retries, set MxRtyPassiveActivation to anything less than 0xFF.

Example Sketch:
#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>

#define IRQ   (2)
#define RESET (3)  // Not connected by default on the NFC Shield

Adafruit_NFCShield_I2C nfc(IRQ, RESET);

void setup(void) {
  Serial.begin(115200);
  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (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);
  
  // 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.
  nfc.setPassiveActivationRetries(0xFF);
  
  // configure board to read RFID tags
  nfc.SAMConfig();
    
  Serial.println("Waiting for an ISO14443A card");
}

void loop(void) {
  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)
  
  // 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);
  
  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); 
    }
    Serial.println("");
    // Wait 1 second before continuing
    delay(1000);
  }
  else
  {
    // PN532 probably timed out waiting for a card
    Serial.println("Timed out waiting for a card");
  }
}
Hey wait ... isn't there something funny with the SVDD pin?
Indeed, good eye! Unfortunately, both v1.0 and v1.3 of the breakout boards have a problem on the schematic. SVDD is connected directly to VDD, but should be left floating since it is used to power secure modules. This has no effect on the functionality of the boards, but does cause some extra current to be drawn. It will be fixed on the next revision of the board, but if you require the use of the secure modules (rare), you can simply cut the trace to the left of C22, which is the cap connected to SVDD (just follow the trace straight up from pin 37).
Are there any special requirements to use the PN532 Breakout with the Due?
While the libraries do not officially support the Due yet, some customers have been able to get them working with some minor changes to the library.

We recommend using the I2C libraries with both the shield and the breakout boards since the I2C library represents the latest code from Adafruit, and the shield version should work without too much effort.

There is one caveat combining the breakout, I2C and the Due, though: The Due includes pullup resistors for I2C0 (SCL0 and SDA1), but there are no pullups resistors on SCL1 and SDA1. SCL1/SDA1 are the pins used as replacements for the Uno I2C pins (the pins used on standard shields), so you will need to add two 1.5K pullups on SCL1 and SDA1 to use the breakout board with I2C1 and the Due. Simply solder two 1.5K resistors, one from SCL1 to 3V3 and another from SDA1 to 3.3V, and then connect the board the same way you would with an Uno.

This issue only applies to the PN532 Breakout board since the PN532 shield includes I2C pullup resistors right on board.

This guide was first published on Dec 30, 2012. It was last updated on Mar 18, 2024.

This page (FAQ) was last updated on Mar 08, 2024.

Text editor powered by tinymce.