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.
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:
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.
req_pin = DigitalInOut(board.D12)
Initialise the I2C object:
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:
-
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 toresponse_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.
ic, ver, rev, support = pn532.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.
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.
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT """ 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=0.1) # pn532 = PN532_UART(uart, debug=False) ic, ver, rev, support = pn532.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])