This firmware turns a Seeed Studio XIAO ESP32-S3 paired with a PN532 NFC Module (via I2C) into a BLE-managed NFC read/write bridge. It exposes a custom BLE GATT server that enables remote wireless clients (desktop, mobile, or script) to receive live tag notifications and queue diverse NDEF payloads for tag writing.
- Full NDEF Feature Support:
- Plain Text: Standard NDEF text records.
- Web URIs:
http://andhttps://web links. - iOS Shortcuts: Auto-launching iOS shortcuts via
shortcuts://. - GEO Location: Coordinates (
geo:lat,lon) for native mapping apps. - Wi-Fi Credentials: Network setup via
application/vnd.wfa.wscMIME records. - vCards: Full contact cards (
text/vcard). - Direct Actions: Phone calls (
tel:), SMS (sms:), FaceTime (facetime:), and email (mailto:). - Payment & Social Schemes: PayPal, Venmo, CashApp, and social profile URIs.
- Crypto Wallet Addresses: Native
bitcoin:andethereum:URI protocols. - Android Application Records (AAR): Auto-launch/install via
android.com:pkgexternal records.
- BLE GATT Interface: Live status notifications on tag read and dynamic write payload queuing over BLE.
- Active LOW Visual Feedback: Onboard LED blinks for BLE connections, write commands, and active tag operations.
| Seeed Studio XIAO ESP32-S3 | PN532 NFC Module (I2C Mode) |
|---|---|
| 3V3 | VCC |
| GND | GND |
| GPIO 5 (D4) | SDA |
| GPIO 6 (D5) | SCL |
| GPIO 2 (D1) | IRQ |
| GPIO 3 (D2) | RST / RESET |
Note: Ensure the DIP switches or jumpers on your PN532 module are set to I2C mode (usually
I2C: I0 = High, I1 = Low).
- Device Name:
XIAO-NFC-Bridge - Service UUID:
4fafc201-1fb5-459e-8fcc-c5c9c331914b
- Read Characteristic (Notify / Read):
beb5483e-36e1-4688-b7f5-ea07361b26a8- Emits a BLE notification containing the decoded payload string whenever an NFC tag is swiped.
- Write Characteristic (Write):
82910d19-21cb-40c2-901b-c743e498308d- Receives formatted string payloads from a BLE client. The payload is held in a write buffer until an NFC tag is placed on the reader.
When a string payload is written to the BLE Write Characteristic, writeNDEFPayload() inspects the prefix to construct the appropriate NDEF record type:
| Prefix / Format Pattern | TNF Category | NDEF Record Type / Scheme |
|---|---|---|
http://, https://, tel:, sms:, geo:, shortcuts://, facetime:, mailto:, bitcoin:, ethereum: |
TNF 0x01 (Well Known) | URI Record (U) |
BEGIN:VCARD... |
TNF 0x02 (MIME Media) | text/vcard |
WIFI:S:SSID;T:WPA;P:PASS;; |
TNF 0x02 (MIME Media) | application/vnd.wfa.wsc |
aar:package.name |
TNF 0x04 (External Type) | android.com:pkg |
| Any other raw text string | TNF 0x01 (Well Known) | Text Record (T) |
This project is configured for PlatformIO.
[env:seeed_xiao_esp32s3]
platform = espressif32
board = seeed_xiao_esp32s3
framework = arduino
monitor_speed = 115200
lib_deps =
adafruit/Adafruit PN532@^1.3.3
don/NDEF@^0.0.0
- Compile the Firmware:
pio run
- Upload to Board:
pio run --target upload
- Open Serial Monitor:
pio device monitor
- 2 Quick Blinks: BLE Client Connected.
- 3 Quick Blinks: BLE Write Payload Received & Queued.
- Continuous Slow Blink (1Hz): PN532 Initialization Error (Check Wire/DIP Switches).