Raspberry Pi 4B 更换 nrf24 库后为何出现 SpiDev 类型错误?
结论
当前安装的 nrf24 库初始化时,把传入的 SpiDev 对象作为 ce 参数,与整数进行范围比较,导致了报错。
spidev.SpiDev() 返回 SPI 设备对象是正常的。将 from lib_nrf24 import NRF24 改成 from nrf24 import NRF24 后,原来的构造参数和后续方法不一定兼容,需要按新库的接口调整调用。
异常说明了什么?
原代码使用了这样的初始化方式:
radio = NRF24(GPIO, spidev.SpiDev())
异常发生在新库的构造函数内部:
assert 0 <= ce <= 31
错误信息是:
TypeError: '<=' not supported between instances of 'int' and 'SpiDev'
可以确定,执行范围检查时,ce 的值是一个 SpiDev 对象。该参数需要能够与整数进行范围比较的值,当前传入的却是设备对象。
异常发生在参数检查阶段。/dev/spidev0.0 和 /dev/spidev0.1 的存在说明系统已暴露 SPI 设备节点,但这不能消除 Python 参数类型错误,也不能证明无线模块接线正确或通信正常。
先确认实际安装的 NRF24 接口
在运行原程序的同一个 Python 环境中,执行下面的独立脚本:
import inspect
import sys
import nrf24
from nrf24 import NRF24
print("Python:", sys.executable)
print("Module:", nrf24.__file__)
print("Constructor:", inspect.signature(NRF24))
print(inspect.getsource(NRF24.__init__))
重点查看:
- 构造函数第一个参数要求什么对象,是否接受
RPi.GPIO模块。 ce的参数位置、默认值和引脚编号约定。- SPI 总线、设备号和片选如何配置,是否由库内部创建 SPI 对象。
错误堆栈已经指向当前环境中的 nrf24/nrf24.py。检查实际加载的代码,可以避免误用另一个同名库或不同版本的示例。
按同一个库的 API 调整程序
如果继续使用当前的 nrf24,需要根据它的构造函数签名重新初始化,并将 ce 设置为实际连接的 CE 引脚编号。如果接口支持关键字参数,显式写出 ce=... 可以减少位置参数混淆。
现有信息不足以确定完整的构造语句:题目没有提供完整签名,也没有确认第一个参数要求的 GPIO 后端。只把 spidev.SpiDev() 换成某个整数,可能会让程序进入下一步,但仍可能遇到其他接口错误。
还需要核对原程序中的这些调用:
radio.begin(0, 25)
radio.setPALevel(NRF24.PA_MIN)
radio.setDataRate(NRF24.BR_1MBPS)
radio.openWritingPipe(pipes[0])
radio.available(0)
确认新库是否提供这些方法和常量,以及相应的参数含义是否一致。可以先列出类中可见的公开成员:
from nrf24 import NRF24
print([name for name in dir(NRF24) if not name.startswith("_")])
也可以使用与原教程代码匹配的库及版本。选用前,应确认库的获取来源和运行环境兼容性。原问题没有提供足够依据判断 lib_nrf24 是否已经停止维护。
原代码还有哪些地方需要核对?
CE、CSN 和参数含义需要重新对应。原注释将 CE 标为 GPIO08、CSN 标为 GPIO25,但 radio.begin(0, 25) 中两个参数的具体含义须以所用库为准。SPI 设备号、GPIO 编号和排针物理编号不能混用,也不要猜测 ce 的值来绕过断言。
信道注释与数值不一致。原代码写的是:
radio.setChannel(0x76)
0x76 是十六进制,等于十进制的 118。如果目标是十进制信道 76,应在确认接口要求后使用 76,并确保通信双方配置一致。
粘贴的代码中循环体缺少缩进。例如,补齐消息长度的部分应具有下面的结构:
sendMessage = list("Hi, there!")
while len(sendMessage) < 32:
sendMessage.append(0)
题目中的程序实际已经运行到构造函数,说明实际运行的文件与粘贴内容可能存在缩进差异。检查后面的发送、等待和超时逻辑时,应以实际文件为准。另外,消息能否使用混合字符与整数的列表,也要核对新库的 write() 参数要求。
先理清构造函数参数与库接口的对应关系,再逐步检查 SPI 访问、接线和收发过程,以确定后续故障的位置。
备注:内容仅供参考。
