

本章节包含以下部分,请按需阅读:
参考下表进行连接
| Core2021-XF | ESP32S3 |
|---|---|
| CLK | 40 |
| MISO | 46 |
| MOSI | 45 |
| CS | 42 |
| DIO11 | 38 |
| RESET | 39 |
| BUSY | 41 |
core2021-xf\examples\esp32s3 目录中。| 示例程序 | 基础例程说明 | 依赖库 |
|---|---|---|
| 01_lr2021_tx | LR2021 发送 | RadioLib |
| 02_lr2021_rx | LR2021 接收 | RadioLib |
| 03_lr2021_pingpong | LR2021 PingPong | RadioLib |
| 04_lr2021_tx_cw | LR2021 以 CW 模式发送 | RadioLib |
| 05_lr2021_LoRaWAN | LoRaWAN | RadioLib |
core2021-xf\examples\esp32s3\arduino,选择需要测试的示例程序
【程序说明】
【代码分析】
SPI.begin(...):ESP32S3 硬件 SPI 引脚初始化,自定义 CLK/MOSI/MISOradio.irqDioNum = 11:配置 LR2021 模块中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证频率精度setFlag(void):中断回调函数,模块发送完成后自动触发,标记发送完成标志radio.setPacketSentAction(setFlag):绑定发送完成中断函数radio.startTransmit("内容"):启动 LoRa 异步发送,支持字符串 / 字节数组radio.finishTransmit():发送完成后收尾操作,关闭发射电路、复位模块状态loop() 主逻辑:检测发送完成标志 → 打印状态 → 延时 → 发送下一包带序号的数据【运行效果】
程序编译下载完成,打开串口监控可以看到打印发送完成的日志,如下图所示(搭配02_lr2021_rx):

【程序说明】
【代码分析】
SPI.begin(...):ESP32S3 硬件 SPI 初始化,自定义 CLK/MOSI/MISO 引脚radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证频率精度,提升接收稳定性setFlag(void):中断回调函数,模块接收到完整数据包后自动触发radio.setPacketReceivedAction(setFlag):绑定接收完成中断服务函数radio.startReceive():启动 LoRa 连续接收模式,进入等待数据状态radio.readData(str):读取接收到的无线数据,支持字符串格式解析radio.getRSSI() / radio.getSNR():获取信号质量参数,用于调试与链路评估loop() 主逻辑:检测接收完成标志 → 读取数据 → 解析打印 → 继续监听【运行效果】
程序编译下载完成,打开串口监控可以看到实时接收日志,包含数据内容、RSSI、SNR 信息,如下图所示(搭配01_lr2021_tx):

【程序说明】
INITIATING_NODE 为发起端,另一块为接收端【代码分析】
SPI.begin(...):ESP32S3 硬件 SPI 初始化,自定义 CLK/MOSI/MISO 引脚radio.irqDioNum = 11:配置 LR2021 中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证通信频率精度setFlag(void):通用中断回调,发送完成或接收完成都会触发radio.setIrqAction(setFlag):绑定收发共用中断函数INITIATING_NODE 宏定义:用于区分主动发起节点radio.startTransmit():启动数据包发送radio.startReceive():切换模块到监听接收状态radio.readData(str):读取接收到的 LoRa 数据包loop() 主逻辑:发送完成 → 进入接收;接收完成 → 延时回复 → 再次发送【运行效果】
INITIATING_NODE 宏定义
【程序说明】
【代码分析】
SPI.begin(...):ESP32S3 硬件 SPI 初始化,自定义 CLK/MOSI/MISO 引脚radio.XTAL = true:开启外部晶振,保证载波频率精度OUT_HZ 868000000UL:定义直接发射频率(868MHz),可自行修改radio.setOutputPower(22):配置发射功率为 22dBmradio.transmitDirect(OUT_HZ):进入连续直接发射模式,输出固定频率载波loop():无业务逻辑,载波持续发射无需程序干预【运行效果】
程序烧录后模块立即输出固定频率载波信号
串口打印初始化与发射启动状态,可使用频谱仪/接收模块检测到连续射频信号,如下图所示:

【程序说明】
【代码分析】
SPI.begin(...):ESP32S3 硬件 SPI 初始化,自定义 CLK/MOSI/MISO 引脚radio.irqDioNum = 11:配置 LR2021 中断映射,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证 LoRaWAN 频点精度prefs.begin(...):初始化 ESP32 NVS 分区,用于保存 LoRaWAN 会话restoreLoRaWANState():从 NVS 恢复会话信息,实现快速重连node.beginOTAA() / node.activateOTAA():OTAA 入网相关函数saveLoRaWANState():成功入网后保存会话信息到 NVSnode.sendReceive():发送上行数据,并自动监听服务器下行printHex / printAscii:格式化打印接收数据【运行效果】
烧录后自动完成 OTAA 接入,周期性上报数据并监听下行
串口实时打印入网状态、上下行消息、信号质量等信息,如下图所示:

【程序说明】
EspHal.h,完美适配 ESP-IDF 环境ESP_LOG 输出,稳定可靠【核心文件】
EspHal.h:ESP-IDF 硬件抽象层,提供 GPIO、SPI、延时、中断等底层实现(所有例程通用)main.cpp:LoRa 发送主程序【代码分析】
EspHal* hal = new EspHal(...):ESP-IDF 硬件抽象层初始化radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚radio.XTAL = true:开启外部晶振,保证频率精度setFlag(void):发送完成中断回调函数radio.setPacketSentAction(setFlag):绑定发送完成中断radio.startTransmit(...):启动异步 LoRa 发送radio.finishTransmit():发送完成后关闭射频电路,确保低功耗稳定【运行效果】

【程序说明】
EspHal.h,完美适配 ESP-IDF 环境【核心文件】
EspHal.h:底层硬件抽象(所有例程通用)main.cpp:LoRa 接收主程序【代码分析】
EspHal* hal:ESP-IDF 硬件抽象初始化(GPIO/SPI/中断)radio.irqDioNum = 11:配置 LR2021 中断映射radio.XTAL = true:开启外部晶振,保证接收频率精度setFlag(void):接收完成中断回调radio.setPacketReceivedAction(setFlag):绑定接收完成中断radio.startReceive():启动 LoRa 连续监听radio.readData():读取数据包并解析【运行效果】

【程序说明】
EspHal.h,完美适配 ESP-IDF 环境【核心文件】
EspHal.h:底层硬件抽象(所有 ESP-IDF 例程通用)main.cpp:LoRa 乒乓双向收发应用程序【代码分析】
EspHal* hal:ESP-IDF 硬件抽象层实例初始化,封装 SPI、GPIO、延时与中断radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚radio.XTAL = true:启用外部晶振,保障 LoRa 频点精度setFlag(void):收发事件共用中断回调函数radio.setIrqAction(setFlag):绑定模块中断触发回调INITIATING_NODE:宏开关,定义设备为主动发包节点radio.startTransmit() / radio.startReceive():程序自动切换发送与监听模式radio.readData():解析接收数据包并打印文本、信号参数【运行效果】

【程序说明】
EspHal.h,完美适配 ESP-IDF 环境【核心文件】
EspHal.h:底层硬件抽象(所有 ESP-IDF 例程通用)04_lr2021_direct_transmit.c:LoRa 载波发射主程序【代码分析】
EspHal* hal:ESP-IDF 硬件抽象初始化(SPI、GPIO、延时、中断)radio.irqDioNum = 11:配置 LR2021 中断映射引脚radio.XTAL = true:开启外部晶振,保证载波频率精度OUT_HZ 868000000UL:定义连续发射频率(868MHz)radio.setOutputPower(22):设置发射功率为 22dBmradio.transmitDirect(OUT_HZ):进入直接载波发射模式,启动持续发射【运行效果】

【程序说明】
EspHal.h,纯 ESP-IDF 环境独立运行【核心文件】
EspHal.h:底层硬件抽象(所有 ESP-IDF 例程通用)05_lr2021_lorawan_otaa.c:LoRaWAN OTAA 通信主程序【代码分析】
EspHal* hal:ESP-IDF 硬件抽象初始化(SPI、GPIO、延时、中断)radio.irqDioNum = 11:配置 LR2021 中断映射引脚radio.XTAL = true:开启外部晶振,保证 LoRa 频点精度nvs_flash_init():启用 NVS 存储,用于保存 LoRaWAN 会话restoreLoRaWANState():从闪存恢复会话,支持快速重连node.beginOTAA() / node.activateOTAA():OTAA 入网关键函数node.sendReceive():发送上行数据并监听服务器下行printHex / printAscii:格式化打印下行数据【运行效果】

本章节包含以下部分,请按需阅读:
参考下表进行连接
| Core2021-XF | Raspberry Pi Pico/Pico2 |
|---|---|
| CLK | 10 |
| MISO | 11 |
| MOSI | 12 |
| CS | 13 |
| DIO11 | 15 |
| RESET | 5 |
| BUSY | 14 |
core2021-xf\examples\pico 目录中。| 示例程序 | 基础例程说明 | 依赖库 |
|---|---|---|
| 01_lr2021_tx | LR2021 发送 | RadioLib |
| 02_lr2021_rx | LR2021 接收 | RadioLib |
| 03_lr2021_pingpong | LR2021 PingPong | RadioLib |
| 04_lr2021_tx_cw | LR2021 以 CW 模式发送 | RadioLib |
| 05_lr2021_LoRaWAN | LoRaWAN | RadioLib |
进入到 core2021-xf\examples\pico\arduino,选择需要测试的示例程序
选择好芯片型号跟端口

上传完成后,打开串口监测器,就会输出相关的信息
【程序说明】
【代码分析】
SPI1.setSCK / setRX / setTX:RP2040 硬件 SPI1 引脚重新映射SPI1.begin():启动树莓派 Pico 硬件 SPI1radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证频率精度setFlag(void):中断回调函数,模块发送完成后自动触发,标记发送完成标志radio.setPacketSentAction(setFlag):绑定发送完成中断函数radio.startTransmit("内容"):启动 LoRa 异步发送,支持字符串 / 字节数组radio.finishTransmit():发送完成后收尾操作,关闭发射电路、复位模块状态loop() 主逻辑:检测发送完成标志 → 打印状态 → 延时 → 发送下一包带序号的数据【运行效果】
程序编译下载完成,打开串口监控可以看到打印发送完成的日志,如下图所示(搭配02_lr2021_rx):

【程序说明】
【代码分析】
SPI1.setSCK / setRX / setTX:RP2040 硬件 SPI1 引脚重新映射配置SPI1.begin():初始化树莓派 Pico 硬件 SPI1 总线radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证频率精度,提升接收稳定性setFlag(void):中断回调函数,模块接收到完整数据包后自动触发radio.setPacketReceivedAction(setFlag):绑定接收完成中断服务函数radio.startReceive():启动 LoRa 连续接收模式,进入等待数据状态radio.readData(str):读取接收到的无线数据,支持字符串格式解析radio.getRSSI() / radio.getSNR():获取信号质量参数,用于调试与链路评估loop() 主逻辑:检测接收完成标志 → 读取数据 → 解析打印 → 继续监听【运行效果】
程序编译下载完成,打开串口监控可以看到实时接收日志,包含数据内容、RSSI、SNR 信息,如下图所示(搭配01_lr2021_tx):

【程序说明】
INITIATING_NODE 为发起端,另一块为接收端【代码分析】
SPI1.setSCK / setRX / setTX:树莓派 Pico SPI1 引脚重映射SPI1.begin():初始化硬件 SPI1 总线radio.irqDioNum = 11:配置 LR2021 中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证通信频率精度setFlag(void):通用中断回调,发送完成或接收完成都会触发radio.setIrqAction(setFlag):绑定收发共用中断函数INITIATING_NODE 宏定义:用于区分主动发起节点radio.startTransmit():启动数据包发送radio.startReceive():切换模块到监听接收状态radio.readData(str):读取接收到的 LoRa 数据包loop() 主逻辑:发送完成 → 进入接收;接收完成 → 延时回复 → 再次发送【运行效果】
INITIATING_NODE 宏定义
【程序说明】
【代码分析】
SPI1.setSCK / setRX / setTX:树莓派 Pico SPI1 引脚重映射配置SPI1.begin():初始化硬件 SPI1 总线radio.XTAL = true:开启外部晶振,保证载波频率精度OUT_HZ 868000000UL:定义直接发射频率(868MHz),可自行修改radio.setOutputPower(22):配置发射功率为 22dBmradio.transmitDirect(OUT_HZ):进入连续直接发射模式,输出固定频率载波loop():无业务逻辑,载波持续发射无需程序干预【运行效果】
程序烧录后模块立即输出固定频率载波信号
串口打印初始化与发射启动状态,可使用频谱仪/接收模块检测到连续射频信号,如下图所示:

【程序说明】
【代码分析】
SPI1.setSCK/setRX/setTX:RP2040 硬件 SPI1 引脚重映射配置SPI1.begin():初始化树莓派 Pico 硬件 SPI1 总线radio.irqDioNum = 11:配置 LR2021 中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证 LoRaWAN 频点精度EEPROM.begin(256):初始化 RP2040 片上 Flash 模拟 EEPROMrestoreLoRaWANState():从 EEPROM 恢复会话信息,实现快速重连node.beginOTAA()/activateOTAA():OTAA 入网相关关键函数saveLoRaWANState():入网成功后保存会话信息到 EEPROMnode.sendReceive():发送上行数据并自动监听下行printHex/printAscii:格式化打印下行数据【运行效果】
烧录程序后自动完成 OTAA 接入,周期性上报数据并接收下行
串口实时打印入网状态、上下行数据、信号质量等信息,如下图所示:

进入到 core2021-xf\examples\pico\c,选择需要测试的示例程序
选择好芯片型号跟端口

上传完成后,打开串口监测器,就会输出相关的信息
【程序说明】
【代码分析】
PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK):创建 Pico 硬件抽象层实例并绑定 SPILR2021 radio = new Module(hal, RFM_NSS, RFM_IRQ, RFM_RST, RFM_BUSY):初始化 LR2021 模块对象radio.irqDioNum = 11:配置中断映射引脚radio.XTAL = true:开启外部晶振,提高频率精度radio.begin():初始化模块,返回错误码radio.setPacketSentAction(setFlag):绑定发送完成回调函数 setFlag()radio.setFrequency(868.0)、setOutputPower(22)、setBandwidth(125.0)、setSpreadingFactor(7)、setCodingRate(5)、setSyncWord(...)、setPreambleLength(8):配置 LoRa 参数radio.startTransmit("Hello World!"):启动第一次数据包发送setFlag():发送完成后设置 transmittedFlag = true,用于主循环检测for(;;):transmittedFlagradio.finishTransmit() 做发送收尾操作【运行效果】
程序启动后在串口打印初始化状态(搭配02_lr2021_rx):

【程序说明】
【代码分析】
PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK):创建 Pico 硬件抽象层实例并绑定 SPILR2021 radio = new Module(hal, RFM_NSS, RFM_IRQ, RFM_RST, RFM_BUSY):初始化 LR2021 模块对象radio.irqDioNum = 11:配置中断映射引脚radio.XTAL = true:开启外部晶振,提高频率精度radio.begin():初始化模块,返回错误码radio.setPacketSentAction(setFlag):绑定发送完成回调函数 setFlag()radio.setFrequency(868.0)、setOutputPower(22)、setBandwidth(125.0)、setSpreadingFactor(7)、setCodingRate(5)、setSyncWord(...)、setPreambleLength(8):配置 LoRa 参数radio.startReceive():启动接收模式,进入监听状态setFlag():接收完成后设置 receivedFlag = true,用于主循环检测for(;;):receivedFlagradio.getPacketLength() 并调用 radio.readData(rxBuf, len)radio.startReceive()【运行效果】
程序启动后在串口打印初始化状态:(搭配01_lr2021_tx):

【程序说明】
#define INITIATING_NODE 宏控制,另一块模块自动进入接收模式【代码分析】
PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK):创建 Pico 硬件抽象层实例并绑定 SPILR2021 radio = new Module(hal, RFM_NSS, RFM_IRQ, RFM_RST, RFM_BUSY):初始化 LR2021 模块对象radio.irqDioNum = 11:配置中断映射引脚radio.XTAL = true:开启外部晶振,提高频率精度radio.begin():初始化模块,返回错误码radio.setPacketSentAction(setFlag):绑定发送 / 接收完成回调函数INITIATING_NODE 决定当前节点是否先发送数据for(;;):operationDone 标志radio.startReceive()radio.readData(rxBuffer, rxLen)【运行效果】
INITIATING_NODE
【程序说明】
【代码分析】
PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK):创建 Pico 硬件抽象层实例并绑定 SPILR2021 radio = new Module(hal, RFM_NSS, RFM_IRQ, RFM_RST, RFM_BUSY):初始化 LR2021 模块对象radio.irqDioNum = 11:配置中断映射引脚radio.XTAL = true:开启外部晶振,提高频率精度radio.begin():初始化模块,返回错误码radio.setOutputPower(22):设置发射功率为 22 dBmradio.transmitDirect(OUT_HZ):进入 连续直接发射模式,输出固定频率载波【运行效果】
程序烧录后模块立即输出固定频率载波信号
串口打印初始化与发射启动状态,可使用频谱仪/接收模块检测到连续射频信号,如下图所示:

【程序说明】
【代码分析】
PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK):创建 Pico 硬件抽象层实例并绑定 SPILR2021 radio = new Module(hal, RFM_NSS, RFM_IRQ, RFM_RST, RFM_BUSY):初始化 LR2021 模块对象LoRaWANNode node(&radio, &Region, subBand):创建 LoRaWAN 节点实例FLASH_TARGET_OFFSET:存储偏移FLASH_EMULATE_EEPROM_SIZE:仿真容量saveLoRaWANState() / restoreLoRaWANState():保存 / 恢复 LoRaWAN 会话状态node.beginOTAA(joinEUI, devEUI, nwkKey, appKey):初始化 OTAA 参数joinLoRaWAN(restored):尝试入网并保存 DevNonce / Sessionnode.sendReceive(tx, sizeof(tx), 1, rx, &rxLen):发送上行数据并接收下行uplinkIntervalSeconds 秒后下一次发送【运行效果】
烧录程序后自动完成 OTAA 接入,周期性上报数据并接收下行
串口实时打印入网状态、上下行数据、信号质量等信息,如下图所示:

本章节包含以下部分,请按需阅读:
| 图片 | 说明 |
|---|---|
| Arduino UNO R3 |
| Arduino UNO R4 |
| Arduino UNO R4 WIFI |
参考下表进行连接
| Core2021-XF | Arduino UNO |
|---|---|
| CLK | 13 |
| MISO | 12 |
| MOSI | 11 |
| CS | 10 |
| DIO11 | 2 |
| RESET | 3 |
| BUSY | 9 |
core2021-xf\examples\arduino 目录中。| 示例程序 | 基础例程说明 | 依赖库 |
|---|---|---|
| 01_lr2021_tx | LR2021 发送 | RadioLib |
| 02_lr2021_rx | LR2021 接收 | RadioLib |
| 03_lr2021_pingpong | LR2021 PingPong | RadioLib |
| 04_lr2021_tx_cw | LR2021 以 CW 模式发送 | RadioLib |
| 05_lr2021_LoRaWAN | LoRaWAN(Arduino R3 无法使用) | RadioLib |
选择开发板:
| 图片 | 说明 |
|---|---|
| Arduino UNO R3 |
| Arduino UNO R4 |
选择开发板的端口,然后进行编译上传
上传完成后,打开串口监测器,就会输出相关的信息。
【程序说明】
【代码分析】
radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证频率精度setFlag(void):中断回调函数,模块发送完成后自动触发,标记发送完成标志radio.setPacketSentAction(setFlag):绑定发送完成中断函数radio.startTransmit("内容"):启动 LoRa 异步发送,支持字符串 / 字节数组radio.finishTransmit():发送完成后收尾操作,关闭发射电路、复位模块状态loop() 主逻辑:检测发送完成标志 → 打印状态 → 延时 → 发送下一包带序号的数据【运行效果】
程序编译下载完成,打开串口监控可以看到打印发送完成的日志,如下图所示(搭配02_lr2021_rx):

【程序说明】
【代码分析】
radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证频率精度,提升接收稳定性setFlag(void):中断回调函数,模块接收到完整数据包后自动触发,标记接收完成标志radio.setPacketReceivedAction(setFlag):绑定接收完成中断服务函数radio.startReceive():启动 LoRa 连续接收模式,进入等待数据状态radio.readData(str):读取接收到的无线数据,支持字符串格式解析radio.getRSSI() / radio.getSNR():获取信号质量参数,用于调试与链路评估loop() 主逻辑:检测接收完成标志 → 读取数据 → 解析打印 → 继续监听【运行效果】
程序编译下载完成,打开串口监控可以看到实时接收日志,包含数据内容、RSSI、SNR 信息,如下图所示(搭配01_lr2021_tx):

【程序说明】
INITIATING_NODE 为发起端,另一块为接收端【代码分析】
radio.irqDioNum = 11:配置 LR2021 中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证通信频率精度setFlag(void):通用中断回调,发送完成或接收完成都会触发radio.setIrqAction(setFlag):绑定收发共用中断函数INITIATING_NODE 宏定义:用于区分主动发起节点radio.startTransmit():启动数据包发送radio.startReceive():切换模块到监听接收状态radio.readData(str):读取接收到的 LoRa 数据包loop() 主逻辑:发送完成 → 进入接收;接收完成 → 延时回复 → 再次发送【运行效果】
INITIATING_NODE 宏定义
【程序说明】
【代码分析】
radio.XTAL = true:开启外部晶振,保证载波频率精度OUT_HZ 868000000UL:定义直接发射频率(868MHz),可自行修改radio.setOutputPower(22):配置发射功率为 22dBmradio.transmitDirect(OUT_HZ):进入连续直接发射模式,输出固定频率载波loop():无业务逻辑,载波持续发射无需程序干预【运行效果】
程序烧录后模块立即输出固定频率载波信号
串口打印初始化与发射启动状态,可使用频谱仪/接收模块检测到连续射频信号,如下图所示:

【程序说明】
【代码分析】
radio.irqDioNum = 11:配置 LR2021 中断映射引脚,必须在初始化前设置radio.XTAL = true:开启外部晶振,保证 LoRaWAN 频率精度EEPROM.begin():初始化片上 EEPROM,用于保存 LoRaWAN 会话信息restoreLoRaWANState():从 EEPROM 恢复入网会话与随机值,实现快速重连node.beginOTAA():初始化 OTAA 入网参数(JoinEUI、DevEUI、AppKey、NwkKey)node.activateOTAA():发起 OTAA 加入服务器请求saveLoRaWANState():入网成功后保存会话信息到 EEPROMnode.sendReceive():发送上行数据,并自动开启接收窗口监听下行消息printHex / printAscii:打印下行数据的十六进制与 ASCII 格式【运行效果】
环境搭建参考 LoRaWAN 环境搭建文档
程序烧录后自动进行 OTAA 入网,入网成功后定时上传数据
串口打印入网状态、上下行消息、RSSI、SNR 等信息,如下图所示:

本章节包含以下部分,请按需阅读:
sudo apt install cmake -y
sudo apt install -y liblgpio-dev
cd ~
#国内用gitee下载
git clone https://gitee.com/waveshare/core2021-xf.git
#国外用github下载
git clone https://github.com/waveshareteam/core2021-xf.git
cd core2021-xf/examples/raspberrypi
sudo raspi-config nonint do_spi 0参考下表进行连接
| Core2021-XF | Raspberry Pi (BCM) |
|---|---|
| CLK | 11 |
| MISO | 9 |
| MOSI | 10 |
| CS | 25 |
| DIO11 | 17 |
| RESET | 22 |
| BUSY | 24 |
core2021-xf/examples/raspberrypi 目录中。| 示例程序 | 基础例程说明 | 依赖库 |
|---|---|---|
| 01_lr2021_tx | LR2021 发送 | RadioLib |
| 02_lr2021_rx | LR2021 接收 | RadioLib |
| 03_lr2021_pingpong | LR2021 PingPong | RadioLib |
| 04_lr2021_tx_cw | LR2021 以 CW 模式发送 | RadioLib |
| 05_lr2021_LoRaWAN | LoRaWAN | RadioLib |
【程序说明】
【脚本说明】
build.sh:工程编译脚本,自动创建构建目录、生成 Makefile、编译项目,输出可执行文件clean.sh:工程清理脚本,快速删除编译生成的文件,还原工程目录【代码分析】
PiHal* hal = new PiHal(0, SPI_FREQ_HZ):树莓派硬件初始化,配置 SPI 总线与时钟radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚radio.XTAL = true:开启外部晶振,保证通信频率精度setFlag(void):中断回调函数,发送完成后自动标记状态radio.setPacketSentAction(setFlag):绑定发送完成中断radio.startTransmit():启动 LoRa 数据包异步发送radio.finishTransmit():发送完成后关闭射频电路,确保稳定低功耗【程序使用】
lr2021_tx目录,执行编译运行:cd ~/core2021-xf/examples/raspberrypi/lr2021_tx
chmod +x *
./build.sh
./build/01_lr2021_tx
【运行效果】

【程序说明】
【脚本说明】
build.sh:工程编译脚本,自动创建构建目录、生成 Makefile、编译项目,输出可执行文件clean.sh:工程清理脚本,快速删除编译生成的文件,还原工程目录【代码分析】
PiHal* hal = new PiHal(0, SPI_FREQ_HZ):树莓派硬件初始化,配置 SPI 总线与时钟radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚radio.XTAL = true:开启外部晶振,保证通信频率精度setFlag(void):中断回调函数,接收完成后自动标记状态radio.setPacketReceivedAction(setFlag):绑定接收完成中断radio.startReceive():启动 LoRa 异步监听模式radio.readData():读取接收到的数据包,支持 HEX 与字符串解析radio.getRSSI() / radio.getSNR():获取信号质量参数【程序使用】
lr2021_rx目录,执行编译运行:cd ~/core2021-xf/examples/raspberrypi/lr2021_rx
chmod +x *
./build.sh
./build/02_lr2021_rx
【运行效果】

【程序说明】
【脚本说明】
build.sh:工程编译脚本,自动创建构建目录、生成 Makefile、编译项目,输出可执行文件clean.sh:工程清理脚本,快速删除编译生成的文件,还原工程目录【代码分析】
PiHal* hal = new PiHal(0, SPI_FREQ_HZ):树莓派硬件初始化,配置 SPI 总线与时钟radio.irqDioNum = 11:配置 LR2021 模块中断映射引脚radio.XTAL = true:开启外部晶振,保证通信频率精度setFlag(void):通用中断回调,发送/接收完成都会触发INITIATING_NODE:宏定义,用于区分主动发起节点radio.startTransmit():启动数据包发送radio.startReceive():切换模块到监听状态radio.readData():读取接收的 LoRa 数据包并解析【程序使用】
lr2021_pingpong目录,执行编译运行:cd ~/core2021-xf/examples/raspberrypi/lr2021_pingpong
chmod +x *
./build.sh
./build/03_lr2021_pingpong
【运行效果】

【程序说明】
【脚本说明】
build.sh:工程编译脚本,自动创建构建目录、生成 Makefile、编译项目,输出可执行文件clean.sh:工程清理脚本,快速删除编译生成的文件,还原工程目录【代码分析】
PiHal* hal = new PiHal(0, SPI_FREQ_HZ):树莓派硬件初始化,配置 SPI 总线与时钟radio.XTAL = true:开启外部晶振,保证载波频率精度OUT_HZ 868000000UL:定义连续发射频率(868MHz)radio.setOutputPower(22):配置发射功率为 22dBmradio.transmitDirect(OUT_HZ):进入直接连续发射模式,输出固定频率载波【程序使用】
04_lr2021_tx_cw目录,执行编译运行:cd ~/core2021-xf/examples/raspberrypi/04_lr2021_tx_cw
chmod +x *
./build.sh
./build/04_lr2021_tx_cw
【运行效果】

【程序说明】
lorawan_state.bin 持久化保存会话信息,掉电重启可快速恢复,无需重复入网【脚本说明】
build.sh:工程编译脚本,自动创建构建目录、生成 Makefile、编译项目,输出可执行文件clean.sh:工程清理脚本,快速删除编译生成的文件,还原工程目录【代码分析】
PiHal* hal = new PiHal(0, SPI_FREQ_HZ):树莓派硬件初始化,SPI0 + 8MHz 时钟radio.irqDioNum = 11:配置 LR2021 中断映射,确保通信稳定radio.XTAL = true:开启外部晶振,保证 LoRaWAN 频点精度saveLoRaWANState():将会话数据保存到本地文件,实现持久化restoreLoRaWANState():从文件恢复会话,支持快速重连node.beginOTAA() / node.activateOTAA():OTAA 入网关键函数node.sendReceive():发送上行数据并监听服务器下行printHex / printAscii:格式化打印下行数据【程序使用】
05_lr2021_LoRaWAN目录,执行编译运行:cd ~/core2021-xf/examples/raspberrypi/05_lr2021_LoRaWAN
chmod +x *
./build.sh
./build/05_lr2021_LoRaWAN
【运行效果】

参考下表进行连接:
| Core2021-XF | STM32L476RG |
|---|---|
| CLK | PA5 |
| MISO | PA6 |
| MOSI | PA7 |
| CS | PA8 |
| DIO8 | PA1 |
| RESET | PA0 |
| BUSY | PB3 |
examples/main_examples 目录中【程序说明】
【代码分析】
smtc_modem_hal.h、smtc_hal_mcu.h、smtc_hal_gpio.h、smtc_hal_watchdog.hradio_tx_irq_callback、radio_rx_irq_callback、timer_irq_callbackralf_params_lora_t rx_lora_param / tx_lora_param:用于端口测试的模拟 RX/TX 配置porting_test_spi():验证 SPI 端口与芯片固件版本porting_test_radio_irq():验证收发中断触发porting_test_get_time():检测 HAL 获取时间函数porting_test_timer_irq():验证定时器中断porting_test_stop_timer():验证定时器停止功能porting_test_disable_enable_irq():验证中断禁用/启用逻辑porting_test_random():验证随机数生成与分布porting_test_config_rx_radio() / porting_test_config_tx_radio():检测收发配置时间porting_test_sleep_ms():检测 MCU 睡眠时间porting_test_timer_irq_low_power():验证定时器低功耗模式porting_test_flash() / test_context_store_restore()main_porting_tests():ENABLE_TEST_FLASH 选择是否进行 Flash 测试【运行效果】

【程序说明】
"LoRa")【代码分析】
hal_mcu_init():初始化 MCU 外设smtc_rac_init():初始化 Radio Abstraction Layeruser_button_t 保存状态和按下时间user_button_callback():按键防抖,触发 Manager 模式SMTC_LED_TX / SMTC_LED_RXping_pong_init():初始化 Ping-Pong 事务periodic_uplink_init():初始化周期上行hal_watchdog_reload()smtc_rac_run_engine()ping_pong_on_button_press()hal_mcu_set_sleep_for_ms(SLEEP_DELAY)ping_pong_init():设置交易上下文、Payload、调制参数ping_pong_tx() / ping_pong_rx():发送/接收 PING 或 PONGpre_ping_pong_callback() / post_ping_pong_callback():【运行效果】

【程序说明】
example_options.h 提供 LoRaWAN 用户凭据:USER_LORAWAN_DEVICE_EUIUSER_LORAWAN_JOIN_EUIUSER_LORAWAN_GEN_APP_KEYUSER_LORAWAN_APP_KEYMODEM_EXAMPLE_REGION(EU868 或 WW_2G4)【代码分析】
hal_mcu_init()、hal_gpio_init_in() 配置外设smtc_rac_init() 和 smtc_modem_init() 初始化 Modem,回调 modem_event_callback()user_button_callback() 处理按键事件,触发即时上行periodical_uplink_init() 初始化事务post_periodic_callback() 调度下一次上行modem_event_callback() 处理 Modem 各类事件:RESET:设置凭据和区域,发起 JoinJOINED:入网成功,启动第一次周期上行ALARM:周期上行触发TXDONE:上行发送完成DOWNDATA:下行数据接收LINK_CHECK、CLASS_B_PING_SLOT_INFO 等打印调试信息smtc_modem_run_engine() 和 smtc_rac_run_engine() 处理事务【运行效果】

Semtech 的 LoRa 是一种长距离、低功耗的物联网 (IoT) 无线平台,一般情况下泛指使用LoRa技术的射频芯片.主要特点如下
LoRa(long range 的缩写)采用的扩频调制技术源于啁啾扩频 (CSS) 技术,是远距离无线传输技术和LPWAN通信技术中的一种.扩频技术用带宽换取灵敏度的技术,Wi-Fi,ZigBee等都使用了扩频技术,但LoRa调制的特点是接近香农定理的极限,最大效率地提高灵敏度.相比于传统FSK技术,在相同的通信速率下,LoRa比FSK灵敏度好8~12dBm.目前,LoRa 主要在Sub-GHz的ISM频段运行,
LoRa技术融合了数字扩频、数字信号处理和前向纠错编码等技术使得在长距离通信性能层面大幅度提高,LoRa的链路预算优于其他任何标准化的通信技术,链路预算是指给定的环境中决定距离的主要因素.
LoRa射频芯片主要有 SX127X系列,SX126X系列,SX130X系列,其中SX127X,SX126X系列用于LoRa节点,SX130X用于LoRa网关,详情可参考Semtech的产品列表
LoRaWAN 是一种建立在 LoRa 无线电调制技术之上的低功耗广域网开放协议。旨在将电池供电的“事物”无线连接到区域、国家或全球网络中的互联网,并针对关键的物联网 (IoT) 要求,例如双向定向通信、端到端安全、移动性和本地化服务。其中节点无线连接到互联网有入网认证,相当于建立节点和服务器间的加密通信信道,LoRaWAN协议层次下图所示。
MAC层中的Class A/B/C 三类节点设备基本覆盖了物联网所有的应用场景,三者之间不同点在于节点收发的时隙不同
Modulation层中EU868,AS430等表明不同国家使用频段参数不同,地区参数请点击参考链接

实现LoRaWAN网络覆盖城市或其它区域需要由节点(LoRa节点射频芯片)、网关(或称基站,LoRa网关射频芯片)、Server和云四部分组成,如下图所示
DEVICE(节点设备)需先发起入网请求数据包到GATEWAY(网关)再到服务器,认证通过后才可以正常和服务器收发应用数据
GATEWAY(网关)可通过有线网络,3/4/5G无线网络与服务器进行通信
服务器端主要运营商有TTN等,自行搭建云端服务请参考lorawan-stack,chirpstack

树莓派4B(含配套电源)
SD卡(建议使用容量大于 8GB 的 SD 卡)
读卡器
网关设备
节点设备
开发板(可选型号):ESP32、树莓派、STM32 和 Raspberry Pi Pico

本示例使用ChirpStack作为 LoRaWAN 网络服务器,请按照官方提供的 Raspberry Pi 安装步骤进行配置。
先下载ChirpStack Gateway OS 镜像,将其解压后,使用Win32DiskImager将镜像写入 SD 卡。
下载镜像
写入镜像
写入完成后,请参考官方文档进行详细配置。本文仅提供简要安装流程,详细信息请参见:ChirpStack Gateway OS 入门指南
将 SD 卡插入树莓派并通电启动。启动后,电脑 Wi-Fi 将扫描到名为 ChirpStackAP-XXXXXX 的无线热点,密码为 ChirpStackAP。连接成功后,在浏览器中访问:192.168.0.1,即可打开 ChirpStack 管理界面,首次登录无需密码。
连接 Wi-Fi
访问 Web 界面
启动后可通过以太网或 Wi-Fi 接入外部网络。此处以连接以太网为例,若需配置 Wi-Fi,请参考:Wi-Fi 配置,联网后可在 Web 管理界面查看当前 IP 地址。

服务器配置完成并获取 IP 地址后,关闭树莓派并断电,将 SX1303-868M-LoRaWAN-Gateway-HAT(网关设备)连接至树莓派,并接上天线。启动树莓派后,在浏览器中访问前面获取的 IP 地址,进入 ChirpStack 管理界面,依次点击ChirpStack -> Concentratord,启用网关功能。以 SX1303(868 MHz)为例,配置如下,配置完成后点击“保存并应用”:

使能网关

配置网关参数
使用前面获取的 IP 地址通过 SSH 工具(如 MobaXterm)远程访问设备。默认用户名为 root,连接成功后,在终端中输入以下命令获取网关 ID:gateway-id,系统将输出当前设备的网关 ID,请记下该 ID,稍后添加网关时将用到。

进入应用程序:Applications -> ChirpStack,首次进入时需要登录,默认账号和密码均为 admin。登录后,点击 Gateways -> Add gateway,在添加页面中填写前面获取的 gateway-id,并保存。返回 Gateways 页面,即可看到网关是否已经成功上线。

添加网关到服务器

查看网关是否上线
这里以 Core1121-XF 为例,添加节点。
首先,在 Web 界面中添加一个设备配置文件:Device Profiles -> Add device profile,配置如下图所示:

然后添加一个应用程序:Applications -> Add application,填写相关信息并保存:


设置 EUI

设置密钥
使用 05_lr2021_LoRaWAN 示例程序,打开后进入目录:core2021-xf\examples\arduino\05_lr2021_LoRaWAN中,编辑其中的 config.h 文件,将前面生成的 EUI 和 密钥 等信息填入对应位置。完成后编译并烧录。

烧录完成后,节点将自动请求加入 LoRaWAN 网络。加入成功后,节点将定时发送上行数据。可通过 Web 界面查看设备事件与通信状态:
①、点击 Events,查看节点运行状态
②、观察是否加入失败
③、若加入成功,可看到入网事件
④、查看节点上报的数据
⑤、通过串口查看调试信息

服务器也支持向节点下发数据:
①、点击 Queue
②、输入需要下发的十六进制数据
③、点击发送
④、节点接收数据并在串口打印

开发板设计文件
GitHub:
Gitee:
周一-周五(9:30-6:30)周六(9:30-5:30)
手机:13434470212
邮箱:services04@spotpear.cn
QQ:202004841
