Lorawan调试纪要
Lorawan调试纪要
- Lorawan基础概念
1.1 lorawan简介及扩频技术
LoRaWAN是为LoRa远距离通信网络设计的一套通讯协议和系统架构。

Lora 扩频技术:通过注入一个更高频信号将基带信号扩展到更宽的频带,它的基本特点是其传输信息所用信号的带宽远大于信息本身的带宽。
扩频计数常用设置参数及术语:带宽(BandWidth)、SNR(信噪比)、RSSI(接收信号强度指示)、扩频因子(SF)、 编码率(CR)等
1.2 Lorawan 网络架构

LoRaWAN的网络实体分为四个部分: 终端节点、网关、LoRaWAN服务器(包含NS、AS)和用户服务器。
End Node: 终端节点一般是各类传感器,进行数据采集,开关控制等 。
Gateway: LoRa网关,对收集到的节点数据进行封装转发 。
NS(NetworkServer): 主要负责上下行数据包的完整性校验。
AS(ApplicationServer): 主要负责OTAA设备的入网激活,应用数据的加解密 。
CS(CustomerServer): 从AS中接收来自节点的数据,进行业务逻辑处理,通过AS提供的API接口向节点发送数据。
1.3 LoRaWAN终端设备分类
根据协议规定有 Class A/B/C 三类终端设备,这三类设备基本覆盖了物联网所有的应用场景。CLASSA/B/C的应用和区别如下:

1.4 LoRaWAN终端设备入网
在LoRaWAN中,node最终和服务器能够正常数据交互,需要先入网,入网的本质,也就是获得一些通信相关的参数,有以下几个:
- NwkSKey:用于数据的校验,也就是说在MIC校验时会用到
- AppSKey:用于负载的AES加密,也就是说在加密解密时会使用到
- DevAddr:是node的短地址,在数据通讯时,使用的是node的短地址
- DevEUI:在ABP入网方式的通讯中不会使用,在OTAA方式中会使用到,是由设备在入网前就产生了。在入网时,node将DevEUI上传,然后服务器会将此DevEUI注册并返回一个DevAddr,也就是说DevAddr此时和DevEUI就建立了映射关系,在node后续的通讯中,使用DevAddr。
LoRaWAN入网方式有两种:
- ABP (Activation By Personalization,个性化激活)
- OTAA(Over-The-Air Activation,空中激活)
1 ABP
ABP是一种简单的入网机制,同时,它也不太安全,适合于建设私网。
这种方法比较简单粗暴,直接配置 DevAddr,NwkSKey,AppSKey 这三个LoRaWAN最终通讯的参数,不再需要join流程。在这种情况下,这个设备是可以直接发应用数据的。
2 OTAA
需要设置的参数
- DevEUI(设备唯一标识符, Server与Node预先存储)
- AppEUI(应用唯一标识符, Server与Node预先存储)
- AppKey(Server和Node都要预先存好, 用于对join_accept message的加解密还有node用于生成AppSKey和NwkSKey)
OTAA方式入网的node,在刚上电的时候,是不处于入网状态的,此时就需要进行入网操作。
如果我们简单的把服务器看做一个整体,那么入网操作的流程是这样的:
- node 发送入网请求,即join_request message
- GW 收到 node 的数据,上传给服务器
- 服务器收到入网请求,同意入网,并且将设备在服务器注册,建立长地址与短地址之间的联系,生成通讯密钥,将通讯密钥的参数打包下发给GW,即 Join-accept message
- GW 收到服务器的数据,下发给 node
- node 根据下发的数据包,得到 DevAddr、APPSKEY、NWKSKEY
1.5 LoRaWAN终端设备数据传输
这是Class A 上下行的时序图,目前接收窗口RX1一般是在上行后1秒开始,接收窗口RX2是在上行后2秒开始。

Class C 和 A 基本是相同的,只是在 Class A 休眠的期间,它都打开了接收窗口RX2

Class B 的时隙则复杂一些,它有一个同步时隙beacon,还有一个固定周期的接收窗口ping时隙。如这个示例中,beacon周期为128秒,ping周期为32秒

- 加网之后,应用数据就被加密处理了。
- LoRaWAN规定数据帧类型有 Confirmed 或者 Unconfirmed 两种,即需要应答和不需要应答类型。厂商可以根据应用需要选择合适的类型。
- 终端节点每次发送数据包都要随机切换信道,切换信道可以有效降低同频干扰和无线信号衰减。
- 发送占空比(DutyCycle) 不同国家和地区, 在ISM频段, 每个无线设备允许的最大发送占空比是有限制的, 这样是为了保证公平和防止非法占用信道。 以欧洲为例, DutyCycle=1%,如果一个设备发射时间为1s, 则接下来99s它都不能再发射无线信号(但是可以接收)。
1.6 其他
ADR机制: LoRa网络允许终端设备逐一使用所有可用的数据速率。LoRaWAN协议根据该特性对静态终端的数据速率进行调整优化,这就是数据速率自适应(ADR)。
CAD机制:空中唤醒技术。
- Lorawan 终端节点实现
推荐节点MCU芯片 STM32L 系列。
本次移植 STM32F103 + SX1276 + LoRaMac-node-4.4.0
根据 lorawan 版本(本文 1.0.2)选择对应版本 LoRaMac-node
注意 版本说明 LoRaMac-node-4.4.0 之前的版本不支持 CN470,之后的版本代码结构相对复杂会增加移植适配难度;
主要移植内容:
- gpio、spi、rtc、timer、delay等驱动适配
- sx1276硬件层适配
- 其他
采用 CLass C方式与服务器进行交互。
本次移植遇到的问题:
-
硬件上设计有缺陷,DIO引脚未连接MCU,导致不能实现源码的中断处理,需适配为查询寄存器方式来实现,由此带来了不稳定性;
-
此MCU的RTC不支持日历寄存器,需软件算法弥补;
-
此MCU与Lorawan的低功耗处理有点不兼容,已在大部分地方禁止进入低功耗;
-
Lorawan 网关实现
3.1 源码下载及编译
lora_gateway-5.0.1 网关库
packet_forwarder-4.0.1 包转发
根据情况修改 loragw_spi 中的
define SPI_DEV_PATH "/dev/spidev0.0"
修改 Makefile 交叉编译最后生成网关服务程序 lora_pkt_fwd
3.2 网关所需配置及脚本
-
网关引脚复位脚本编写
!/bin/sh
This script is intended to be used on IoT Starter Kit platform, it performs
the following actions:
- export/unpexort GPIO7 used to reset the SX1301 chip
Usage examples:
./reset_lgw.sh stop
./reset_lgw.sh start
The reset pin of SX1301 is wired with RPi GPIO7
If used on another platform, the GPIO number can be given as parameter.
if [ -z "$2" ]; then
IOT_SK_SX1301_RESET_PIN=129
else
IOT_SK_SX1301_RESET_PIN=$2
fiecho "Accessing concentrator reset pin through GPIO$IOT_SK_SX1301_RESET_PIN..."
WAIT_GPIO() {
sleep 0.1
}iot_sk_init() {
# setup GPIO 7
#echo "$IOT_SK_SX1301_RESET_PIN" > /sys/class/gpio/export; WAIT_GPIO# set GPIO 7 as output #echo "out" > /sys/class/gpio/gpio$IOT_SK_SX1301_RESET_PIN/direction; WAIT_GPIO # write output for SX1301 reset #echo "1" > /sys/class/gpio/gpio$IOT_SK_SX1301_RESET_PIN/value; WAIT_GPIO #echo "0" > /sys/class/gpio/gpio$IOT_SK_SX1301_RESET_PIN/value; WAIT_GPIO # set GPIO 7 as input #echo "in" > /sys/class/gpio/gpio$IOT_SK_SX1301_RESET_PIN/direction; WAIT_GPIO # 按需求使用GPIO控制 /apps/bin/gpio-tool -o 2 1 WAIT_GPIO /apps/bin/gpio-tool -o 2 0 WAIT_GPIO /apps/bin/gpio-tool -i 2}
iot_sk_term() {
# cleanup GPIO 7
if [ -d /sys/class/gpio/gpio$IOT_SK_SX1301_RESET_PIN ]
then
echo "$IOT_SK_SX1301_RESET_PIN" > /sys/class/gpio/unexport; WAIT_GPIO
fi
}case "$1" in
start)
iot_sk_term
iot_sk_init
;;
stop)
iot_sk_term
;;
*)
echo "Usage: $0 {start|stop} []"
exit 1
;;
esacexit 0
-
网关服务启动脚本编写
#!/bin/shecho "start lora gateway" cd /apps/wh_lora ./reset_lgw.sh start ./lora_pkt_fwd & -
网关全局配置文件编写(CN470)
设置对应区域频段信息,可参照官网示例
{
"SX1301_conf": {
"lorawan_public": true,
"clksrc": 1, /* radio_1 provides clock to concentrator /
"antenna_gain": 0, / antenna gain, in dBi /
"radio_0": {
"enable": true,
"type": "SX1255",
"freq": 470600000,
"rssi_offset": -166.0,
"tx_enable": true,
"tx_freq_min": 460000000,
"tx_freq_max": 506000000
},
"radio_1": {
"enable": true,
"type": "SX1255",
"freq": 471400000,
"rssi_offset": -166.0,
"tx_enable": false
},
"chan_multiSF_0": {
/ Lora MAC channel, 125kHz, all SF, 470.3 MHz /
"enable": true,
"radio": 0,
"if": -300000
},
"chan_multiSF_1": {
/ Lora MAC channel, 125kHz, all SF, 470.5 MHz /
"enable": true,
"radio": 0,
"if": -100000
},
"chan_multiSF_2": {
/ Lora MAC channel, 125kHz, all SF, 470.7 MHz /
"enable": true,
"radio": 0,
"if": 100000
},
"chan_multiSF_3": {
/ Lora MAC channel, 125kHz, all SF, 470.9 MHz /
"enable": true,
"radio": 0,
"if": 300000
},
"chan_multiSF_4": {
/ Lora MAC channel, 125kHz, all SF, 471.1 MHz /
"enable": true,
"radio": 1,
"if": -300000
},
"chan_multiSF_5": {
/ Lora MAC channel, 125kHz, all SF, 471.3 MHz /
"enable": true,
"radio": 1,
"if": -100000
},
"chan_multiSF_6": {
/ Lora MAC channel, 125kHz, all SF, 471.5 MHz /
"enable": true,
"radio": 1,
"if": 100000
},
"chan_multiSF_7": {
/ Lora MAC channel, 125kHz, all SF, 471.7 MHz /
"enable": true,
"radio": 1,
"if": 300000
},
"chan_Lora_std": {
/ Lora MAC channel, 250kHz, SF7, 470.5 MHz */
"enable": true,
"radio": 0,
"if": -100000,
"bandwidth": 250000,
"spread_factor": 7
},"chan_FSK": { /* FSK 100kbps channel, 470.5 MHz */ "enable": true, "radio": 0, "if": -100000, "bandwidth": 250000, "datarate": 100000 }, "tx_lut_0": { /* TX gain table, index 0 */ "pa_gain": 0, "mix_gain": 8, "rf_power": -6, "dig_gain": 0 }, "tx_lut_1": { /* TX gain table, index 1 */ "pa_gain": 0, "mix_gain": 10, "rf_power": -3, "dig_gain": 0 }, "tx_lut_2": { /* TX gain table, index 2 */ "pa_gain": 0, "mix_gain": 12, "rf_power": 0, "dig_gain": 0 }, "tx_lut_3": { /* TX gain table, index 3 */ "pa_gain": 1, "mix_gain": 8, "rf_power": 3, "dig_gain": 0 }, "tx_lut_4": { /* TX gain table, index 4 */ "pa_gain": 1, "mix_gain": 10, "rf_power": 6, "dig_gain": 0 }, "tx_lut_5": { /* TX gain table, index 5 */ "pa_gain": 1, "mix_gain": 12, "rf_power": 10, "dig_gain": 0 }, "tx_lut_6": { /* TX gain table, index 6 */ "pa_gain": 1, "mix_gain": 13, "rf_power": 11, "dig_gain": 0 }, "tx_lut_7": { /* TX gain table, index 7 */ "pa_gain": 2, "mix_gain": 9, "rf_power": 12, "dig_gain": 0 }, "tx_lut_8": { /* TX gain table, index 8 */ "pa_gain": 1, "mix_gain": 15, "rf_power": 13, "dig_gain": 0 }, "tx_lut_9": { /* TX gain table, index 9 */ "pa_gain": 2, "mix_gain": 10, "rf_power": 14, "dig_gain": 0 }, "tx_lut_10": { /* TX gain table, index 10 */ "pa_gain": 2, "mix_gain": 11, "rf_power": 17, "dig_gain": 0 }, "tx_lut_11": { /* TX gain table, index 11 */ "pa_gain": 3, "mix_gain": 9, "rf_power": 20, "dig_gain": 0 }, "tx_lut_12": { /* TX gain table, index 12 */ "pa_gain": 3, "mix_gain": 10, "rf_power": 23, "dig_gain": 0 }, "tx_lut_13": { /* TX gain table, index 13 */ "pa_gain": 3, "mix_gain": 11, "rf_power": 25, "dig_gain": 0 }, "tx_lut_14": { /* TX gain table, index 14 */ "pa_gain": 3, "mix_gain": 12, "rf_power": 26, "dig_gain": 0 }, "tx_lut_15": { /* TX gain table, index 15 */ "pa_gain": 3, "mix_gain": 14, "rf_power": 27, "dig_gain": 0 } }, "gateway_conf": { "gateway_ID": "AE02000218041014", /* change with default server address/ports, or overwrite in local_conf.json */ "server_address": "10.99.20.253", "serv_port_up": 1700, "serv_port_down": 1700, /* adjust the following parameters for your network */ "keepalive_interval": 30, "stat_interval": 300, "push_timeout_ms": 1000, /* forward only valid packets */ "forward_crc_valid": true, "forward_crc_error": false, "forward_crc_disabled": false, "autoquit_threshold": 5 } } -
Lorawan 服务器实现
详见《lora服务器ChirpStack部署》
- 联合调试
启动服务器,浏览器输入 http://10.99.20.253:8080
# 进入 chirpstack-docker
docker-compose up
启动网关服务
./loraserver_start.sh
运行节点(联系发送)
在服务器页面查看上行数据如下:


浙公网安备 33010602011771号