前言:

本文将从频率、时间这两个资源的角度,来剖析LoRaWAN A类/C类终端的信道选择算法与代码实现示例。

不同的地区的频段,有不同的规范要求,算法有所差异,本文将以中国区的470M频段为例进行拆解,其他区域的频段以此类推。

不同的终端类型,算法也算法有所差异,本文将以ClassA与Class C为例,而Class B相对比较复杂,将单独讨论。


Table of Contents

前言:

第一章 频谱资源与载波信道

1.1 电磁频谱

1.2 LoRa WAN频段:

1.3 载波信道

1. 4 RegionCN470载波信道的划分与定义

1.5  RegionCN470信道号与频率的映射关系

第二章  RegionCN470上行发送的信道/频率资源调度算法

第三章 RegionCN470下行接收的信道/频率资源调度算法

3.1 接收窗口Rx1

3.2 接收窗口Rx2

第四章 RegionCN470上下发送的时间资源调度算法

4.1 非Join消息上行调度算法--占空比未使能

4.2 非Join消息上行调度算法--占空比使能

4.3 Join消息上行调度算法--自带占空比使能

第五章 RegionCN470下行接收的时间资源调度算法

5.1 Class A类型终端

5.2 Class C类型终端

5.3 时间资源调度算法代码示例


第一章 频谱资源与载波信道

1.1 电磁频谱

是指按电磁波波长(或频率)连续排列的整个电磁波族。


1.2 LoRa WAN频段:

频段:无线通信中使用的频段只是电磁波频段中很小的一部分,定义了无线电波的频率范围。

LoRaWAN代码目前支持的频段  
 *              - #define REGION_EU433
 *              - #define REGION_CN470
 *              - #define REGION_CN779
 *              - #define REGION_IN865
 *              - #define REGION_EU868
 *              - #define REGION_AU915
 *              - #define REGION_US915
 *              - #define REGION_US915_HYBRID
 *              - #define REGION_KR920
 *              - #define REGION_AS923

EU: 欧洲; CN: 中国;IN:印度;AU:澳大利亚;US: 美国;

1.3 载波信道

频段是一段频率范围,跨越的范围有几十兆,甚至上百兆。对于LoRa而言,一次数据传输通常只需要125K或250K或500K的频谱带宽。因此需要把整个频段的频谱进一步的平均切分。有点类似整个马路的车道:

每个切分的一小段称为载波带宽

在LTE里面,每个切分的一小段载波带宽,又称为子载波;

在LoRa里,没有子载波的概念,每个切分的一小段载波带宽,被称为一个独立的信道(channel)

LoRa的调制解调,就是对125K或250K或500K这么一小段的载波带宽进行的。

1. 4 RegionCN470载波信道的划分与定义

上行发送信道:96个信道,信道带宽:200K, 总带宽=96*0.2K = 19.2M

下行接收信道:48个信道,信道带宽:200K,   总带宽=48*0.2K = 9.6M

接收窗口Rx1和RX2的信道都来下行接收信道。

至于Rx1和Rx2窗口选择哪个具体的信道,由下行信道的算法所决定。

代码实现参考:

/*!* Defines the first channel for RX window 1 for CN470 band*/
#define CN470_FIRST_RX1_CHANNEL                     ( (uint32_t) 500300000 )/*!* Defines the last channel for RX window 1 for CN470 band*/
#define CN470_LAST_RX1_CHANNEL                      ( (uint32_t) 509700000 )/*!* Defines the step width of the channels for RX window 1*/
#define CN470_STEPWIDTH_RX1_CHANNEL                 ( (uint32_t) 200000 )/*!* Second reception window channel frequency definition.*/
#define CN470_RX_WND_2_FREQ                         ( (uint32_t)505300000 )/*!* LoRaMac maximum number of channels*/
#define CN470_MAX_NB_CHANNELS                        96/*!* LoRaMAC channel definition*/
typedef struct sChannelParams
{/*!* Frequency in Hz*/uint32_t Frequency;/*!* Alternative frequency for RX window 1*/uint32_t Rx1Frequency;/*!* Data rate definition*/DrRange_t DrRange;/*!* Band index*/uint8_t Band;
}ChannelParams_t;/*!* LoRaMAC receive window 2 channel parameters*/
typedef struct sRx2ChannelParams
{/*!* Frequency in Hz*/uint32_t Frequency;/*!* Data rate** LoRaWAN Regional Parameters V1.0.2rB** The allowed ranges are region specific. Please refer to \ref DR_0 to \ref DR_15 for details.*/uint8_t  Datarate;
}Rx2ChannelParams_t;// Global attributes
/*!* LoRaMAC channels*/
static ChannelParams_t Channels[CN470_MAX_NB_CHANNELS];/*!* LoRaMac bands*/
static Band_t Bands[CN470_MAX_NB_BANDS] =
{CN470_BAND0
};/*!* LoRaMac channels mask*/
static uint16_t ChannelsMask[CHANNELS_MASK_SIZE];  //通过mask,可以中96个信道中选择部分信道/*!* LoRaMac channels default mask*/
static uint16_t ChannelsDefaultMask[CHANNELS_MASK_SIZE];//上行信道号与上行发送频率之间的映射关系:按顺序一一映射
void RegionCN470InitDefaults( InitType_t type )
{
//.........................................// 125 kHz channelsfor( i = 0; i < CN470_MAX_NB_CHANNELS; i++ ){Channels[i].Frequency = 470300000 + i * 200000;Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;Channels[i].Band = 0;}      // Initialize the channels default mask// 使用所有的96个信道ChannelsDefaultMask[0] = 0xFFFF;ChannelsDefaultMask[1] = 0xFFFF;ChannelsDefaultMask[2] = 0xFFFF;ChannelsDefaultMask[3] = 0xFFFF;ChannelsDefaultMask[4] = 0xFFFF;ChannelsDefaultMask[5] = 0xFFFF;
}//下行信道号与下行发送频率之间的映射关系:按顺序一一映射
//这里采用的是动态计算还是一次性初始化
bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
{if( rxConfig->RxSlot == RX_SLOT_WIN_1 ){// Apply window 1 frequencyfrequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL;}
}

1.5  RegionCN470信道号与频率的映射关系

对上述代码需要进一步解读的是:信道号与频率的映射关系

(1)发送信道号与频率的映射关系:是在程序初始时,进行映射的。

(2)接收信道号与频率的映射关系:

接收窗口Rx1:是在每次RxConfg的时候,进行映射的。

bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
{
}

接收窗口Rx2:是动态参数配置

static void OnRxWindow2TimerEvent( void )
{

RxWindow2Config.Channel = Channel;
    RxWindow2Config.Frequency = LoRaMacParams.Rx2Channel.Frequency;  //读取参数设置。

RegionRxConfig( LoRaMacRegion, &RxWindow2Config, ....)

}


第二章  RegionCN470上行发送的信道/频率资源调度算法

每一次数据发送,LoWAN MAC都会从96个最大信道数,随机的选择一个可用的信道,而不是采用固定信道:

代码示例:

LoRaMacStatus_t RegionCN470NextChannel(...)
{// We found a valid channel*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];}

nbEnabledChannels:是支持的最大时机channel数目

randr( 0, nbEnabledChannels - 1):在0和nbEnabledChannels - 1产生一个随机数,通过该随机数的下标,从enabledChannels【】数组中获取实际的信道号 。


第三章 RegionCN470下行接收的信道/频率资源调度算法

RegionCN470 FDD模式,上下行的频率是分开的。

3.1 接收窗口Rx1

由于上行发送最大支持96个信道,下行接收只支持48个信道,因此无法采用1对1的映射。

RegionCN470采用的是多对1的映射关系:接收信号号=发送信道号%48.

当LoRa的网关接收到终端的数据,并获取该数据对应的信道后,通过上述同样的映射关系,选择下行的发送信道。

确保终端的接收与网关的发送是在相同的信道上。

bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
{//...................................if( rxConfig->RxSlot == RX_SLOT_WIN_1 ){// Apply window 1 frequencyrx_channel = rxConfig->Channel % 48;frequency = CN470_FIRST_RX1_CHANNEL + rx_channel * CN470_STEPWIDTH_RX1_CHANNEL;}
}

注意:

多对一的映射关系不会引发错乱,只有一对多的关系,才会导致错乱,才会导致终端接收与网关发送的信道不一致。

3.2 接收窗口Rx2

终端的接收窗口Rx2的接收信道与发送信道号无关。采用两种机制

  • 终端与网关预先约定好
  • 网关通过接收窗口Rx1的信道,下发配置命令,通知终端接收窗口Rx2信道号,实际上是接收频率。

代码示例:

static void OnRxWindow2TimerEvent( void )
{RxWindow2Config.Frequency = LoRaMacParams.Rx2Channel.Frequency;
}

上述参数LoRaMacParams.Rx2Channel.Frequency是实现线下预约好的,作为默认值,也可以通过下发配置命令修改该默认值。


至此:探讨了LoRa终端在接收和发送数据时,发送和接收信道的选择,即发送和接收数据时,载波频率的选择。

但每个LoRa终端,并非在任何时间,都可以占用信道发送数据,这里受限于发送占空比(消息类型、占空比 duty cycle的设定)

也并非在任何时候,都可以通过信道接收数据,这里这里所限于终端的工作模式(种类类型、接收窗口)



第四章 RegionCN470上下发送的时间资源调度算法

4.1 非Join消息上行调度算法--占空比未使能

在这种情况下,不受空口占用信道占空比的限制,可以在任意时刻发送数据。

发送数据的周期只收到如下参数的影响:

#define CN470_DUTY_CYCLE_ENABLED                    0/*!* Defines the application data transmission duty cycle. 5s, value in [ms].*/
#define APP_TX_DUTYCYCLE                            5000/*!* Defines a random delay for application data transmission duty cycle. 1s,* value in [ms].*/
#define APP_TX_DUTYCYCLE_RND                        1000// Schedule next packet transmission
TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( 0, APP_TX_DUTYCYCLE_RND );

TxDutyCycleTime定义了下次发送数据的时间,叠加了周期性与随机性双重特征。

4.2 非Join消息上行调度算法--占空比使能

当应用层有数据发送时,LoRaWAN的发送调度器必须确保:发送数据占用空口信道的时间满足占空比的要求。

在上图中,在T0和T2之间的任何时间是不允许发送数据的,比如T1,因为这段时间,不满足发送占空比的要求。

只有当前时间大于T2, 比如T3, 才能允许发送下一个数据。

这里的关键是如何求发送间隔周期?

发送间隔周期T =  数据帧在空口发送时间 /占空比。

举例:

空口发送时间1.2s, 占空比100%(或者变成1), 最短发送周期=1.2s

空口发送时间1.2s, 占空比1%(或者表达成100), 最短发送周期=1.2s * 100 =》120s =》2分钟。

空口发送时间1.2s, 占空比0.1%(或者表达成1000), 最短发送周期=1.2s * 1000 =》1200s =》20分钟。

代码示例:

#define CN470_DUTY_CYCLE_ENABLED                    1/*!* Band 0 definition* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }*/
#define CN470_BAND0   { 1, CN470_MAX_TX_POWER, 0, 0, 0 } //  占空比:1/1 = 100.0 %void RegionCommonCalcBackOff( RegionCommonCalcBackOffParams_t* calcBackOffParams )
{if( calcBackOffParams->DutyCycleEnabled == true ) //发送占空比使能{//计算还剩多少时间,允许下次发送数据calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir;}else //发送占空比没有使能{    //立即发送数据,无时间延时:TimeOff = 0calcBackOffParams->Bands[bandIdx].TimeOff = 0; }}

4.3 Join消息上行调度算法--自带占空比使能

(1)Join消息的可变占空比

为了防止join request失败或无响应后,终端无休止的发送Jion request。

针对request成功之前的Join消息请求,LoRaWAN MAC设计了强制性的占空比使能机制。

且随着时间的推移,占空比的比值不是固定的,需要分等级性的变化,时间越长,占空比的比值越小。

定义可变占空比的代码案例:


#define BACKOFF_DC_1_HOUR       100     //占空比=1%
#define BACKOFF_DC_10_HOURS     1000    //占空比=0.1%
#define BACKOFF_DC_24_HOURS     10000   //占空比=0.01%uint16_t RegionCommonGetJoinDc( TimerTime_t elapsedTime )
{uint16_t dutyCycle = 0;if( elapsedTime < 3600000 ){dutyCycle = BACKOFF_DC_1_HOUR;}else if( elapsedTime < ( 3600000 + 36000000 ) ){dutyCycle = BACKOFF_DC_10_HOURS;}else{dutyCycle = BACKOFF_DC_24_HOURS;}return dutyCycle;
}

(2)通过占空比和join消息空口的发送时间求下次发送的剩余时间time_off

void RegionCommonCalcBackOff( RegionCommonCalcBackOffParams_t* calcBackOffParams )
{if( calcBackOffParams->Joined == false ){// Get the join duty cycle: 100, 1000, 10000joinDutyCycle = RegionCommonGetJoinDc( calcBackOffParams->ElapsedTime );// Apply band time-off.calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * (dutyCycle - 1);}}

因此,如果Join request消息的空口发送时间是1.5s,

则Join request失败或超时重新请求的最小周期为:1.5s * 100 = 1500s => 2.5分钟。


第五章 RegionCN470下行接收的时间资源调度算法

5.1 Class A类型终端

(1)Join accept之前

(2)Join accept之后:

5.2 Class C类型终端

(1)Join accept之前

(2)Join accept之后:

5.3 时间资源调度算法代码示例

static void OnRadioTxDone( void )
{GetPhyParams_t getPhy;PhyParam_t phyParam;SetBandTxDoneParams_t txDone;TimerTime_t curTime = TimerGetCurrentTime( );if( LoRaMacDeviceClass != CLASS_C ){Radio.Sleep( );   //Class A终端,发送完成后,直接进入休眠状态}else{OpenContinuousRx2Window( ); //Class A终端,发送完成后, 带宽Rx2接收窗口}// Setup timersif( IsRxWindowsEnabled == true ){TimerSetValue( &RxWindowTimer1, RxWindow1Delay );  //1s或5s之后打开Rx1窗口TimerStart( &RxWindowTimer1 ); if( LoRaMacDeviceClass != CLASS_C ){TimerSetValue( &RxWindowTimer2, RxWindow2Delay ); //2s或6s之后打开Rx2窗口TimerStart( &RxWindowTimer2 );}if( ( LoRaMacDeviceClass == CLASS_C ) || ( NodeAckRequested == true ) ){getPhy.Attribute = PHY_ACK_TIMEOUT;phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );TimerSetValue( &AckTimeoutTimer, RxWindow2Delay + phyParam.Value );TimerStart( &AckTimeoutTimer );               //对于需要应答的消息,额外等待2s}}
//...................
}

物联网LoRa系列-30:LoRaWAN A类/C类终端的载波信道资源与时间资源上下行调度算法相关推荐

  1. 物联网LoRa系列-32:LoRaWAN无线智能水表如何进行水量数据采集?脉冲采集、双干簧管、磁性元件、光电转换、霍尔元件

    目录 1. 无线远传智能水表概述 2. 常用智能水表的发展与类型 3. 智能水表数据的采集的基本原理 3.1 光电转换型原理 3.2 双干簧管数据采集的基本原理 3.3 霍尔元件型原理 4. 干簧管脉 ...

  2. 物联网LoRa系列-28:LoRaWAN PingPong终端与Class A/B/C类型终端不能互通的原因与解决办法

    在LoRa终端与LoRa网关和服务器联调之前,有时候需要通过相对简单的PingPong终端序给Class A/B/C类型的终端发送数据,以验证Class A/B/C终端可以正常收发数据包.然而原生提供 ...

  3. 物联网LoRa系列-4:LoRa终端射频芯片SX1268、SX1278、SX1262对比与选择

    1. 产品简述 LoRa的射频芯片主要分两大类,一类是LoRa终端射频芯片,另一类是LoRa基站/网关射频芯片. LoRa终端射频芯片目前有三款:SX1278.SX12786.SX1262: LoRa ...

  4. 物联网LoRa系列-26:LoRaWAN Class A/B/C类型终端的软件架构

    前言: 本文是在了解LoRoWAN协议的基础之上,对LoRa Class A/B/C终端的通用的软件实现架构进行拆解. 从软件架构的角度拆解LoRa Class A/B/C终端的软件功能实体之间的关系 ...

  5. 物联网LoRa系列-1:物联网系统分层架构

    本文将阐述物联网总体的系统组成以及分层架构:系统架构图.感知层.网络层.平台层.应用层. 本系列将全面.详细的拆解5G物联网的内部架构.主要技术原理.开发环境搭建.代码实现等,同时还将手把手的一步步构 ...

  6. 物联网LoRa系列-24:LoRa终端--PingPong应用程序常见问题解析

    前言: 前面对LoRa终端的各种技术的拆解, 从技术的内容角度看,主要是包括LoRa的SX1261/SX1262终端的硬件设计.SX1261/SX1262芯片资料的解读.以及PingPong应用程序的 ...

  7. 物联网LoRa系列-17:LoRa终端Sx1262芯片内部的射频信号放大器

    至此,我们已经拆解了天线是如何发送和接收空中的无线电磁波信号.拆解了无线终端如何对射频前端的高频电信号进行进一步处理的.还拆解了无线终端的发送和接收如何分时复用天线的半双工模式. 本篇将进一步拆解无线 ...

  8. 物联网LoRa系列-8:LoRa终端应用程序开发环境的搭建

    目录: 一. LoRa终端应用程序开发环境的目标 二. LoRa终端应用程序开发环境的搭建步骤 一.  LoRa终端应用程序开发环境的目标 (1)Protel 99SE:是硬件原理图和PCB开发的工具 ...

  9. 物联网LoRa系列-12:LoRa终端--数据发送和接收的整个过程

    在上文<全面拆解和构建5G物联网-11:LoRa终端--基于物理层协议的PingPong应用程序的软件架构>中,我们已经通过开发板提供商提供的软件工程文件,在两个LoRa节点之间进行了点对 ...

最新文章

  1. matlab中的mkdir函数_科学网—Matlab中计算函数运行时间的三种方法及判断新建文件夹 - 张伟的博文...
  2. ACMNO.24 C语言-转置矩阵 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换。 输入 一个3x3的矩阵 输出 转置后的矩阵 样例
  3. 有些事儿,工程师可能今生仅此一次
  4. 微博:吃饭砸锅的艺术
  5. 《IBM-PC汇编语言程序设计》(第2版)【沈美明 温冬婵】——第十章——自编解析与答案
  6. koa --- 使用Github OAuth登录
  7. js图片压缩java上传,JS实现异步上传压缩图片
  8. 十分钟搞定 pandas
  9. english 2012020604
  10. Java SE 正则表达式 API Pattern 与 Matcher.
  11. 最新席瓦莱恩服务器人口比例,魔兽世界怀旧服:2021年3月最新人口比例数据
  12. WebRoot 与 WEB-INF 相关问题学习整理
  13. 【后端】Nginx 体系
  14. HTML、CSS学习总结
  15. 基于 SSR 的预渲染首屏直出方案
  16. OFDM和OFDMA的主要优缺点
  17. 急如闪电快如风,彩虹女神跃长空,Go语言高性能Web框架Iris项目实战-初始化项目ep00
  18. 自动管道过滤器结构组成与应用领域介绍
  19. echarts 仪表盘 文字位置_ECharts 使用series.title.offsetCenter设置仪表盘标题位置
  20. 服务器自带的校时ip是多少钱,国内大概可用的NTP时间校准服务器IP地址

热门文章

  1. Docker收购Kitematic:一个非常棒的GUI工具
  2. 初中教师资格证科学计算机面试,2019下半年初中科学教师资格证面试真题及答案汇总...
  3. 引水工程--nyoj1239
  4. 『前端学习实例』 静态网页(Bootstrap)
  5. 死锁、活锁和饿死的理解(转)
  6. Java遍历集合元素并修改
  7. 大数据平台用于生成数据跑批脚本的脚本
  8. 金融服务(银行证券机构方向)etl批量作业集群统一调度平台搭建
  9. 利用python函数,求正方形的面积
  10. ZigBee网络数据传递流程_物联网技术讲解:室内定位技术(WIFI、蓝牙BLE、Zigbee、UWB)...