LoRaWAN实战 中国470频段的代码实现

news/2024/12/13 2:29:06/

前言

在LoRaWAN协议中文版_配套文件 地区参数(物理层)中已经为中国规划了470频段,因此国内开发者对此需求很强烈。

在最新(2017-02-27)的V4.3.1版本协议栈上已经新增了中国470频段。这篇文章从源码角度解析下其实现方式。

目前国内的LoRaWAN基站产品都和标准有一些不同,比如CLAA等,所以搞清楚整个代码实现还是很有必要的。只要熟悉了整个流程,对接任何一个基站都不是难事。

我正在陆续对协议的各个章节进行翻译,具体其他章节的译文,以及译文之外的代码解析,可点此查看帖子LoRa学习笔记_汇总。

本文作者twowinter,转载请注明作者:http://blog.csdn.net/iotisan/

源码解析

1.前导码格式的源码实现

同步字的处理在SX1276的驱动中:

void SX1276SetPublicNetwork( bool enable )
{SX1276SetModem( MODEM_LORA );if( enable == true ){// Change LoRa modem SyncWordSX1276Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );}else{// Change LoRa modem SyncWordSX1276Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );}
}

而前导码长度则是在每次SetTxConfig和SetRxConfig时配置进去。

2.信道频率的源码实现

先说上行信道的处理。

第一步,初始化时把所有信道6*16=96个上行信道都使能了。

	LoRaMacParamsDefaults.ChannelsMask[0] = 0xFFFF;LoRaMacParamsDefaults.ChannelsMask[1] = 0xFFFF;LoRaMacParamsDefaults.ChannelsMask[2] = 0xFFFF;LoRaMacParamsDefaults.ChannelsMask[3] = 0xFFFF;LoRaMacParamsDefaults.ChannelsMask[4] = 0xFFFF;LoRaMacParamsDefaults.ChannelsMask[5] = 0xFFFF;

第二步,紧接着把96个信道的频点赋值一遍。

	for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS; i++ ){Channels[i].Frequency = 470.3e6 + i * 200e3;Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;Channels[i].Band = 0;}

第三步,发送时在SetNextChannel中选择合适的频点,默认是96个信道中随机选择。

Channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];

这上面是上行信道处理三部曲,下行信道处理则轻松多了。主要是配合接收窗口处理,由这个宏定义了下行的起始频点。具体可以看下面第7点。

#define LORAMAC_FIRST_RX1_CHANNEL           ( (uint32_t) 500.3e6 )

3.数据速率和节点发射功率编码

速率编码如下:

const uint8_t Datarates[]  = { 12, 11, 10,  9,  8,  7 };

发射功率编码如下:

const int8_t TxPowers[]    = { 17, 16, 14, 12, 10, 7, 5, 2 };

速率范围如下:

/*!* Minimal datarate that can be used by the node*/
#define LORAMAC_TX_MIN_DATARATE                     DR_0/*!* Maximal datarate that can be used by the node*/
#define LORAMAC_TX_MAX_DATARATE                     DR_5/*!* Minimal datarate that can be used by the node*/
#define LORAMAC_RX_MIN_DATARATE                     DR_0/*!* Maximal datarate that can be used by the node*/
#define LORAMAC_RX_MAX_DATARATE                     DR_5/*!* Default datarate used by the node*/
#define LORAMAC_DEFAULT_DATARATE                    DR_0

发射功率范围如下:

/*!* Minimal Tx output power that can be used by the node*/
#define LORAMAC_MIN_TX_POWER                        TX_POWER_2_DBM/*!* Maximal Tx output power that can be used by the node*/
#define LORAMAC_MAX_TX_POWER                        TX_POWER_17_DBM/*!* Default Tx output power used by the node*/
#define LORAMAC_DEFAULT_TX_POWER                    TX_POWER_14_DBM

4.CFList

中国没有。具体见OnRadioRxDone中的FRAME_TYPE_JOIN_ACCEPT分支。

5.LinkAdrReq命令

对于 ChMaskCntl 的处理都在 ProcessMacCommands() 的 SRV_MAC_LINK_ADR_REQ 分支中。

小彩蛋一个:你发现没,注释里写着Channel mask KO。不知是djaeckle (loramac-node的作者之一)调皮,还是语言习惯如此。

if( chMaskCntl == 6 )
{// Enable all 125 kHz channelsfor( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ ){for( uint8_t j = 0; j < 16; j++ ){if( Channels[i + j].Frequency != 0 ){channelsMask[k] |= 1 << j;}}}
}
else if( chMaskCntl == 7 )
{status &= 0xFE; // Channel mask KO
}
else
{for( uint8_t i = 0; i < 16; i++ ){if( ( ( chMask & ( 1 << i ) ) != 0 ) &&( Channels[chMaskCntl * 16 + i].Frequency == 0 ) ){// Trying to enable an undefined channelstatus &= 0xFE; // Channel mask KO}}channelsMask[chMaskCntl] = chMask;
}

6.最大载荷长度

/*!* Maximum payload with respect to the datarate index. Cannot operate with repeater.*/
const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 222, 222 };/*!* Maximum payload with respect to the datarate index. Can operate with repeater.*/
const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222 };

这在RxWindowSetup()进行处理,调用了最终的驱动函数。

if( RepeaterSupport == true )
{Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD );
}
else
{Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD );
}

7.接收窗口处理。

RX1的处理在OnRxWindow1TimerEvent()中,满足协议要求。

RxWindowSetup( LORAMAC_FIRST_RX1_CHANNEL + ( Channel % 48 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, datarate, bandwidth, symbTimeout, false );

RX2的默认参数见如下宏:

#define RX_WND_2_CHANNEL                                  { 505300000, DR_0 }

RX2的处理在OnRxWindow2TimerEvent()中:

if( RxWindowSetup( LoRaMacParams.Rx2Channel.Frequency, LoRaMacParams.Rx2Channel.Datarate, bandwidth, symbTimeout, rxContinuousMode ) == true )
{RxSlot = 1;
}

速率偏移处理如下:

datarate = LoRaMacParams.ChannelsDatarate - LoRaMacParams.Rx1DrOffset;
if( datarate < 0 )
{datarate = DR_0;
}

8.默认设置

目前基本各地区的参数都一样,因此协议栈也是直接共用如下参数:

/*!* Class A&B receive delay 1 in ms*/
#define RECEIVE_DELAY1                              1000/*!* Class A&B receive delay 2 in ms*/
#define RECEIVE_DELAY2                              2000/*!* Join accept receive delay 1 in ms*/
#define JOIN_ACCEPT_DELAY1                          5000/*!* Join accept receive delay 2 in ms*/
#define JOIN_ACCEPT_DELAY2                          6000/*!* Class A&B maximum receive window delay in ms*/
#define MAX_RX_WINDOW                               3000/*!* Maximum allowed gap for the FCNT field*/
#define MAX_FCNT_GAP                                16384/*!* ADR acknowledgement counter limit*/
#define ADR_ACK_LIMIT                               64/*!* Number of ADR acknowledgement requests before returning to default datarate*/
#define ADR_ACK_DELAY                               32/*!* Number of seconds after the start of the second reception window without* receiving an acknowledge.* AckTimeout = \ref ACK_TIMEOUT + Random( -\ref ACK_TIMEOUT_RND, \ref ACK_TIMEOUT_RND )*/
#define ACK_TIMEOUT                                 2000/*!* Random number of seconds after the start of the second reception window without* receiving an acknowledge* AckTimeout = \ref ACK_TIMEOUT + Random( -\ref ACK_TIMEOUT_RND, \ref ACK_TIMEOUT_RND )*/
#define ACK_TIMEOUT_RND                             1000

End



http://www.ppmy.cn/news/142109.html

相关文章

联想G470更换SSD

用了10年的老笔记本了&#xff0c;现在卡出翔&#xff0c;换了个ssd&#xff0c;真香&#xff01;&#xff01;清明假期最后一天&#xff0c;折腾了蛮久终于搞定&#xff0c;简单记录下过程。 原笔记本配置 鲁大师检测结果&#xff1a; 电脑型号 联想 Lenovo G470 20078 笔记…

TMS470学习三-最小系统

声明&#xff1a;参考&#xff1a;https://blog.csdn.net/thisway_diy/article/details/115109168?spm1001.2014.3001.5501 参照韦老师的博客和视频路线学习470&#xff0c;同时会借用韦老师博客的内容&#xff0c;非商业目的&#xff0c;仅仅是学习使用。 单片机最小系统是指…

t470键盘拆解_thinkpad t470怎么样?thinkpad t470拆机图解全面评测

说起商务本你会想到什么&#xff1f;对笔记本有一定了解的用户相信脑海中都会冒出ThinkPad这个品牌吧&#xff0c;正如豪华轿车就选奔驰和宝马一样&#xff0c;在商务本的世界里&#xff0c;ThinkPad俨然如商务本的代名词&#xff0c;可靠的品质还有小红点这些经典的设计就是它…

ac远程web管理 r470gp tl_良心升级!TL-R470GP-AC一体化路由也支持无缝漫游了

TP-Link的POE供电 AC一体化路由 + 面板AP设置简单价格合理,是目前市面上卖的最好的AC+面板AP无线wifi全屋覆盖方案,也就是大家所说的TP-Link全家桶。TL-R470GP-AC是TP一体化路由入门型号,虽然TP把它归在企业产品线,但是其实买的最多的还是家用。 TL-R470GP-AC和1750GI-POE…

小黑升级记----记ThinkPad470p加装固态盘

目录 一 缘起 二 拆机 三 配件选择 四 安装 五 系统迁移 六 总结 一 缘起 本着做开发来用的目的&#xff0c;两年前买了ThinkPad T系列的470P。之所以选择ThinkPad&#xff0c;是因为之前R系列的本&#xff0c;用了接近10年&#xff0c;除了USB插口老化&#xff0c;里面…

t460p和t470p对比评测_老模具小升级 ThinkPad T470p商务本评测

老模具小升级 ThinkPad T470p商务本评测 2017年03月29日 05:35作者:孙斌编辑:孙斌文章出处:泡泡网原创 分享 ThinkPad品牌的商务本中,T系列无疑是元老级的存在。主打性能的T系列在去年迎来了硬件大幅度升级的T460p,而今年随着Kabylake处理器的上市,新一代的T470p产品来到…

Ubuntu安装Nvidia470驱动踩坑

实验室有个几年前的服务器&#xff0c;装了GTX 1080Ti显卡。之前我装了NVIDIA最新的470版本驱动&#xff0c;通过 nvidia-smi 命令也可以看到显卡工作情况&#xff0c;因此我以为搞定了。 然而今天打算跑个程序的时候&#xff0c;突然发现Torch报错了&#xff1a; torch._C._c…

Thinkpad T470 内置电池问题

进入BIOS模式&#xff0c;选择F1&#xff0c;找到Power->disable built-in battery选项&#xff0c;选择enter Temporarily disable battery for servicing the system. Afterselecting this item, the system will be automatically powered off, then ready to be servic…