请求协助实现PN532 NFC模块触发手机弹窗功能
手机贴近PN532触发带是/否弹窗的实现方案
核心逻辑
要让手机识别PN532并弹出带选项的窗口,得让PN532模拟NFC标签发送特定消息,同时手机端配合接收这个消息并展示交互弹窗。你当前的代码是被动读取NFC标签,需要修改为让PN532主动模拟标签,向手机发送触发信号。
第一步:修改PN532代码,实现主动模拟NFC标签
PN532支持模拟NDEF标签,以下是调整后的代码,可在检测到手机靠近时发送触发消息:
#include <Wire.h> #include <Adafruit_PN532.h> #define SDA_PIN 20 // micro:bit的SDA引脚 #define SCL_PIN 19 // micro:bit的SCL引脚 Adafruit_PN532 nfc(SDA_PIN, SCL_PIN); // 定义要发送的NDEF消息:替换为你的手机应用包名 uint8_t ndefMessage[] = { 0x03, // TLV长度 0x29, // 类型长度 0x17, // 有效负载长度(对应app://your.app.package的字符数) 'U', 'R', 'I', // 记录类型:URI 0x00, // URI前缀(无,直接使用完整路径) 'a', 'p', 'p', ':', '/', '/', 'c', 'o', 'm', '.', 'y', 'o', 'u', 'r', 'g', 'r', 'o', 'u', 'p', '.', 'n', 'f', 'c', 'a', 'p' // 替换为你的应用包名 }; void setup(void) { Serial.begin(115200); Serial.println("PN532 模拟NFC标签模式启动"); nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (!versiondata) { Serial.print("未检测到PN532模块"); while (1); } // 配置模块为主动模拟模式 nfc.SAMConfig(); nfc.setPassiveActivationRetries(0xFF); Serial.println("等待手机靠近..."); } void loop(void) { uint8_t success; uint8_t uid[] = {0, 0, 0, 0, 0, 0, 0}; uint8_t uidLength; // 检测手机(作为NFC读卡器)靠近 success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); if (success) { Serial.println("检测到手机,发送触发消息..."); // 模拟NDEF标签并发送消息 success = nfc.emulateNDEF(ndefMessage, sizeof(ndefMessage)); if (success) { Serial.println("消息发送成功"); } else { Serial.println("消息发送失败"); } delay(2000); // 防止短时间内重复触发 } }
第二步:手机端实现弹窗交互
系统自带的NFC触发无法直接弹出自定义是/否窗口,需要开发简单的手机应用:
Android平台
- 新建Android项目,在
AndroidManifest.xml中添加NFC权限和NDEF过滤规则,关联你在PN532代码中填写的应用包名。 - 编写Activity接收NFC触发的Intent,弹出带是/否选项的对话框:
import android.app.AlertDialog; import android.content.DialogInterface; import android.nfc.NfcAdapter; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; public class NFCActivity extends AppCompatActivity { private NfcAdapter nfcAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); nfcAdapter = NfcAdapter.getDefaultAdapter(this); // 处理启动时的NFC触发 handleNFCIntent(getIntent()); } @Override protected void onNewIntent(android.content.Intent intent) { super.onNewIntent(intent); handleNFCIntent(intent); } private void handleNFCIntent(android.content.Intent intent) { if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { showConfirmDialog(); } } private void showConfirmDialog() { new AlertDialog.Builder(this) .setTitle("确认操作") .setMessage("要执行这个操作吗?") .setPositiveButton("是", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 填写点击“是”后的逻辑,比如向Micro:bit发送反馈信号 } }) .setNegativeButton("否", null) .show(); } }
iOS平台
- 在Xcode中新建iOS项目,在
Info.plist中添加NFCReaderUsageDescription权限说明。 - 使用
NFCNDEFReaderSession监听NFC消息,检测到PN532的消息后弹出交互窗口:
import UIKit import CoreNFC class ViewController: UIViewController, NFCNDEFReaderSessionDelegate { var nfcSession: NFCNDEFReaderSession? override func viewDidLoad() { super.viewDidLoad() // 初始化NFC会话 nfcSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false) } func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) { DispatchQueue.main.async { let alert = UIAlertController(title: "确认操作", message: "要执行这个操作吗?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "是", style: .default, handler: { _ in // 填写点击“是”后的逻辑 })) alert.addAction(UIAlertAction(title: "否", style: .cancel)) self.present(alert, animated: true) } } func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) { // 处理NFC会话错误 } }
关键注意事项
- 确认你的PN532 V3(HW-147)固件支持NDEF模拟功能,该型号一般默认支持。
- 手机必须开启NFC功能,并授予对应应用NFC权限。
- 若不想开发完整应用,可让PN532发送网页链接,在网页内实现是/否弹窗,但体验不如原生应用流畅。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

