Python & CircuitPython

It's easy to use the PN532 breakout and shield with Python and CircuitPython, and the Adafruit CircuitPython PN532 module.  This module allows you to easily write Python code that reads and writes data from and to RFID/NFC tags.

You can use this breakout with any CircuitPython microcontroller board or with a computer that has GPIO and Python thanks to Adafruit_Blinka, our CircuitPython-for-Python compatibility library.

CircuitPython Microcontroller Wiring

First assemble a PN532 breakout or shield exactly as shown on the previous pages. 

Here's an example of wiring a Feather M0 to the breakout with I2C:

  • Board 3V to breakout 3.3V
  • Board GND to breakout GND
  • Board SCL to breakout SCL
  • Board SDA to breakout SDA
  • Board D6 to breakout RSTOUT_N

I2C requires external pull ups on SCL and SDA!

 

You must set the jumpers to enable I2C on your PN532! For I2C:

  • SEL0 = ON
  • SEL1 = OFF

Here's an example of wiring a Feather M0 to the breakout using SPI:

  • Board 3V to breakout 3.3V
  • Board GND to breakout GND
  • Board MISO to breakout MISO
  • Board MOSI to breakout MOSI
  • Board SCK to breakout SCK
  • Board D5 to breakout SSEL

 

You must set the jumpers to enable SPI on your PN532! For SPI:

  • SEL0 = OFF
  • SEL1 = ON

Here's an example of wiring a Feather M0 to the breakout using UART:

  • Board 3V to breakout 3.3V
  • Board GND to breakout GND
  • Board RX to breakout TX
  • Board TX to breakout RX

 

You must set the jumpers to enable UART on your PN532! For UART:

  • SEL0 = OFF
  • SEL1 = OFF

Here's an example of wiring a Metro M0 to the shield using I2C:

Assemble the shield as shown in the previous pages, and plug into your Metro M0.

 

You must set the jumpers to enable I2C on your PN532! For I2C:

  • SEL0 = ON
  • SEL1 = OFF

Python Computer Wiring

Since there's dozens of Linux computers/boards you can use we will show wiring for Raspberry Pi. For other platforms, please visit the guide for CircuitPython on Linux to see whether your platform is supported

This breakout is designed to work with I2C, SPI and UART, however I2C AND UART DO NOT WORK RELIABLY ON RASPBERRY PI. If you're using the PN532 with Raspberry Pi, use SPI!

Here's the Raspberry Pi wired with SPI:

  • Pi 3V to breakout 3.3V
  • Pi GND to breakout GND
  • Pi MOSI to breakout MOSI
  • Pi MISO to breakout MISO
  • Pi SCLK to breakout SCK
  • Pi D5 to breakout SSEL

 

You must set the jumpers to enable SPI on your PN532! For SPI:

  • SEL0 = OFF
  • SEL1 = ON

We don't recommand using I2C, but here's the Raspberry Pi wired with I2C:

  • Pi 3V to breakout 3.3V
  • Pi GND to breakout GND
  • Pi SCL to breakout SCL
  • Pi SDA to breakout SDA
  • Pi D6 to breakout RSTPD_N
  • Pi D12 to breakout P32

 

You must set the jumpers to enable I2C on your PN532! For I2C:

  • SEL0 = ON
  • SEL1 = OFF

We don't recommand using UART, but here's the Raspberry Pi wired with UART:

  • Pi 3V to breakout 3.3V
  • Pi GND to breakout GND
  • Pi RXD to breakout TX
  • Pi TXD to breakout RX

 

You must set the jumpers to enable UART on your PN532! For UART:

  • SEL0 = OFF
  • SEL1 = OFF

CircuitPython Installation of PN532 Library

Next you'll need to install the Adafruit CircuitPython PN532 library on your CircuitPython board.  

First make sure you are running the latest version of Adafruit CircuitPython for your board.

Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle.  Our introduction guide has a great page on how to install the library bundle for both express and non-express boards.

Remember for non-express boards like the, you'll need to manually install the necessary libraries from the bundle:

  • adafruit_pn532.mpy
  • adafruit_bus_device

Before continuing make sure your board's lib folder or root filesystem has the adafruit_pn532.mpy, and adafruit_bus_device files and folders copied over.

Next connect to the board's serial REPL so you are at the CircuitPython >>> prompt.

Python Installation of PN532 Library

You'll need to install the Adafruit_Blinka library that provides the CircuitPython support in Python. This may also require enabling I2C on your platform and verifying you are running Python 3. Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready!

Once that's done, from your command line run the following command:

  • sudo pip3 install adafruit-circuitpython-pn532

If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!

CircuitPython & Python Usage

To demonstrate the usage of the breakout we'll initialize it and read the ID from a tag using the board's Python REPL.

Run the following code to import the necessary modules and assign the reset pin to a digital pin on your board. We've used D6:

Download: file
import board
import busio
from digitalio import DigitalInOut
from adafruit_pn532.i2c import PN532_I2C
reset_pin = DigitalInOut(board.D6)

On Raspberry Pi, you must also connect a pin to P32 "H_Request" for hardware wakeup. This avoids I2C clock stretching.

Download: file
req_pin = DigitalInOut(board.D12)

Initialise the I2C object:

Download: file
i2c = busio.I2C(board.SCL, board.SDA)
pn532 = PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin)

Now we can start interacting with NFC/RFID tags using the following functions:

  • get_firmware_version - Get the latest firmware version.
  • SAM_configuration - configure the PN532 to read MiFare cards.
  • read_passive_target - Wait for a MiFare card to be available and return its UID when found.
  • call_function - Send specified command to the PN532 and expect up to response_length bytes back in a response.
  • mifare_classic_authenticate_block - Authenticate specified block number for a MiFare classic card.
  • mifare_classic_read_block - Read a block of data from the card.
  • mifare_classic_write_block - Write a block of data to the card.
  • ntag2xx_read_block - Read a block of data from the card.
  • ntag2xx_write_block - Write a block of data to the card.

First, we'll verify the PN532 is connected and check the firmware.

Download: file
ic, ver, rev, support = pn532.get_firmware_version()
print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))

Now we're going to configure the PN532 to read MiFare cards. Then we'll wait for a card to be available and print the UID.

First we check to see if a card is available. While we're waiting we'll print . to the serial output so we know it's still looking. If no card is found, we continue looking. When a card is found, we print the UID.

Download: file
pn532.SAM_configuration()
while True:
    uid = pn532.read_passive_target(timeout=0.5)
    print('.', end="", flush=True)
    if uid is None:
        continue
    print('Found card with UID:', [hex(i) for i in uid])

Touch a MiFare card to the breakout!

That's all there is to reading the UID from a card with CircuitPython and the PN532! For more information, check out the documentation.

Full Example Code

"""
This example shows connecting to the PN532 with I2C (requires clock
stretching support), SPI, or UART. SPI is best, it uses the most pins but
is the most reliable and universally supported.
After initialization, try waving various 13.56MHz RFID cards over it!
"""

import board
import busio
from digitalio import DigitalInOut
#
# NOTE: pick the import that matches the interface being used
#
from adafruit_pn532.i2c import PN532_I2C
#from adafruit_pn532.spi import PN532_SPI
#from adafruit_pn532.uart import PN532_UART

# I2C connection:
i2c = busio.I2C(board.SCL, board.SDA)

# Non-hardware
#pn532 = PN532_I2C(i2c, debug=False)

# With I2C, we recommend connecting RSTPD_N (reset) to a digital pin for manual
# harware reset
reset_pin = DigitalInOut(board.D6)
# On Raspberry Pi, you must also connect a pin to P32 "H_Request" for hardware
# wakeup! this means we don't need to do the I2C clock-stretch thing
req_pin = DigitalInOut(board.D12)
pn532 = PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin)

# SPI connection:
#spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
#cs_pin = DigitalInOut(board.D5)
#pn532 = PN532_SPI(spi, cs_pin, debug=False)

# UART connection
#uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100)
#pn532 = PN532_UART(uart, debug=False)

ic, ver, rev, support = pn532.get_firmware_version()
print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))

# Configure PN532 to communicate with MiFare cards
pn532.SAM_configuration()

print('Waiting for RFID/NFC card...')
while True:
    # Check if a card is available to read
    uid = pn532.read_passive_target(timeout=0.5)
    print('.', end="")
    # Try again if no card is available.
    if uid is None:
        continue
    print('Found card with UID:', [hex(i) for i in uid])
This guide was first published on Dec 30, 2012. It was last updated on Dec 30, 2012. This page (Python & CircuitPython) was last updated on May 23, 2019.