PingPong系統
1 引言
前2章介紹了SX1278的發送和接收,在此基礎上,我們設計一個有趣的PingPong系統,更好地了解LoRa終端的收發邏輯。
該系統将LoRa終端自動定義成2種角色:master和slave。master主動發送ping資料幀,接收pong資料幀;slave如果接收到ping資料幀,回應pong資料幀。
2 整體邏輯流程
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISM3gjMycDN2EDOxATM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
如上圖所示,當LoRa終端上電後,在(2 * PingPongPeriod)周期内沒有接收到ping資料幀,它就認為自己是master。Master節點每隔(1 * PingPongPeriod)周期主動發送ping資料幀,然後啟動RF接收,可能接收到pong回應幀(正常通信),也可能接收逾時(slave沒有上電或通信失敗)。
同理,當LoRa終端上電後,在(2 * PingPongPeriod)周期内接收到ping資料幀,它就認為自己是slave。Slave節點啟動RF接收,如果接收到ping資料幀,它将發送pong回應幀。
一個節點從上電,判斷自身角色,根據角色處理邏輯,如下流程圖所示。
3 代碼剖析
PROCESS_THREAD(PingPong, ev, data)
{
#definePING "ping, this is MASTER ofrime node."
#definePONG "pong, this is SLAVE of rimenode."
#definePING_SIZE 34
#definePONG_SIZE 33
staticbool s_bIsMaster;
staticuint16_t s_wPingPongPeriod;
staticint32_t s_lTxCnt = 0;
staticint32_t s_lRxCnt = 0;
PROCESS_BEGIN();
InitSetLoRa();
s_wPingPongPeriod =
SX1278GetTimeOnAir(4) + SX1278GetTimeOnAir(4) + 15; 1
SX1278Receive(2 * s_wPingPongPeriod); 2
PROCESS_YIELD(); 3
SX1278SetSleep(); 4
if(GetCompareRxFrame(PING, PING_SIZE)) 5
{
s_bIsMaster = FALSE;
}
else
{
s_bIsMaster = TRUE;
}
if(s_bIsMaster)
{
while (1)
{
++s_lTxCnt;
SX1278Send(PING, PING_SIZE); 6
PROCESS_YIELD_UNTIL( (RF_Tx_Done == s_tRFResult) ||
(RF_Tx_Timeout ==s_tRFResult) ); 7
SX1278Receive(s_wPingPongPeriod); 8
PROCESS_YIELD();
SX1278SetSleep();
if (GetCompareRxFrame(PONG, PONG_SIZE)) 9
{
++s_lRxCnt;
RIME_DBG( RIME_DBG_ON,
"TxCnt=%ld, Rx Cnt=%ld, SNR=%d, RSSI=%d.\r\n",
s_lTxCnt, s_lRxCnt, s_chPacketSnr,s_nPacketRssi ); 10
}
}
}
else
{
while (1)
{
SX1278Receive(0); 11
PROCESS_YIELD();
SX1278SetSleep();
if (GetCompareRxFrame(PING, PING_SIZE)) 12
{
++s_lTxCnt;
SX1278Send(PONG, PONG_SIZE); 13
PROCESS_YIELD_UNTIL( (RF_Tx_Done ==s_tRFResult) ||
(RF_Tx_Timeout == s_tRFResult) ); 14
++s_lRxCnt;
RIME_DBG( RIME_DBG_ON,
"Tx Cnt=%ld, RxCnt=%ld, SNR=%d, RSSI=%d.\r\n",
s_lTxCnt, s_lRxCnt,s_chPacketSnr, s_nPacketRssi );
}
}
}
PROCESS_END();
}
Line#1:計算PingPong通信空中時間,添加15ms做為收發準備時間;
Line#2:啟動接收功能,逾時時長為2倍PingPong通信空中時間;
Line#3:阻塞程序,直到接收資料幀或逾時;
Line#4:設定SX1278為休眠,否則它将處于持續接收狀态(那怕逾時亦如此);
Line#5:GetCompareRxFrame()複制資料幀到解析工作區,比較是否為ping幀;
Master節點邏輯
Line#6:master節點發送ping資料幀;
Line#7:阻塞程序,直到發送ping資料幀完畢;
Line#8:啟動接收功能,逾時時長為PingPong通信空中時間;
Line#9:比較是否為pong回應幀;
Line#10:列印發送和接收資料幀個數,SNR和RSSI值;
Slave節點邏輯
Line#11:啟動持續接收功能,為0表明關閉逾時功能;
Line#12:比較是否為ping資料幀;
Line#13:slave節點發送pong回應幀;
Line#14:阻塞程序,直到發送pong回應幀完畢;