You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python读取NTAG215文本数据?树莓派PN532读取异常排查

解决NTAG215读取不完整文本的问题

问题描述

使用搭载Waveshare PN532 NFC模块的树莓派,读取通过Google Play商店NFC Tools app写入NTAG215的hello_world文本数据时,运行Python脚本仅输出bytearray(b'nhel'),无法获取完整字符串。

用户原代码:

"""
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 RPi.GPIO as GPIO
import codecs
from pn532 import *


if __name__ == '__main__':
    try:
        pn532 = PN532_SPI(debug=False, reset=20, cs=4)
        #pn532 = PN532_I2C(debug=False, reset=20, req=16)
        #pn532 = PN532_UART(debug=False, reset=20)

        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=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])
             ntag2xx_block = pn532.ntag2xx_read_block(6)
            print(ntag2xx_block)
            
            for i in uid:
                print(hex(i))
    except Exception as e:
        print(e)
    finally:
        GPIO.cleanup()

问题原因

  1. 单块读取限制:NTAG215的每个数据块仅能存储4字节内容,你只读取了块6,自然只能拿到4个字符的片段。
  2. NDEF格式封装:NFC Tools写入的文本会遵循NDEF(NFC Data Exchange Format)标准,数据被封装在结构化的头部和多个连续块中,nhel是NDEF头部加上部分文本内容的原始字节,并非完整的文本 payload。

解决方案

需要读取连续的多个数据块,并解析NDEF格式以提取真实文本内容。

修改后的代码

"""
读取NTAG215的完整NDEF文本数据
"""
import RPi.GPIO as GPIO
from pn532 import *

def parse_ndef_text(data_blocks):
    # 合并所有读取到的块数据
    raw_data = b''.join(data_blocks)
    # 解析NDEF头部:TNF字段判断是否为文本类型
    tnf = raw_data[0] & 0x07
    if tnf != 0x01:
        return "非NDEF文本格式数据"
    
    type_len = raw_data[1]
    payload_len = raw_data[2]
    # 跳过NDEF头部和语言编码部分,提取纯文本
    lang_code_length = raw_data[3 + type_len]
    text_start = 3 + type_len + lang_code_length
    text_end = text_start + payload_len - lang_code_length
    return raw_data[text_start:text_end].decode('utf-8')

if __name__ == '__main__':
    try:
        pn532 = PN532_SPI(debug=False, reset=20, cs=4)
        ic, ver, rev, support = pn532.get_firmware_version()
        print(f'PN532固件版本: {ver}.{rev}')

        pn532.SAM_configuration()
        print('等待NFC卡片...')
        
        while True:
            uid = pn532.read_passive_target(timeout=5)
            print('.', end="")
            if uid is None:
                continue
            
            print(f'\n检测到卡片UID: {[hex(i) for i in uid]}')
            
            # 读取连续块:从块6开始,读取3个块(足够容纳hello_world)
            # 若写入更长文本,可增加读取的块数
            data_blocks = []
            for block_num in range(6, 9):
                block_data = pn532.ntag2xx_read_block(block_num)
                if block_data:
                    data_blocks.append(block_data)
            
            # 解析并打印完整文本
            full_text = parse_ndef_text(data_blocks)
            print(f'完整文本内容: {full_text}')
            
    except Exception as e:
        print(f'错误信息: {e}')
    finally:
        GPIO.cleanup()

关键说明

  • 多块读取:循环读取块6、7、8,确保覆盖hello_world所在的所有数据块,若写入更长文本,可扩展读取的块范围。
  • NDEF解析:parse_ndef_text函数跳过NDEF的结构头部(TNF、类型长度、负载长度、语言编码),直接提取并解码文本内容。
  • 兼容性:该代码针对NFC Tools写入的标准NDEF文本格式,若使用其他工具写入非标准格式,需调整解析逻辑。

内容的提问来源于stack exchange,提问作者snow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 09:45:33