本文來源公衆號【物聯網思考】
本文主要結合LoRaNode SDK v4.4.2和LoRaWAN規範1.0.3來展開。
查看《lorawan_regional_parameters_v1.0.3reva_0.pdf》文檔,每個地區對應的信道都不一樣,在SDK中,不同的地區以不同的文件實現:
查看文檔,CN470頻段,支持96個上行通道,48個下行通道。
國內主要是CN470,因此主要看RegionCN470這個文件。
發送頻率設置
SDK在函數void RegionCN470InitDefaults( InitDefaultsParams_t* params )中初始化信道參數:
void RegionCN470InitDefaults( InitDefaultsParams_t* params )
{
Band_t bands[CN470_MAX_NB_BANDS] =
{
CN470_BAND0
};
switch( params->Type )
{
case INIT_TYPE_INIT:
{
// Initialize bands
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN470_MAX_NB_BANDS );
// Channels
// 125 kHz channels
for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ )//CN470_MAX_NB_CHANNELS是一個宏定義,取值是96
{
NvmCtx.Channels[i].Frequency = 470300000 + i * 200000;
NvmCtx.Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;
NvmCtx.Channels[i].Band = 0;
}
// Initialize the channels default mask
NvmCtx.ChannelsDefaultMask[0] = 0xFFFF;
NvmCtx.ChannelsDefaultMask[1] = 0xFFFF;
NvmCtx.ChannelsDefaultMask[2] = 0xFFFF;
NvmCtx.ChannelsDefaultMask[3] = 0xFFFF;
NvmCtx.ChannelsDefaultMask[4] = 0xFFFF;
NvmCtx.ChannelsDefaultMask[5] = 0xFFFF;
// Update the channels mask
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
break;
}
case INIT_TYPE_RESTORE_CTX:
{
if( params->NvmCtx != 0 )
{
memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) );
}
break;
}
case INIT_TYPE_RESTORE_DEFAULT_CHANNELS:
{
// Restore channels default mask
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
break;
}
default:
{
break;
}
}
}
可以看到,通過for循環給96個信道賦值,從470.3M開始,以200K的步長增加,並且把信道掩碼全部賦值爲0xffff。
其中NvmCtx是一個結構體變量,查看其定義如下:
// Definitions
#define CHANNELS_MASK_SIZE 6
/*!
* Region specific context
*/
typedef struct sRegionCN470NvmCtx
{
/*!
* LoRaMAC channels
*/
ChannelParams_t Channels[ CN470_MAX_NB_CHANNELS ];
/*!
* LoRaMac bands
*/
Band_t Bands[ CN470_MAX_NB_BANDS ];
/*!
* LoRaMac channels mask
*/
uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ];
/*!
* LoRaMac channels default mask
*/
uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ];
}RegionCN470NvmCtx_t;
可以看到,CN470信道掩碼是一個uint16_t的數組,數組有6個元素,16*6=96bit剛好對應96個上行信道,既就是每個信道對應一個bit。在上面初始化的時候,信道通過for循環遍歷,信道掩碼全部設置爲了0xffff,既SDK中默認開啓了所有的信道。
通常情況下LoRaWAN網關(sx1301/2/8)只支持8個上行通道1個下行通道,既只可以同時接收8路數據。因此我們需要修改讓節點只用8個信道上報數據,這8個信道與網關保持一致。
我們參考上面的把不需要的信道頻率設置爲0,或對應的掩碼位置設爲0,剩下的就是我們需要的信道。
假設,我們要設置的8個頻點爲:
uint32_t UserFreq[8]={471900000,472100000,472300000,472500000,472700000,472900000,473100000,473300000};
那麼只需在void RegionCN470InitDefaults( InitDefaultsParams_t* params )函數默認的信道初始化後加入如下代碼:
NvmCtx.ChannelsDefaultMask[0] = 0x0000;
NvmCtx.ChannelsDefaultMask[1] = 0x0000;
NvmCtx.ChannelsDefaultMask[2] = 0x0000;
NvmCtx.ChannelsDefaultMask[3] = 0x0000;
NvmCtx.ChannelsDefaultMask[4] = 0x0000;
NvmCtx.ChannelsDefaultMask[5] = 0x0000;
for( uint8_t i = 0,j=0; i < 8; i++ )
{
j=(UserFreq[i].Frequency-470300000 )/200000;//計算信道號
NvmCtx.Channels[j].Frequency = UserFreq[i].Frequency ;
NvmCtx.Channels[j].DrRange.Value=( DR_5 << 4 ) | DR_0;
NvmCtx.Channels[j].Band = 0;
NvmCtx.ChannelsDefaultMask[j/16]|=1<<(j%16);//相應的信道掩碼位設置爲1
}
// Update the channels mask
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
上面代碼中,最關鍵的兩句話,計算信道號和相應的信道掩碼位設置爲1。
接收頻率設置
還是查看《lorawan_regional_parameters_v1.0.3reva_0.pdf》文檔
可以看出,下行通道rx1等於上行通道號與48取餘,rx2是固定的,默認爲505.3MHZ。
SDK中在函數bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )實現了接收頻率的設置:
bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
{
int8_t dr = rxConfig->Datarate;
uint8_t maxPayload = 0;
int8_t phyDr = 0;
uint32_t frequency = rxConfig->Frequency;
if( Radio.GetStatus( ) != RF_IDLE )
{
return false;
}
if( rxConfig->RxSlot == RX_SLOT_WIN_1 )
{
// Apply window 1 frequency
frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL;
//計算rx1的頻率
}
// Read the physical datarate from the datarates table
phyDr = DataratesCN470[dr];
Radio.SetChannel( frequency );
// Radio configuration
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
if( rxConfig->RepeaterSupport == true )
{
maxPayload = MaxPayloadOfDatarateRepeaterCN470[dr];
}
else
{
maxPayload = MaxPayloadOfDatarateCN470[dr];
}
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
*datarate = (uint8_t) dr;
return true;
}
其中,最重要的一句代碼:
// Apply window 1 frequency
frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL;
//計算rx1的頻率
通過發射信道號,計算rx1的接收信道。可見,如果發射信道固定了,那麼rx1(接收1)的信道也就固定了。
因此,我們在CN470頻段,只需要修改發射信道即可完成發射和接收的設置。
——————END——————
關注公衆號:“物聯網思考”,獲取更多開發資料、經驗。