邁向藍牙 5 網狀網路的捷徑

資料提供者:DigiKey 北美編輯群

有了藍牙 5 支援的網狀網路功能之後,開發人員即能提升無線連線系統 (如 IoT 裝置) 的範圍與網路可用性。然而,網狀網路的低功率無線硬體設計有多層的複雜性,且開發人員在網狀網路軟體開發上可能很快會受困,導致專案延宕。

由於支援藍牙 5 的智慧型手機和其他行動平台的興起,幾乎在每個產業領域和應用中,對藍牙網狀網路功能的需求預期會呈爆炸性成長,開發人員必須對此迅速回應,因此時間成為一個關鍵因素。為此,矽晶和軟體廠商推出了可簡化並加速開發流程的解決方案。

本文將重點說明藍牙網狀網路的基本原理,接著會利用 Silicon Labs 具網狀能力的藍牙 5 模組系列來逐步說明開發流程。運用此類整合式藍牙 5 解決方案,開發人員可迅速佈署能完全利用藍牙網狀網路優勢的連線裝置與應用。

文末將說明 Silicon Labs 藍牙網狀網路軟體開發套件,包括利用範例網狀網路應用程式碼,詳盡檢視所展示的事件驅動型模型。

對藍牙網狀網路的需求

藍牙網狀網路已經超越傳統藍牙技術的點對點連線功能。藍牙網狀網路可透過相鄰且連線的裝置接繼訊息,擴展低功率裝置可有效擴及的範圍,使其超越其發射器功率輸出和接收器靈敏度可達到的實際範圍。最重要的是,越來越多智慧型手機和其他行動裝置支援藍牙應用程式,藍牙網狀網路運用此自然趨勢,達到更精細複雜的網狀網路連線應用。

有了網狀網路的支援,使用藍牙的開發人員如今擁有強大的能力,可在居家自動化、大樓管理以及任意數量的 IoT 應用,輕鬆連接大量裝置。

藍牙網狀網路的運作原理

藍牙網狀網路在網路的節點之間運用一個概念相當簡易的互動模型 (圖 1)。專用的節點類型在節點間提供接繼訊息所需的額外能力,擴大了透過代理節點與支援藍牙的行動裝置互動的網路的有效範圍。

藍牙網狀網路的圖片圖 1:除了基本邊緣節點外,藍牙網狀網路可以使用特殊節點類型來傳遞訊息給其他節點 (接繼)、作為低功率節點的快取 (朋友),或將網路 (代理) 連接到支援藍牙的行動裝置。(圖片來源:Silicon Labs)

其他專用節點類型可滿足降低功率的要求,利用朋友節點來快取低功率節點在長時間睡眠狀態下定期輪詢的訊息。即便有此新增功能,藍牙網狀網路裝置依然能使用泛型屬性設定檔 (GATT) 服務連接至採用較早藍牙版本的舊型裝置。因此,網狀網路裝置可完全運用現有低功率藍牙 (BLE) 能力的優點,例如信標,以產生區域專屬訊息並傳送給智慧型手機,或是針對資產管理應用標識自身。

藍牙網狀網路針對大樓自動化或其他 IoT 應用,能因應其越來越受到重視的網路安全需求。在 BLE 應用中,提供的安全性只可選擇保護單一裝置,藍牙網狀網路則不同,其安全措施會試圖保護整體網狀網路。

藍牙針對網狀網路提供的安全性作法特別有意思。其安全性方案在網狀網路中引進分隔的概念,為每個裝置、網路和整體應用採用個別的安全措施。與各個裝置關連的私人裝置金鑰 (DevKey) 僅為涉及該節點的設定和佈建等作業提供安全性。每個裝置需要一個網路金鑰 (NetKey) 以便與網路或子網路裡的其他節點通訊。最後,在應用層級的互動中 (例如傳送開燈訊息),則需要一個應用金鑰 (AppKey)。其他的安全措施會攔截常見的威脅,例如中間人攻擊或重放攻擊。綜合而言,藍牙網狀網路的安全性機制提供了更複雜 IoT 應用所需的關鍵信任基礎。

儘管如此,實作藍牙網狀網路連線的應用依然為開發人員帶來極大困難。多數採用網狀網路的應用都建構在具有功率限制的裝置上,且需仰賴網狀網路來延伸低功率無線電子系統的有效範圍。即使是經驗豐富的硬體開發人員,在打造合適的網狀網路低功率硬體裝置時,有時也會一籌莫展。就算完成自訂的藍牙設計,為了符合國家認證要求,開發人員可能面臨巨額的成本和時程的延遲。軟體開發人員在尋找相容的藍牙網狀網路堆疊,以便建構可支援自家應用的軟體層時,也會有造成延宕的因素。不過,透過 Silicon Laboratories 的藍牙硬體和軟體,開發人員可在低功率裝置中為自家應用迅速部署藍牙網狀網路功能。

藍牙模組

Silicon Labs 的藍牙網狀網路解決方案建構在其低功率藍牙 BGM13P 硬體模組上,結合一個無線處理器及一個完整的藍牙堆疊,採用 12.9 × 15.0 × 2.2 mm 封裝,提供一個經驗證的完整藍牙系統。EFR32BG13 Blue Gecko 無線系統單晶片 (SoC) 位於模組中心,提供核心功能。EFR32BG13 SoC 結合一個 32 位元 Arm® Cortex®-M4 核心、一個 2.4 GHz 無線電子系統、512 KB 的快閃記憶體、64 KB 的 RAM,以及一個類比與數位周邊裝置的廣泛補強功能。除了晶片上硬體加密加速器外,此 SoC 還可透過一個安全管理單元,支援不斷增加且更為嚴格的安全需求,該單元為周邊裝置提供的粒度存取控制,與記憶體保護單元提供給記憶體的完全一樣。

EFR32BG13 SoC 可作為自訂藍牙硬體設計的基礎。開發人員若採用此 SoC,不但能承擔 SoC 支援電路的設計要求,也能照應已完成設計所需的認證要求。此模組提供完全認證的設計,內含 EFR32BG13 和所需的支援電路,包括數個振盪器源、兩個晶體及連接埠驅動器。同時,此模組提供一系列節能功能,可供開發人員回應低功率裝置的持續要求。

此模組在主動模式下僅消耗 87 µA/MHz,在完全休眠的深度睡眠下,則消耗 1.4 μA。工程師可運用低功率感測器介面和低功率計時器等特點,協助達到最佳的低功率深度睡眠模式時間。採用低功率感測器介面,工程師便能對該模組的整合式有限狀態機和類比周邊裝置進行編程,如此便能在處理器處於深度睡眠模式時,持續獲取並處理感測器訊號。同樣的,低功率計時器可供工程師輸出簡易波形並監控即時時脈/計數器,以便在處理器不參與的情況下,於指定期間執行動作。

毫無疑問,無線裝置的功耗一般都仰賴無線電子系統的效率。在此案例中,該模組的 2.4 GHz 無線電子系統在接收模式下僅消耗 9.9 mA,在 0 dBm 輸出功率的發射模式下,僅消耗 8.5 mA。儘管如此,該模組還能透過 RF 控制提供額外的節能功能。開發人員可在模組內編程 RF 感測功能,藉此在偵測到廣頻 RF 能量時喚醒處理器。藉助這個方法,開發人員可讓模組在無活動期保持深度睡眠,卻不會失去通訊。不過,就如同先前所述,開發人員也能設定裝置,使其如同藍牙 5 低功率節點一般地運作,定期自深度睡眠中醒來,輪詢朋友節點以取得快取訊息。

系統開發

縱使具備以上特點,此模組在實作上幾乎沒有任何困難。開發人員可直接將模組納入包含既有處理器的設計中,作為藍牙網路輔助處理器使用 (圖 2A)。開發人員也可將模組作為一個完整的系統解決方案使用 (圖 2B)。在此獨立模式中,開發人員可在該模組的 EFR32BG13 處理器上執行其應用程式碼,並使用 EFR32BG13 整合的類比與數位周邊裝置,在簡易的 IoT 設計中進行訊號擷取。

Silicon Labs 的 BGM13P 模組作為主機 CPU 的藍牙輔助處理器及獨立使用的圖片圖 2:設計人員可將 BGM13P 模組作為主機 CPU (A) 的藍牙輔助處理器使用,也可獨立使用 (B);善用該模組整合的 EFR32BG13 SoC 執行應用程式,乃至感測器數據採集。(圖片來源:Silicon Labs)

開發人員可進一步使用內建整合式天線的 BGM13P22F512GA-V2 模組簡化其藍牙設計。對於更具有挑戰性的 RF 環境,開發人員在設計中可轉而採用 BGM13P22F512GE-V2,此型號內含 U.FL 連接器,可連接藍牙相容的扁平式塊狀天線,比如 TaoglasFXP74.07.0100A

Silicon Labs 的 SLWSTK6101C 開發套件更免除了此層面的硬體實作。SLWSTK6101C 的設計可針對不同的藍牙裝置,搭配擴充卡使用,是一個具代表性的 IoT 設計。此設計包含了 MacronixMX25R8035F 8 Mbit 快閃記憶體、Sharp MicroelectronicsLS013B7DH03 128 x 128 LCD,以及 Silicon Labs 的 Si7021 溫度與濕度感測器。在此案例中,開發人員插入 SLWRB4306A 無線電路板,將 BGM13P 模組納入 SLWSTK6101C 板中。

除了能夠此設計為生產就緒,此完整的電路板組也是經過實證的的公版設計,供工程師檢驗介接不同裝置 (如隨身碟、LCD 及感測器) 的各種方法。

舉例來說,雖然 8 Mbit 隨身碟和 LCD 是透過 SPI 匯流排連接到模組,但 Si7021 感測器的 I2C 介面是與開發板上的外接排針座共用匯流排。Silicon Labs 展示了一個用於設計簡易介面的方法,可讓感測器平時都保持在停用狀態,且與該共用匯流排保持電氣隔離。當模組的 PD15 輸入升高時,SENSOR_ENABLE 輸出會隨之升高,將感測器連接到 3.3 V VMCU 電源軌以及 I2C 匯流排 (圖 3)。

Silicon Labs Si7021 感測器的圖片圖 3:除了作為硬體評估平台,Silicon Labs 的 SLWSTK6101C 開發套件也能用作公版設計。圖示說明與外部裝置 (如此處所示之 Silicon Labs 的 Si7021 感測器) 進行介接的方法。(圖片來源:Silicon Labs)

共用的 I2C 匯流排排針座僅是此平台可用於支援開發工作的數個特點之一 (圖 4)。除了板載的 J-Link 除錯器,該板還提供一個封包追蹤介面 (PTI),可讓工程師詳盡地分析封包。PTI 建構在一個封包與狀態追蹤單元上,內建於 EFR32BG13 SoC 中,能夠以非侵入方式捕捉系統傳送與接收的所有封包。若要分析藍牙網狀網路等複雜的協定,此封包追蹤能力可提供一個對最佳化與微調低層級網路通訊的關鍵工具。

Silicon Labs SLWSTK6101C 套件的圖片圖 4:Silicon Labs 的 SLWSTK6101C 套件提供多重介面,可用於封包追蹤、能源監控,以及低層級 Arm 嵌入式追蹤微單元 (ETM) 的追蹤。該套件提供豐富的工具組,可讓工程師深入分析設計運作與效能。(圖片來源:Silicon Labs)

網路專家需要 PTI 等能力來達到網路最佳化,系統開發人員也需要一些工具來協助辨識應用效率不彰的情況,以避免導致耗電過度。Silicon Labs 的 Simplicity Studio Energy Profiler 工具針對此類應用層級功耗最佳化,提供程式碼層級的功耗分析。

如同 Packet Trace 工具,Energy Profiler 妥善運用底層硬體。在此情況下,此電路板包含了一個專屬的能源監控電路,內有一個電流感測器電阻、一個電流感測放大器,以及增益級,可將其輸出傳送至電路板的控制器,讓開發主機系統存取 (圖 5)。平行增益級可讓能源監控器以兩種不同解析度層級測量介於 0.1 μA 到 95 mA 的電流:解析度為 0.1 mA 時,高於 250 μA;解析度為 1 μA 時,低於 250 μA 閾值。

Silicon Labs 的 BGM13P 藍牙模組的圖片圖 5:BGM13P 藍牙模組內建專屬的能源監控電路和處理控制器,可提供從 0.1 μA 到 95 mA 的非侵入性電流測量值。(圖片來源:Silicon Labs)

當能源監控電路產生電流測量值時,內建於 EFR32BG13 的低階追蹤機制可定期為處理器的程式計數器採樣,並將結果輸出到裝置的序列電線輸出引腳。藉由合併能源監控以及此程式追蹤輸出的結果,Energy Profiler 可即時顯示與裝置上執行之程式碼相關連的能源消耗 (圖 6)。

Silicon Labs Simplicity Studio Energy Profiler 的圖片圖 6:Simplicity Studio Energy Profiler 將能源監控輸出與程式追蹤資料合併,即時顯示與實際程式碼相關連的電流消耗。(圖片來源:Silicon Labs)

網狀網路應用開發

硬體工程師可利用開發套件來最佳化硬體設計,軟體開發人員也能善用 Silicon Labs 的全面性軟體開發環境,快速建立網狀網路應用。Silicon Labs 的藍牙 5 網狀網路堆疊隨附 Simplicity Studio,可使用特定網狀網路資源擴充基本的藍牙堆疊。因此,開發人員能夠從較傳統的藍牙協定 (如信標或點對點通訊) 輕鬆移轉到完全網狀網路拓撲 (圖 7)。

Silicon Labs 藍牙網狀網路堆疊的圖片圖 7:Silicon Labs 藍牙網狀網路堆疊可透過網狀網路層 (綠色) 擴充較早期的藍牙功能 (藍色),讓開發人員得以善加運用從信標到完全網狀網路設定的完整藍牙功能。(圖片來源:Silicon Labs)

Simplicity Studio 搭配 Silicon Labs 的 BGM13P 架構 SLWRB4306A 與 SLWSTK6101C 開發板使用,可讓開發人員以合適的軟體開發套件 (SDK) 設定其環境。以藍牙開發來說,Studio 提供了 Silicon Labs 的藍牙網狀網路 SDK,外加預先建構的示範二進位與原始程式碼。在此環境中,開發人員可使用範例程式碼,實作完整藍牙網狀網路應用。

範例應用專門設計用來展示藍牙網狀網路的運作,因此可搭配開發板和行動應用程式,帶領開發人員完成典型的網狀網路運作,包括佈建、設定以及與應用相關的使用。工程師針對一組個別設定在連線照明應用中,作為燈或開關的開發板執行 Simplicity Studio,以部署範例應用。工程師透過使用範例程式碼和硬體,即可從中深入瞭解在典型網狀應用下,裝置從開機開始的各個作業階段。

藍牙採用 Silicon Labs 的軟體架構,透過使用可表示事件本質的預先定義事件 ID,以一系列事件的形式進行操作。在範例軟體套件中,開機或重置時執行的 main() 常式會在進入其主要迴路前,呼叫一系列的初始化常式,此情形下僅包含兩行程式碼 (清單 1)。

Copy
int main()
{
#ifdef FEATURE_SPI_FLASH
  /* Put the SPI flash into Deep Power Down mode for those radio boards where it is available */
  MX25_init();
  MX25_DP();
  /* We must disable SPI communication */
  USART_Reset(USART1);

#endif /* FEATURE_SPI_FLASH */

  enter_DefaultMode_from_RESET();

#if (EMBER_AF_BOARD_TYPE == BRD4304A)
  LNA_init();
#endif

  gecko_init(&config);

#ifdef FEATURE_PTI_SUPPORT
  APP_ConfigEnablePti();
#endif // FEATURE_PTI_SUPPORT

  RETARGET_SerialInit();

  /* initialize LEDs and buttons.Note: some radio boards share the same GPIO for button & LED.* Initialization is done in this order so that default configuration will be button for those
   * radio boards with shared pins.led_init() is called later as needed to (re)initialize the LEDs
   * */
  led_init();
  button_init();

  LCD_init();

  while (1) {
    struct gecko_cmd_packet *evt = gecko_wait_event();
    handle_gecko_event(BGLIB_MSG_ID(evt->header), evt);
  }
}

清單 1:Simplicity Studio 提供完整的開發環境,包括類似此網狀網路照明主要常式的範例程式碼,可展示事件處理的初始化和迴路。(程式碼來源:Silicon Labs)

在主要迴路的第一行中,函數 gecko_wait_event() 會封鎖,等待事件出現在由低層級填入的事件佇列中。雖然開發人員通常會避免封鎖函數,但在此情況下,這個方法特別有效,因為在封鎖函數模式中,藍牙堆疊會自動管理低耗電的睡眠狀態。針對無法容忍封鎖等待的特定應用要求,SDK 亦提供非封鎖函數,在佇列為空時,會傳回下一個事件或 NULL。但是藉著此函數,開發人員則需自行處理低耗電睡眠管理。

在主要迴路的第二行中,處置器函數 handle_gecko_event() 會依照事件 ID (清單 2) 處理最新事件 (evt)。裝置啟動時,該堆疊會發出系統啟動事件 (gecko_evt_system_boot_id)。事件處理器進而會呼叫一系列初始化函數,包括可將藍牙網狀網路堆疊初始化的 gecko_cmd_mesh_node_init()。之後,處理器會呼叫其他函數,以提供與該事件類型相關的功能 (事件類型由其關聯的事件 ID 代表)。

Copy
/**
 * Handling of stack events.Both Bluetooth LE and Bluetooth mesh events are handled here.*/
static void handle_gecko_event(uint32_t evt_id, struct gecko_cmd_packet *evt)
{
  struct gecko_bgapi_mesh_node_cmd_packet *node_evt;
  struct gecko_bgapi_mesh_generic_server_cmd_packet *server_evt;
  struct gecko_msg_mesh_node_provisioning_failed_evt_t  *prov_fail_evt;

  if (NULL == evt) {
    return;
  }

  switch (evt_id) {
    case gecko_evt_system_boot_id: 
      // check pushbutton state at startup.If either PB0 or PB1 is held down then do factory reset
      if (GPIO_PinInGet(BSP_GPIO_PB0_PORT, BSP_GPIO_PB0_PIN) == 0 || GPIO_PinInGet(BSP_GPIO_PB1_PORT, BSP_GPIO_PB1_PIN) == 0) {
        initiate_factory_reset();
      } else {
        struct gecko_msg_system_get_bt_address_rsp_t *pAddr = gecko_cmd_system_get_bt_address();

        set_device_name(&pAddr->address);

        // Initialize Mesh stack in Node operation mode, wait for initialized event
        gecko_cmd_mesh_node_init();

        // re-initialize LEDs (needed for those radio board that share same GPIO for button/LED)
        led_init();
      }
      break;
      ...case gecko_evt_mesh_node_initialized_id: 
      printf(node initialized\r\n);

      struct gecko_msg_mesh_node_initialized_evt_t *pData = (struct gecko_msg_mesh_node_initialized_evt_t *)&(evt->data);

      if (pData->provisioned) {
      ...} else {
        printf(node is unprovisioned\r\n);
        LCD_write(unprovisioned, LCD_ROW_STATUS);

        printf(starting unprovisioned beaconing...\r\n);
        gecko_cmd_mesh_node_start_unprov_beaconing(0x3);   // enable ADV and GATT provisioning bearer
      }
      break;

    case gecko_evt_mesh_node_provisioning_started_id: 
      printf(Started provisioning\r\n);
      LCD_write(provisioning..., LCD_ROW_STATUS);
      // start timer for blinking LEDs to indicate which node is being provisioned
      gecko_cmd_hardware_set_soft_timer(32768 / 4, TIMER_ID_PROVISIONING, 0);
      break;

    case gecko_evt_mesh_node_provisioned_id: 
      _my_index = 0;   // index of primary element hardcoded to zero in this example
      lightbulb_state_init();
      printf(node provisioned, got index=%x\r\n, _my_index);
      // stop LED blinking when provisioning complete
      gecko_cmd_hardware_set_soft_timer(0, TIMER_ID_PROVISIONING, 0);
      LED_set_state(LED_STATE_OFF);
      LCD_write(provisioned, LCD_ROW_STATUS);
      break;

    case gecko_evt_mesh_node_provisioning_failed_id: 
      prov_fail_evt = (struct gecko_msg_mesh_node_provisioning_failed_evt_t  *)&(evt->data);
      printf(provisioning failed, code %x\r\n, prov_fail_evt->result);
      LCD_write(prov failed, LCD_ROW_STATUS);
      /* start a one-shot timer that will trigger soft reset after small delay */
      gecko_cmd_hardware_set_soft_timer(2 * 32768, TIMER_ID_RESTART, 1);
      break;
      ...}
}

清單 2:開發人員可以檢查 Silicon Labs 網狀網路範例程式碼中的關鍵設計模式,例如,佈建事件處理,相關程式碼片段位於網狀網路照明主要常式中呼叫的 handle_gecko_event() 事件處理器常式 (請參見清單 1)。(程式碼來源:Silicon Labs)

藍牙網狀網路中的其中一系列關鍵事件與佈建過程有關。在裝置啟動並完成其初始化序列後,裝置將進入信標模式,自行向網路發出佈建的通知。當佈建繼續進行直至完成 (或失敗) 時,範例程式碼使用開發套件 LCD 和 LED 來提供狀態。藉由檢查事件處理器程式碼區塊以瞭解各個佈建狀態,開發人員可以快速瞭解此佈建順序和選項。

同樣地,軟體工程師可以利用範例程式碼作為建立其應用層級功能的指南。例如,藍牙網狀網路中的關鍵概念是使用「發佈-訂閱」模式,將共享某些功能關係的節點關連起來 (圖 8)。

藍牙「發佈-訂閱」模式的圖片圖 8:應用開發人員使用藍牙的「發佈-訂閱」模式,將裝置組成多個功能分組,例如一組由一個或多個開關控制的燈。(圖片來源:Silicon Labs)

利用這個方法,幾個智慧型燈泡可訂閱單一開關發佈器。當最終用戶啟用開關時,開關會發佈 ON/OFF 事件。該事件將透過網狀網路串接到訂閱的智慧型燈泡,而燈泡的事件處理器將採取適當行動。Silicon Labs 範例程式碼即說明了這一流程。首先使用在網狀網路連接開關中發佈的開/關要求 (清單 3),然後使用在連接的燈中之相對應回應 (清單 4)。

Copy
/**
 * This function publishes one on/off request to change the state of light(s) in the group.* Global variable switch_pos holds the latest desired light state, possible values are
 * switch_pos = 1 -> PB1 was pressed, turn lights on
 * switch_pos = 0 -> PB0 was pressed, turn lights off
 *
 * This application sends multiple requests for each button press to improve reliability.* Parameter retrans indicates whether this is the first request or a re-transmission.* The transaction ID is not incremented in case of a re-transmission.*/
void send_onoff_request(int retrans)
{
  uint16 resp;
  uint16 delay;
  struct mesh_generic_request req;

  req.kind = mesh_generic_request_on_off;
  req.on_off = switch_pos ?MESH_GENERIC_ON_OFF_STATE_ON : MESH_GENERIC_ON_OFF_STATE_OFF;

  // increment transaction ID for each request, unless it's a retransmission
  if (retrans == 0) {
    trid++;
  }

  /* delay for the request is calculated so that the last request will have a zero delay and each
   * of the previous request have delay that increases in 50 ms steps.For example, when using three
   * on/off requests per button press the delays are set as 100, 50, 0 ms
   */
  delay = (request_count - 1) * 50;

  resp = gecko_cmd_mesh_generic_client_publish(
    MESH_GENERIC_ON_OFF_CLIENT_MODEL_ID,
    _my_index,
    trid,
    0,     // transition
    delay,
    0,     // flags
    mesh_generic_request_on_off,     // type
    1,     // param len
    &req.on_off     /// parameters data
    )->result;

  if (resp) {
    printf(gecko_cmd_mesh_generic_client_publish failed,code %x\r\n, resp);
  } else {
    printf(request sent, trid = %u, delay = %d\r\n, trid, delay);
  }
}

清單 3:Silicon Labs 網狀網路開關範例應用的程式碼片段,可說明藍牙 5 發佈過程 (gecko_cmd_mesh_generic_client_publish) 如何在要求訂閱此事件串流之燈的狀態 (開或關) 變化使用。(程式碼來源:Silicon Labs)

Copy
static void onoff_request(uint16_t model_id,
                          uint16_t element_index,
                          uint16_t client_addr,
                          uint16_t server_addr,
                          uint16_t appkey_index,
                          const struct mesh_generic_request *request,
                          uint32_t transition_ms,
                          uint16_t delay_ms,
                          uint8_t request_flags)
{
  printf(ON/OFF request: requested state=<%s>, transition=%u, delay=%u\r\n,
         request->on_off ?ON : OFF, transition_ms, delay_ms);

  if (lightbulb_state.onoff_current == request->on_off) {
    printf(Request for current state received; no op\n);
  } else {
    printf(Turning lightbulb <%s>\r\n, request->on_off ?ON : OFF);
    if (transition_ms == 0 && delay_ms == 0) { // Immediate change
      lightbulb_state.onoff_current = request->on_off;
      lightbulb_state.onoff_target = request->on_off;
      if (lightbulb_state.onoff_current == MESH_GENERIC_ON_OFF_STATE_OFF) {
        LED_set_state(LED_STATE_OFF);
      } else {
        LED_set_state(LED_STATE_ON);
      }
    } else {
      // Current state remains as is for now
      lightbulb_state.onoff_target = request->on_off;
      LED_set_state(LED_STATE_TRANS); // set LEDs to transition mode
      gecko_cmd_hardware_set_soft_timer(TIMER_MS_2_TIMERTICK(delay_ms + transition_ms), TIMER_ID_TRANSITION, 1);
    }
    lightbulb_state_store();
  }

  if (request_flags & MESH_REQUEST_FLAG_RESPONSE_REQUIRED) {
    onoff_response(element_index, client_addr, appkey_index);
  } else {
    onoff_update(element_index);
  }
}

清單 4:Silicon Labs 網狀網路照明範例包含適用特定應用層級事件的常式,例如用於回應開關已發佈的要求而開啟或關閉 LED 的函數 (請參見清單 3)。(程式碼來源:Silicon Labs)

除了藍牙堆疊和用於開發節點的 SDK 之外,Silicon Labs 還提供讓藍牙網狀網路完備的最後一部分,亦即與行動裝置的連線。多數行動裝置支援藍牙 4,雖然其無線電功能可以支援藍牙 5 要求,但卻無法支援藍牙 5 網狀網路層級內的堆疊。Silicon Labs 為行動應用程式開發人員提供可支援網狀網路功能的其他軟體堆疊 (圖 9),進而解決了這一限制。

Silicon Labs 網狀網路堆疊的圖片圖 9:開發人員可將 Silicon Labs 的行動裝置網狀網路堆疊新增至其行動應用程式中,進而在藍牙 5 網狀網路中支援藍牙 4 行動裝置的使用。(圖片來源:Silicon Labs)

結論

對於已利用智慧型手機和其他行動裝置進行點對點通訊的眾多應用,藍牙 5 網狀網路可提供一種相當自然的過渡轉換。然而,藍牙 5 網狀網路的部署在硬體和軟體設計方面面臨重大挑戰,特別是具有功耗限制的應用 (如 IoT)。此外,硬體工程師必須達成最小覆蓋區和低功率的要求;軟體工程師則需要打造使用最少資源即可執行複雜通訊協議的軟體。透過結合 BGM13P 模組、SLWSTK6101C 開發板,以及適合節點和行動裝置的藍牙堆疊,工程師即具備一個可使用藍牙網狀網路快速開發應用的完整平台。

 
DigiKey logo

聲明:各作者及/或論壇參與者於本網站所發表之意見、理念和觀點,概不反映 DigiKey 的意見、理念和觀點,亦非 DigiKey 的正式原則。

關於出版者

DigiKey 北美編輯群