天天看點

LoRa開發7:PingPong系統

PingPong系統

1 引言

前2章介紹了SX1278的發送和接收,在此基礎上,我們設計一個有趣的PingPong系統,更好地了解LoRa終端的收發邏輯。

該系統将LoRa終端自動定義成2種角色:master和slave。master主動發送ping資料幀,接收pong資料幀;slave如果接收到ping資料幀,回應pong資料幀。

2 整體邏輯流程

LoRa開發7:PingPong系統

如上圖所示,當LoRa終端上電後,在(2 * PingPongPeriod)周期内沒有接收到ping資料幀,它就認為自己是master。Master節點每隔(1 * PingPongPeriod)周期主動發送ping資料幀,然後啟動RF接收,可能接收到pong回應幀(正常通信),也可能接收逾時(slave沒有上電或通信失敗)。

LoRa開發7:PingPong系統

同理,當LoRa終端上電後,在(2 * PingPongPeriod)周期内接收到ping資料幀,它就認為自己是slave。Slave節點啟動RF接收,如果接收到ping資料幀,它将發送pong回應幀。

一個節點從上電,判斷自身角色,根據角色處理邏輯,如下流程圖所示。

LoRa開發7:PingPong系統

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回應幀完畢;

繼續閱讀