Lorawan调试纪要

Lorawan调试纪要

  1. 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入网方式有两种:

  1. ABP (Activation By Personalization,个性化激活)
  2. 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,在刚上电的时候,是不处于入网状态的,此时就需要进行入网操作。

如果我们简单的把服务器看做一个整体,那么入网操作的流程是这样的:

  1. node 发送入网请求,即join_request message
  2. GW 收到 node 的数据,上传给服务器
  3. 服务器收到入网请求,同意入网,并且将设备在服务器注册,建立长地址与短地址之间的联系,生成通讯密钥,将通讯密钥的参数打包下发给GW,即 Join-accept message
  4. GW 收到服务器的数据,下发给 node
  5. 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机制:空中唤醒技术。

  1. 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方式与服务器进行交互。

本次移植遇到的问题:

  1. 硬件上设计有缺陷,DIO引脚未连接MCU,导致不能实现源码的中断处理,需适配为查询寄存器方式来实现,由此带来了不稳定性;

  2. 此MCU的RTC不支持日历寄存器,需软件算法弥补;

  3. 此MCU与Lorawan的低功耗处理有点不兼容,已在大部分地方禁止进入低功耗;

  4. 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 网关所需配置及脚本

  1. 网关引脚复位脚本编写

    !/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
    fi

    echo "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
    ;;
    esac

    exit 0

  2. 网关服务启动脚本编写
    #!/bin/sh

    echo "start lora gateway"
    cd /apps/wh_lora
    ./reset_lgw.sh start
    ./lora_pkt_fwd &
    
  3. 网关全局配置文件编写(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
        }
    }
    
  4. Lorawan 服务器实现

详见《lora服务器ChirpStack部署》

  1. 联合调试

启动服务器,浏览器输入 http://10.99.20.253:8080

# 进入 chirpstack-docker
docker-compose up

启动网关服务

./loraserver_start.sh

运行节点(联系发送)

在服务器页面查看上行数据如下:

posted @ 2025-06-20 11:01  silencehuan  阅读(180)  评论(0)    收藏  举报