lora --- LoRa 调制解调器驱动

lora 模块为 Arduino Portenta Vision Shield 上的 Murata CMWX1ZZABZ LoRa 调制解调器提供了驱动。它公开了一个高级 Lora 类,该类封装了调制解调器固件(包括 Arduino MKRWAN ARD-078 固件)所使用的 AT 命令集,使应用程序能够加入 LoRaWAN 网络并发送/接收数据包。

示例:

import lora

modem = lora.Lora(band=lora.BAND_EU868, debug=True)
print("Device EUI:", modem.get_device_eui())
if modem.join_OTAA("0000000000000000", "00000000000000000000000000000000"):
    modem.send_data(b"hello", confirmed=True)

常量

激活模式

lora.MODE_ABP: int

个性化激活(ABP)模式。

lora.MODE_OTAA: int

空中激活(OTAA)模式。

RF 输出模式

lora.RF_MODE_RFO: int

使用调制解调器的 RFO(低功率)RF 输出。

lora.RF_MODE_PABOOST: int

使用调制解调器的 PA_BOOST(高功率)RF 输出。

频段

lora.BAND_AS923: int

AS923(亚洲 923 MHz)区域频段。

lora.BAND_AU915: int

AU915(澳大利亚 915 MHz)区域频段。

lora.BAND_EU868: int

EU868(欧洲 868 MHz)区域频段。

lora.BAND_KR920: int

KR920(韩国 920 MHz)区域频段。

lora.BAND_IN865: int

IN865(印度 865 MHz)区域频段。

lora.BAND_US915: int

US915(美国 915 MHz)区域频段。

lora.BAND_US915_HYBRID: int

US915 混合(子频段)区域规划。

设备类别

lora.CLASS_A: str

LoRaWAN 终端设备 Class A。

lora.CLASS_B: str

LoRaWAN 终端设备 Class B。

lora.CLASS_C: str

LoRaWAN 终端设备 Class C。

异常

exception lora.LoraError

调制解调器或驱动返回任何错误时引发的基类异常。

exception lora.LoraErrorTimeout

当调制解调器在配置的超时时间内未响应(接收缓冲区为空)时引发。

exception lora.LoraErrorParam

当 AT 命令带有无效参数而收到 +ERR_PARAM 响应时引发。

exception lora.LoraErrorBusy

当调制解调器正忙于处理上一条命令而收到 +ERR_BUSY 响应时引发。

exception lora.LoraErrorOverflow

当参数超出允许的最大长度而收到 +ERR_PARAM_OVERFLOW 响应时引发。

exception lora.LoraErrorNoNetwork

当调制解调器尚未加入网络而收到 +ERR_NO_NETWORK 响应时引发。

exception lora.LoraErrorRX

当接收下行链路时发生错误而收到 +ERR_RX 响应时引发。

exception lora.LoraErrorUnknown

当收到 +ERR_UNKNOWN 响应或调制解调器报告未记录的错误时引发。

class lora.Lora(uart: machine.UART | None = None, rst_pin: machine.Pin | None = None, boot_pin: machine.Pin | None = None, band: int = BAND_EU868, poll_ms: int = 300000, debug: bool = False)

构造一个新的调制解调器驱动。构造函数会初始化(或自动创建)UART 和复位/启动引脚,对模块进行硬件复位,执行自动波特率同步,重启模块,查询其固件版本,并配置所请求的区域 band

参数:
  • uart -- 用于与调制解调器通信的预配置 machine.UART 实例。如果为 None,驱动将以 8N2 帧格式打开 UART(8, 19200)(Portenta Vision Shield 默认值)。

  • rst_pin -- 驱动调制解调器复位线的 machine.Pin。如果为 None"PC6" 将配置为推挽输出。

  • boot_pin -- 驱动调制解调器启动选择线的 machine.Pin。如果为 None"PG7" 将配置为拉低的推挽输出。

  • band -- 要配置的区域频段。为 BAND_* 常量之一。

  • poll_ms -- 由 poll() 触发的自动空上行链路之间的间隔(以毫秒为单位),用于保持下行链路窗口打开。

  • debug -- 当为 True 时,所有 UART 流量都将通过 print() 打印。

LoraErrors: dict

从调制解调器错误响应字符串(例如 "+ERR_BUSY")到相应异常类的映射。由 handle_error() 内部使用。

init_modem() None

如果 self.uartself.rst_pinself.boot_pin 尚未设置,则将它们惰性初始化为 Portenta Vision Shield 默认值。由构造函数调用;通常不由用户代码调用。

debug_print(data: str) None

如果在构造时启用了 debug,则打印 data,否则不执行任何操作。

is_arduino_firmware() bool

如果调制解调器运行的是 Arduino MKRWAN ARD-078 固件(从缓存的 fw_version 字符串检测),则返回 True

configure_class(_class: str) None

配置 LoRaWAN 设备类别。

参数:

_class -- CLASS_ACLASS_BCLASS_C 之一。

configure_band(band: int) bool

配置区域频段,并在使用 BAND_EU868 的 Arduino 固件上启用 ETSI 占空比限制器。成功时返回 True

参数:

band -- BAND_* 常量之一。

set_baudrate(baudrate: int) None

更改调制解调器的 UART 波特率(AT+UART)。

参数:

baudrate -- 新的波特率,以比特每秒为单位。

set_autobaud(timeout: int = 10000) bool

发送空 AT 命令,直到调制解调器以 +OK 响应或经过 timeout 毫秒为止。如果同步成功,则返回 True

参数:

timeout -- 尝试的最长时间,以毫秒为单位。

get_fw_version() str

查询调制解调器设备字符串(AT+DEV?)和固件版本(AT+VER?),并将它们作为单个以空格分隔的字符串返回。

get_device_eui() str

以十六进制字符串形式返回调制解调器的 64 位 Device EUI。

factory_default() None

通过 AT+FACNEW 恢复出厂默认设置。

restart() None

重新同步波特率,重启调制解调器,重新读取固件版本,并重新应用所配置的区域频段。失败时引发 LoraError

set_rf_power(mode: int, power: int) None

配置调制解调器 RF 输出级(AT+RFPOWER)。

参数:
set_port(port: int) None

配置后续 send_data() 调用所使用的 LoRaWAN 应用端口(1..223)。

参数:

port -- LoRaWAN FPort。

set_public_network(enable: bool) None

启用或禁用公共网络同步字。

参数:

enable -- True 表示公共 LoRaWAN 同步字,False 表示私有同步字。

sleep(enable: bool) None

使调制解调器进入低功耗睡眠(True)或将其唤醒(False)。

format(hexMode: bool) None

选择 UART 上用于载荷字节的数据格式。

参数:

hexMode -- True 表示 ASCII 十六进制载荷格式,False 表示原始二进制。

set_datarate(dr: int) None

设置 LoRaWAN 数据速率索引(AT+DR)。

参数:

dr -- 区域特定的数据速率索引。

get_datarate() int

返回当前的 LoRaWAN 数据速率索引。

set_adr(adr: bool) None

启用或禁用自适应数据速率(ADR)。

参数:

adr -- True 启用 ADR,False 禁用它。

get_adr() int

返回当前的 ADR 设置(启用时为 1,否则为 0)。

get_devaddr() str

以十六进制字符串形式返回当前的 32 位 DevAddr。

get_nwk_skey() str

以十六进制字符串形式返回当前的网络会话密钥(Network Session Key)。

get_appskey() str

以十六进制字符串形式返回当前的应用会话密钥(Application Session Key)。

get_rx2dr() int

返回用于 RX2 接收窗口的数据速率索引。

set_rx2dr(dr: int) None

设置用于 RX2 接收窗口的数据速率索引。

参数:

dr -- 区域特定的数据速率索引。

get_ex2freq() int

返回用于 RX2 接收窗口的频率,以 Hz 为单位。

set_rx2freq(freq: int) None

设置用于 RX2 接收窗口的频率。

参数:

freq -- 频率,以 Hz 为单位。

set_fcu(fcu: int) None

设置上行链路帧计数器(AT+FCU)。

参数:

fcu -- 新的上行链路帧计数器值。

get_fcu() int

返回当前的上行链路帧计数器。

set_fcd(fcd: int) None

设置下行链路帧计数器(AT+FCD)。

参数:

fcd -- 新的下行链路帧计数器值。

get_fcd() int

返回当前的下行链路帧计数器。

change_mode(mode: int) None

切换激活模式。

参数:

mode -- MODE_ABPMODE_OTAA 之一。

join(timeout_ms: int) bool

发出 AT+JOIN 并等待入网接受事件。如果调制解调器在 timeout_ms 内报告 +EVENT=1,1(入网成功),则返回 True

参数:

timeout_ms -- 等待 +ACK 及随后的入网事件的最长时间,以毫秒为单位。

get_join_status() bool

如果调制解调器当前已加入网络,则返回 True

get_max_size() int

返回当前数据速率下的最大 LoRaWAN 载荷大小,以字节为单位。在 Arduino 固件上,此值固定为 64

poll() None

如果自上次调用以来已过去超过 poll_ms 毫秒,则发送一个空的确认上行链路以刷新待处理的下行链路。意在从应用程序的主循环中频繁调用。

send_data(buff: bytes, confirmed: bool = True) bool

发送一个 LoRaWAN 上行链路。如果 buff 大于 get_max_size(),则引发 LoraError

参数:
  • buff -- 要发送的载荷字节。

  • confirmed -- 当为 True 时,发送确认上行链路(+CTX)并等待网络服务器的 +ACK。当为 False 时,发送非确认上行链路(+UTX)。

返回:

如果调制解调器接受了该数据包(对于确认上行链路,且网络已确认它),则返回 True,否则返回 False

receive_data(timeout: int = 1000) dict | None

等待下行链路。如果在 timeout 毫秒内未收到 +RECV 事件,则返回 None,否则返回一个包含 FPort 和载荷字节的字典 {"port": str, "data": str}

参数:

timeout -- 等待的最长时间,以毫秒为单位。

receive(delimiter: str | list | None = None, max_bytes: int | None = None, timeout: int = 1000) str

底层 UART 读取。从调制解调器读取字符,直到匹配到分隔符、已读取 max_bytes 个字符或经过 timeout 毫秒为止,然后返回累积的字符串,其末尾的任何 \r 都被去除。

参数:
  • delimiter -- 可以是要在缓冲区末尾匹配的单个字符、要与整个修剪后缓冲区匹配的多字符字符串,或此类字符串的列表。

  • max_bytes -- 如果设置,则在恰好读取了这么多字节后立即返回。

  • timeout -- 整体读取超时,以毫秒为单位。

available() int

返回调制解调器的 UART 接收缓冲区中当前可用的字节数。

join_OTAA(appEui: str, appKey: str, devEui: str = None, timeout: int = 60000) bool

将调制解调器切换到 OTAA 模式,编程所提供的密钥和 EUI,然后尝试加入网络。如果入网成功,则返回 True

参数:
  • appEui -- 64 位应用/入网 EUI,以十六进制字符串表示。

  • appKey -- 128 位应用密钥(Application Key),以十六进制字符串表示。

  • devEui -- 可选的 64 位 Device EUI,以十六进制字符串表示。如果为 None,则使用出厂编程的 Device EUI。

  • timeout -- 入网超时,以毫秒为单位。

join_ABP(nwkId: int, devAddr: str, nwkSKey: str, appSKey: str, timeout: int = 60000) bool

将调制解调器切换到 ABP 模式,编程所提供的地址和密钥,然后尝试加入。返回 get_join_status() 的结果。

参数:
  • nwkId -- 网络标识符(当前被固件忽略)。

  • devAddr -- 32 位设备地址(Device Address),以十六进制字符串表示。

  • nwkSKey -- 128 位网络会话密钥(Network Session Key),以十六进制字符串表示。

  • appSKey -- 128 位应用会话密钥(Application Session Key),以十六进制字符串表示。

  • timeout -- 入网超时,以毫秒为单位。

handle_error(command: str, data: str) None

检查调制解调器响应,如果它表示错误,则引发匹配的 LoraError 子类。对于非错误响应不执行任何操作。

参数:
  • command -- 产生 data 的 AT 命令(不带 AT 前缀)。

  • data -- 调制解调器返回的响应字符串。

send_command(cmd: str, *args, delimiter: str = '\\r', data: bytes = None, timeout: int = 1000, raise_error: bool = True) str

cmdargs 构建一条 AT 命令,可选地追加原始 data 载荷,发送它,并返回调制解调器的响应。对于以 ? 结尾的查询命令,仅返回值部分(= 之后的子字符串)。

参数:
  • cmd -- AT 命令后缀(例如 "+JOIN""+DR=");"AT" 前缀和末尾的 \r 会自动添加。

  • args -- 经字符串转换后连接到 cmd 之后的附加参数。

  • delimiter -- 转发给 receive() 的分隔符。

  • data -- 在 AT 命令之后立即写入的可选原始字节(用于二进制上行链路载荷)。

  • timeout -- 响应超时,以毫秒为单位。

  • raise_error -- 当为 True 时,错误响应会被转换为 LoraError 异常;当为 False 时,原始响应会返回给调用者。