ESP32-Wroom-32无法识别PN532 NFC模块的排查求助
ESP32-Wroom-32连接PN532 NFC模块无法识别的解决方法
问题描述
使用ESP32-Wroom-32连接PN532 NFC模块时,无论切换I2C/SPI通信方式、修改引脚配置或更换引脚,均输出Didn't find PN53x board,模块无法被识别。测试代码如下:
#include <Wire.h> #include <SPI.h> #include <Adafruit_PN532.h> // If using the breakout with SPI, define the pins for SPI communication. #define PN532_SCK (16) #define PN532_MOSI (25) #define PN532_SS (17) #define PN532_MISO (26) // Uncomment just _one_ line below depending on how your breakout or shield // is connected to the Arduino: // Use this line for a breakout with a software SPI connection (recommended): Adafruit_PN532 nfc(16, 26, 25, 17); // Use this line for a breakout with a hardware SPI connection. Note that // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin. //Adafruit_PN532 nfc(PN532_SS); // Or use this line for a breakout or shield with an I2C connection: //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET); // Or use hardware Serial: //Adafruit_PN532 nfc(PN532_RESET, &Serial1); void setup(void) { Serial.begin(115200); while (!Serial) delay(10); // for Leonardo/Micro/Zero Serial.println("Hello!"); nfc.begin(); delay(1000); 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); Serial.println("Waiting for an ISO14443A Card ..."); } void loop(void) { 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 //memcpy(data, (const uint8_t[]){ 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0 }, sizeof data); // 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!?"); } } } }
排查与解决步骤
1. 硬件连接检查
- 供电要求:PN532仅支持3.3V供电,严禁接5V。确保ESP32的3.3V引脚能提供足够电流(PN532峰值约100mA),若ESP32供电不足,可改用外部3.3V电源模块。
- 引脚对应:
- SPI模式:优先使用ESP32硬件SPI引脚,对应关系为
SCK→18、MOSI→23、MISO→19,SS引脚可自定义(如17),同时必须连接GND。 - I2C模式:使用ESP32默认I2C引脚
SDA→21、SCL→22,需额外连接PN532的RESET引脚(如接ESP32的4号引脚),IRQ引脚可选(推荐接2号引脚)。
- SPI模式:优先使用ESP32硬件SPI引脚,对应关系为
- 接线质量:检查所有杜邦线是否松动、引脚是否虚焊,重点确认GND连接可靠。
2. 代码配置修正
SPI模式推荐方案(硬件SPI)
使用ESP32硬件SPI稳定性优于软件SPI,修改代码如下:
#include <Wire.h> #include <SPI.h> #include <Adafruit_PN532.h> // 硬件SPI配置:SS引脚自定义为17 #define PN532_SS 17 // 初始化硬件SPI连接 Adafruit_PN532 nfc(PN532_SS); void setup(void) { Serial.begin(115200); while (!Serial) delay(10); Serial.println("Hello!"); // 初始化NFC模块,若失败直接提示 if (!nfc.begin()) { Serial.print("Didn't find PN53x board"); while (1); } uint32_t versiondata = nfc.getFirmwareVersion(); 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); Serial.println("Waiting for an ISO14443A Card ..."); } void loop(void) { uint8_t success; uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; uint8_t uidLength; success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); if (success) { 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) { Serial.println("Seems to be a Mifare Classic card (4 byte UID)"); uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 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]; success = nfc.mifareclassic_ReadDataBlock(4, data); if (success) { Serial.println("Reading Block 4:"); nfc.PrintHexChar(data, 16); Serial.println(""); delay(1000); } else { Serial.println("无法读取指定区块,请尝试其他密钥?"); } } else { Serial.println("认证失败,请尝试其他密钥?"); } } if (uidLength == 7) { Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)"); uint8_t data[32]; success = nfc.mifareultralight_ReadPage (4, data); if (success) { nfc.PrintHexChar(data, 4); Serial.println(""); delay(1000); } else { Serial.println("无法读取指定页面?"); } } } }
I2C模式配置方案
若使用I2C,修改代码初始化部分:
#define PN532_IRQ 2 #define PN532_RESET 4 // 初始化I2C连接 Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
3. 模块与兼容性测试
- 更换PN532模块,排除模块硬件损坏的可能。
- 使用Arduino Uno等其他开发板测试模块,确认模块本身可正常工作,排除ESP32兼容性问题。
内容的提问来源于stack exchange,提问作者Moritz Ende
相关产品推荐
相关产品推荐

