在資源受限的無線終端設備中,如何實現高效、穩定的BLE通信是開發關鍵。LuatOS憑借其低內存占用、高可擴展性與腳本化開發優勢,成為眾多開發者構建BLE應用的首選平臺。本文面向初學者與中級開發者,全面介紹LuatOS中BLE模塊的基礎知識,涵蓋角色定義(主機/從機)、服務配置、特征值操作與事件回調機制,并通過一個完整的溫濕度數據上報案例,逐步演示應用開發全過程。
一、BLE總體介紹
1.1 什么是BLE(Bluetooth Low Energe)?
藍牙低功耗,通常縮寫為 BLE,是藍牙技術聯盟設計的一種個人區域網絡技術,旨在提供顯著降低的功耗、成本和復雜性,同時保持可比的通信范圍。
與傳統經典藍牙相比,BLE并非專注于傳輸高數據量的內容(如音頻流、大文件),而是為間歇性、小數據量的傳輸應用而優化。這使得它非常適合那些需要長時間運行在紐扣電池或小型電池上的設備。
應用場景舉例:
經典藍牙:
1、藍牙耳機/音箱
場景:你用無線耳機聽音樂、看視頻、打電話。
為什么是經典藍牙:因為音頻流需要持續、高速、低延遲的傳輸,才能保證聲音連貫不卡頓。
2、車載藍牙系統
場景:你一上車,手機就自動連接到汽車,可以播放手機里的音樂,或者進行免提通話。
為什么是經典藍牙:和耳機一樣,傳輸的是實時的音頻流,對穩定性和速度要求高。
3、藍牙文件傳輸
場景:兩個人之間不用網絡,直接通過手機“藍牙”功能分享照片、視頻或文檔。
為什么是經典藍牙:傳輸的文件可能比較大,需要較高的傳輸速率。
4、無線鍵盤、鼠標和手柄
場景:連接電腦的無線鍵盤鼠標,或者連接手機/游戲機的藍牙游戲手柄。
為什么是經典藍牙:雖然數據量不大,但它們需要保持持續連接和極低的延遲,以確保你每次按鍵、移動鼠標或操作手柄的指令都能被即時響應。
低功耗藍牙BLE:
1、共享單車開鎖
場景:你用手機App掃碼后,單車鎖“滴”一聲就打開了。
為什么是BLE:開鎖過程只需要手機向車鎖發送一個極小的加密指令包,傳輸瞬間完成,車鎖的電池需要支撐數月。
2、智能手環/手表
場景:你的小米手環或Apple Watch記錄了你一天的步數、心率和睡眠數據。
為什么是BLE:設備本身通過小型電池供電,需要續航數周。它持續采集你的健康數據(小數據包),只在當你打開手機App同步時,才通過BLE將積攢的數據批量發送到手機上。
3、藍牙防丟器
場景:你把一個Tile或AirTag掛在鑰匙上,當鑰匙找不到時,用手機讓防丟器發出聲音。
為什么是BLE:防丟器絕大部分時間處于待機狀態。當你“尋找”它時,手機通過BLE發送一個指令喚醒它,它再回應一個信號。這種間歇性工作模式讓它的紐扣電池能用一年多。
場景:家里的溫濕度計、門窗傳感器、智能燈泡。
為什么是BLE:溫度傳感器每隔幾分鐘才上報一次數據(幾個字節);門窗傳感器只有在開/關狀態變化時才發送信號。它們都由電池供電,需要BLE的低功耗特性來保證較長的續航。
1.2 BLE的發展歷史
BLE的發展與藍牙技術的整體演進緊密相連。其歷史可以看作是為了滿足物聯網需求而專門開辟和不斷優化的一條技術路徑。
1、1998-2010:前BLE時代(經典藍牙主導)
說明:經典藍牙(Bluetooth Classic)專注于連續數據流應用,如音頻和文件傳輸。功耗較高,不適合物聯網傳感器。
2、2010:革命性的起點 - 藍牙4.0
說明:藍牙4.0核心規范發布,首次引入了“藍牙低功耗”技術。這是一個里程碑,它創建了兩種并行的技術:經典藍牙和藍牙低功耗。藍牙4.0芯片分為三種類型:
單模:僅支持BLE。
雙模:同時支持經典藍牙和BLE。
經典:僅支持經典藍牙。
影響:催生了第一批真正的低功耗物聯網設備,如心率帶、智能標簽等。
3、2013:同互聯網融合 - 藍牙4.1
說明:藍牙與互聯網無縫銜接,推動智能家居發展。
支持IPv6直接聯網
設備可同時作為主/從機
單包容量23字節(廣播包仍31字節)
4、2014:速度與連接的提升 - 藍牙4.2
說明:此版本帶來了關鍵改進:
數據傳輸速度提升:將發送數據包長度擴展,單包容量255字節,提升數據傳輸速度。
隱私與安全增強:提供了更強大的加密和隱私保護。
5、2016:物聯網的基石 - 藍牙5.0

說明:這是針對物聯網的一次巨大飛躍,主要特性包括:
BLE速度翻倍至2 Mbps,是BLE 4.2的兩倍
理論距離240米(室外)
Mesh網絡支持
6、2019-2020:專注定向與高精度 - 藍牙5.1 & 5.2
說明:
藍牙5.1:引入了尋向功能,通過測量信號相位,可以實現厘米級精度的室內定位,解決了“在哪里”的問題。
藍牙5.2:引入了LE Audio的核心——低功耗同步信道,為下一代藍牙音頻奠定了基礎,同時提升了多設備連接效率和功耗控制。
7、2021-2023:音頻革命與未來 - 藍牙5.3 & 5.4
說明:
持續優化:藍牙5.3/5.4進一步優化了連接穩定性、延遲和安全性。
LE Audio:基于藍牙5.2及更高版本,它使用全新的LC3編碼器,在更低功耗下提供更高質量的音頻,并支持廣播音頻(如助聽器、多人共享音頻)等創新應用。
Mesh網絡:雖然規范更早推出,但正隨著BLE的普及而廣泛應用,允許成千上萬個設備組成一個龐大的網絡,用于智能樓宇、工業控制等場景。
8、2024: 藍牙6.0
說明:
引入Bluetooth Channel Sounding,通過RTT(round-trip time) 和 PBR(phase-based ranging)技術(類似蘋果的UWB),能夠準確測量藍牙設備間的物理距離。
二、BLE協議棧介紹
在開始講LuatOS的BLE之前,先大概了解下BLE的協議棧。
2.1 BLE低功耗協議棧介紹

BLE協議棧主要用來對你的應用數據進行層層封包,以生成一個滿足BLE協議的空中數據包。也就是說,把應用數據包裹在一系列的幀頭(header)和幀尾(tail)中。
藍牙協議規定了兩個層次的協議,分別是:
(1)藍牙核心協議(Bluetooth Core)
這是藍牙技術的基礎,規定了從無線電波收發到數據鏈路管理的所有底層技術細節。它確保了不同廠商設備之間的基本互聯互通。核心協議層通常又分為控制器(Controller) 和主機(Host) 兩個子部分。
(2)藍牙應用層協議(Bluetooth Application)
建立在核心協議之上,定義了如何利用核心協議來實現具體的功能和服務。例如,心率監測、血壓計、鍵盤鼠標等具體應用場景的規范。
2.2 BLE低功耗藍牙核心協議層詳解(Bluetooth Core)
2.2.1 物理層(PHY)
PHY層用來指定BLE所用的無線頻段,調制解調方式和方法等。
藍牙工作在2.4GHz的頻段,具體的頻段范圍是2400MHz到2483.5MHz,頻段寬度為83.5MHz。BLE將這83.5MHz的寬度分成了0到39共40個通道,每一個通道寬度為2MHz。
下面我們看下藍牙的波形圖:

其中廣播通道為37/38/39,對應的中心頻率分別為2402MHz,2426MHz,2480MHz。BLE在廣播的時候會輪流使用這3個廣播通道進行廣播。
數據通道為0-36,專門用于在設備連接建立之后,傳輸用戶數據和命令。
從圖中可以看到BLE的3個廣播通道并不是連續的,這三個信道和藍牙廣播關系密切,用于設備被發現。
為什么不是連續的?
這就需要看下wifi的信道劃分了,wifi同樣也是工作在2.4GHz頻段下,如果BLE處理不當,自然會被wifi影響。
下面我們來詳細分析Wi-Fi如何影響BLE,以及BLE的應對策略。

Wi-Fi 對BLE的影響機制
根本原因在于頻段重疊:
BLE: 工作在 2.400 - 2.4835 GHz,使用 40 個 2MHz 寬的信道。
Wi-Fi(2.4GHz): 同樣工作在 2.412 - 2.472 GHz(通常),使用 20MHz 或 40MHz 寬的信道。
可以想象一下,Wi-Fi的一個信道就像一條寬闊的八車道高速公路,而BLE的一個信道就像是其中的一條自行車道。當Wi-Fi這條高速公路車流繁忙時,自然會影響到在旁邊自行車道上行駛的BLE。
具體來說:
1、物理信道重疊:
Wi-Fi的1, 6, 11這三個最常用的非重疊信道,會覆蓋一大片BLE的信道。
例如,Wi-Fi信道1(中心頻率2.412 GHz)會干擾BLE的數據信道0到10。
Wi-Fi信道6(中心頻率2.437 GHz)會干擾BLE中間部分的數據信道。
Wi-Fi信道11(中心頻率2.462 GHz)會干擾BLE的數據信道22到36。
2、影響類型:
數據包丟失: BLE數據包在傳輸過程中被Wi-Fi信號淹沒,導致接收端無法正確解碼。
連接中斷: 如果數據包持續丟失,可能導致連接超時而斷開。
廣播受阻: 設備更難被發現或連接,因為廣播信道(特別是38)可能被干擾。
功耗增加: 為了補償丟失的數據包,設備需要更頻繁地重傳數據,從而增加了功耗。
BLE的應對策略(為什么影響通常不大)
1、自適應跳頻【藍牙跳頻(Frequency Hopping)技術)】
藍牙技術使用跳頻擴頻(FHSS)來避免干擾和多徑衰減。跳頻是指藍牙設備在通信過程中,按照一定的序列在不同的信道之間快速切換。這樣,即使某個信道受到干擾,也可以在其他信道上繼續通信,從而保證整體的通信質量。
這是BLE對抗Wi-Fi干擾的方式。在連接狀態下,BLE主從設備會在37個數據信道上快速切換。
它們會持續監測每個信道的通信質量。如果一個信道(比如被Wi-Fi信道6占據的區域)頻繁出錯,系統會將其標記為“壞信道”,并在未來的跳頻序列中自動避開。
這樣,即使有40%的信道被Wi-Fi干擾,通信依然可以通過剩下60%的干凈信道可靠進行。
2、廣播信道的巧妙設計
BLE的3個廣播信道(37, 38, 39)被特意安排在2.4GHz頻段的兩端和正中間。
這個設計就是為了最大化地避開Wi-Fi最常用的1、6、11信道。 - 信道37(2402MHz): 在Wi-Fi信道1的左側,基本安全。 - 信道39(2480MHz): 在Wi-Fi信道11的右側,基本安全。 - 信道38(2426MHz): 位于Wi-Fi信道1和6之間,是最容易受到干擾的廣播信道。
廣播時,設備會在三個信道上都發送數據,只要有一個被手機接收到,連接就能建立。這大大提高了在干擾環境下的發現概率。
2.2.2 鏈路層(LL)
LL 位于物理層(PHY)之上,主機控制器接口(HCI)之下,是 BLE 協議棧中負責報文組裝/拆解、時序控制、信道管理、狀態機切換、安全加密等的核心模塊。
鏈路層定義了兩個設備如何利用無線電傳輸信息。它包含了報文、廣播、數據信道的詳細定義,也規定了發現其他設備的流程、廣播的數據、連接的建立、連接的管理以及連接中的數據傳輸。
LL層只負責把數據發出去或者收回來,對數據進行怎樣的解析則交給上面的GAP或者ATT。
LL層收到的數據,主要交給 ATT 進行解析,以服務于 GATT 定義的應用邏輯。而 GAP 主要處理LL層上報的連接和廣播狀態事件,而非解析具體的數據內容。
主要功能:
廣播與掃描:支撐無連接的廣播通信。
建立與維護連接:完成從掃描→發起→連接確認的流程,并維護連接事件。
數據交換:基于信道跳頻機制可靠傳輸 ACL 數據包。
安全管理:執行加密、鑒權與隱私地址解析。
控制流程:實現連接參數更新、信道映射更新、數據長度擴展等 LL Control PDUs。
LL層主要有5種狀態:
待機狀態(Standby State)
廣播狀態(Advertising State)
掃描狀態(Scanning State)
發起狀態(Initiating State)
連接狀態(Connection State)

下面我們詳細解釋每個狀態:
1、待機狀態(Standby State)
這是鏈路層的默認狀態,設備既不發送也不接收數據。
功耗最低,設備可以在此狀態下初始化或等待其他操作。
2、廣播狀態(Advertising State)
設備通過發送廣播報文來宣告自己的存在。
廣播報文可以包含設備地址、名稱、服務等信息。
設備可以配置為不同的廣播類型(如可連接廣播、非可連接廣播、可掃描廣播等)。
3、掃描狀態(Scanning State)
設備監聽廣播報文,分為主動掃描和被動掃描。
被動掃描:僅接收廣播報文,不發送掃描請求。
主動掃描:在收到可掃描的廣播報文后,發送掃描請求以獲取更多信息(掃描響應)。
4、發起狀態(Initiating State)
設備監聽特定設備的廣播報文,并在收到后發起連接請求。
只有設備配置為發起模式時才會進入此狀態。
5、連接狀態(Connection State)
當發起設備發送連接請求并被廣播設備接受后,雙方進入連接狀態。
在連接狀態下,設備分為主設備和從設備。
中心設備(Central):發起連接的設備。
外圍設備(Peripheral):接受連接的設備。
在連接狀態下,鏈路層會維護一個連接事件(Connection Events),在每個連接事件中,主設備和從設備可以進行數據包的交換。連接事件按照連接間隔(Connection Interval)周期性地發生。
2.2.3 主機控制接口層(HCI)
HCI 是 Host-Controller Interface 的縮寫,即 “主機-控制器接口”。
它本質上是一套軟件層面的規范和協議,定義了藍牙協議棧中兩個主要部分——主機(Host) 和控制器(Controller)——之間應該如何通信。
Host 和 Controller 是什么?
要理解HCI,首先必須明白藍牙協議棧是如何分層的:
Controller:負責處理所有底層、實時性要求高的無線射頻任務。 - 包含協議層:物理層、鏈路層。 - 職責:管理無線電信號、調制解調、跳頻、數據包時序、廣播、掃描等。它直接與硬件打交道。
Host:負責處理所有高層、應用邏輯相關的任務。 - 包含協議層:L2CAP、ATT、GATT、SM以及最終的應用程序。 - 職責:管理連接、定義服務與特征、處理加密安全、為應用程序提供API
2.2.4 邏輯鏈路控制及自適應協議層(L2CAP)
L2CAP對LL進行了一次簡單封裝。LL層只關心傳輸的數據本身,L2CAP就要區分加密通道還是普通通道,同時還要對連接間隔進行管理。
L2CAP是藍牙協議棧的“交通調度中心”和“數據包裝工”。 它位于基礎射頻協議之上,但低于應用層協議(如ATT/GATT),充當一個承上啟下的多路復用和數據適配層。
2.2.5 屬性協議層(ATT)
ATT全稱是Attribute protocol(數據交互協議),這一層的關鍵詞是Attribute(屬性)。一個屬性其實就是一條數據,屬性是BLE數據提供單元,也是藍牙空中傳播數據的最上層。
ATT層定義了各種屬性,屬性的操作方法。通過ATT層可以讀寫對端設備的屬性,但是屬性之間有什么聯系、各個屬性怎么組合起來提供服務,由上層GATT負責。
屬性,是ATT層的關鍵字。
2.2.6 通用訪問配置文件層(GAP)
Generic Access Profile(通用訪問配置規范),主要用來進行廣播、掃描和發起連接等。
GAP層將設備分為四種角色,分別是外圍設備,中心設備,廣播設備和觀察設備。
這些設備圍繞著廣播和連接的差異性而區分,外圍設備和廣播設備對外發出廣播數據,中心設備和觀察設備掃描外部廣播數據,廣播設備和觀察設備通常不建立連接,而外圍設備和中心設備可以建立連接。
圍繞著廣播和連接,GAP層定義了許多不同的"模式(mode)",比如廣播模式和連接模式,在不同模式下的操作稱為“規程(procedure)”。
例如:當一個設備正在進行廣播時,稱其為"廣播模式"。廣播往往會持續較長時間,也許是該設備唯一用途。而當一個設備正在尋找廣播者時,稱其為"觀察規程"。觀察往往持續一段較短時間,用以構建用戶界面或者尋找需要的指定信息。
2.2.7 通用屬性配置文件層(GATT)
GATT(Generic Attribute Profile, 通用屬性規范),自己本身不提供數據,而是將ATT層提供的屬性組合起來構成的服務。GATT是建立連接后通信規范, 而藍牙是通過GAP建立通信的。
在BLE里,通過ATT層可以讀寫對端設備的屬性,但是屬性之間有什么聯系、各個屬性怎么組合起來提供服務,由上層GATT負責。
服務,是GATT層的關鍵字。
注意:
GATT 連接,必須先經過GAP協議。
一旦兩個設備建立起了連接,GATT 就開始起作用了。
中心設備和外設需要雙向通信的話,唯一的方式就是建立GATT 連接。
GATT 定義兩個BLE設備通過服務(Service)和特征(Characteristic)進行通信。
1、GATT(通用屬性配置文件)
定義 BLE 設備如何組織和傳輸數據,以 “服務(Service)” 和 “特征(Characteristic)” 為單位。
示例:心率監測設備的 GATT 服務包含 “心率特征”,手機通過讀取該特征獲取心率數據。
2、服務和特征
服務是特征的容器,通過邏輯分組簡化復雜功能的管理;
特征是數據交互的最小單元,通過屬性定義實現靈活的讀寫與推送機制;
兩者結合構成 GATT 協議的核心框架,支撐藍牙設備間的標準化數據交互(如智能穿戴、醫療設備、物聯網傳感器)。
3、特征的關鍵屬性(Properties)
特征通過 “屬性” 定義數據的操作方式,常見屬性包括:
1)可讀(Read):允許客戶端讀取特征值(如讀取電池電量)。
2)可寫(Write):允許客戶端寫入特征值(如設置設備參數)。
3)通知(Notification):服務端主動發送特征值更新(如心率變化時推送給手機)。
4、UUID
UUID 是藍牙 GATT 協議的 “數字身份證”,通過標準化的唯一標識機制,實現了跨廠商設備的功能互認(標準 UUID)與廠商個性化功能的擴展(自定義 UUID)
三、LuatOS BLE 的四種工作模式解析
在前面的章節中,我們介紹了 BLE 的背景以及基礎理論知識。若要深入了解其協議細節,讀者可參考其他專業的資料。
從本部分開始,我們將聚焦于 LuatOS 的實際開發,重點講解其支持的 四種核心 BLE 工作模式,并通過實例展示如何應用。
3.1 模式解釋
外圍設備模式(peripheral):設備會被掃描到, 并且可以被連接;
中心設備模式(central):設備會掃描其他設備, 并且可以連接其他設備;
廣播者模式(ibeacon):設備會周期性的廣播beacon信息, 可以被掃描到, 但一般不會被連接;
觀察者模式(scan):設備會掃描其他設備, 但不會連接其他設備。
3.2 四種模式的基本流程
3.2.1外圍設備模式(peripheral)的基本流程(概要描述)
1、初始化藍牙框架
? bluetooth_device = bluetooth.init()
2、創建BLE對象
? local ble_device = bluetooth_device:ble(ble_callback)
3、創建GATT描述
? local att_db = {xxx}
4、創建廣播信息
? ble_device:adv_create(adv_data)
5、開始廣播
? ble_device:adv_start()
6、等待連接
7、在回調函數中處理連接事件, 如接收數據, 發送數據等
3.2.2中心設備模式(central)的基本流程(概要描述)
1、初始化藍牙框架
bluetooth_device = bluetooth.init()
2、創建BLE對象
? local ble_device = bluetooth_device:ble(ble_callback)
3、掃描目標BLE設備
? ble_device:scan_start()
4、建立與目標設備的連接
? ble_device:connect(mac, add_type)
5、處理各類BLE事件(連接、斷開連接、掃描報告、GATT操作完成等)
3.2.3廣播者模式(ibeacon)的基本流程(概要描述)
1、初始化藍牙底層框架
? bluetooth_device = bluetooth.init()
2、創建BLE對象
? local ble_device = bluetooth_device:ble(ble_callback)
3、配置ibeacon廣播數據包
? 包含廠商特定數據格式,ibeacon類型標識符
? 設置UUID、Major、Minor等關鍵參數
4、啟動BLE廣播功能
? ble_device:adv_start()
3.2.4觀察者模式(scan)的基本流程(概要描述)
1、初始化藍牙框架
? bluetooth_device = bluetooth.init()
2、創建BLE對象
? local ble_device = bluetooth_device:ble(ble_callback)
3、開始掃描
? ble_device:scan_start()
4、在回調函數中處理掃描事件, 如接收設備信息等
5、按需停止掃描
? ble_device:scan_stop()
3.3 應用場景
3.3.1 外圍設備+中心設備(連接模式)
設計框圖:

3.3.2 廣播者+觀察者(無連接模式)
設計框圖:

四、LuatOS上的BLE核心庫
4.1 常量詳解
4.1.1地址模式常量
ble.PUBLIC

4.1.2 特征屬性常量
ble.READ

ble.WRITE

ble.NOTIFY

ble.IND

ble.WRITE_CMD

4.1.3 事件類型常量
ble.EVENT_CONN

ble.EVENT_DISCONN

ble.EVENT_WRITE

ble.EVENT_READ_VALUE

ble.EVENT_SCAN_REPORT

ble.EVENT_GATT_ITEM

ble.EVENT_GATT_DONE

ble.EVENT_SCAN_STOP

4.1.4 廣播相關常量
ble.COMPLETE_LOCAL_NAME

ble.CHNLS_ALL

ble.CHNL_37

ble.CHNL_38

ble.CHNL_39

ble.FLAGS

ble.FLAGS 說明
在BLE中,標志(flags)通常出現在廣播數據中,這些標志用于指示設備的能力和可發現性等。
根據藍牙核心規范(Bluetooth Core Specification),廣播數據中的Flags字段是一個8位的位圖(bitmask),每個位代表特定的含義,以下是各個位的定義(從LSB到MSB):
Bit 0: LE Limited Discoverable Mode(有限可發現模式)
Bit 1: LE General Discoverable Mode(通用可發現模式,設備持續可被發現)
Bit 2: BR/EDR Not Supported(不支持經典藍牙)
Bit 3: Simultaneous LE and BR/EDR to Same Device Capable(同一設備同時支持BLE和經典藍牙)
Bit 4: Simultaneous LE and BR/EDR to Different Devices Capable(支持同時連接不同設備的BLE和經典藍牙)
Bit 5-7: 保留(Reserved)
注意:Bit 0和Bit 1不能同時被設置。如果同時設置,則視為無效。
Bit1和Bit2被設置時,Flags字段的值為0x06(二進制0000 0110),
Bit2被設置時,Flags字段的值為0x04(二進制0000 0100)。
ble.SERVICE_DATA

ble.MANUFACTURER_SPECIFIC_DATA

4.2 函數詳解
bluetooth.init()
功能
初始化藍牙框架
注意事項
必須在使用藍牙功能之前調用;
僅需要調用一次,若創建失敗, 會返回nil, 請檢查內存是否足夠。
參數
無
返回值
local bluetooth_device = bluetooth.init()
bluetooth_device

示例

bluetooth_device:ble(ble_callback)
功能
創建一個BLE對象, 用于操作BLE設備
注意事項
必須在bluetooth.init()初始化成功后調用;
對象生命周期管理 :BLE對象需要在整個操作周期內保持有效,從初始化到最終釋放;
全局/模塊級變量推薦 :為了確保對象在需要時始終可用,通常建議將BLE對象定義在合適的作用域中:
模塊級變量:適用于單個模塊內部使用
全局變量:適用于跨模塊訪問
作為參數傳遞
參數
ble_callback

返回值
local ble_device = bluetooth_device:ble(ble_callback)
ble_device

示例

ble_device:scan_create(addr_mode,scan_interval,scan_window)
功能
創建一個BLE掃描
注意事項
無
參數
addr_mode

scan_interval

scan_window

返回值
local result = ble_device:scan_create(addr_mode,scan_interval,scan_window)
result

示例

ble_device:scan_start()
功能
開始BLE掃描
注意事項
掃描會一直進行, 直到調用ble.scan_stop()停止掃描;
掃描到結果會觸發ble.EVENT_SCAN_REPORT事件,執行通過bluetooth_device:ble(ble_callback)創建BLE對象時注冊的回調函數;
掃描到同一個設備不會去重, 掃描到數據就會執行回調。
參數
無
返回值
local result = ble_device:scan_start()
result

示例

ble_device:scan_stop()
功能
停止BLE掃描
注意事項
掃描會一直進行, 直到調用ble.scan_stop()停止掃描。
參數
無
返回值
local result = ble_device:scan_stop()
result

示例

ble_device:connect(mac, addr_type)
功能
發起BLE連接請求
注意事項
無
參數
mac

addr_type

返回值
local result = ble_device:connect(mac, addr_type)
result

示例

ble_device:disconnect()
功能
發起BLE斷開連接請求
注意事項
無
參數
無
返回值
local result = ble_device:disconnect()
result

示例

ble_device:gatt_create(opts)
功能
創建一個BLE GATT服務
注意事項
確保UUID格式正確,且特征屬性使用正確的權限常量;
特征屬性必須是 ble.NOTIFY | ble.READ | ble.WRITE | ble.IND 的一種或多種組合;
參數
opts

返回值
local result = ble_device:gatt_create(opts)
result

示例

ble_device:adv_create(opts)
功能
創建一個BLE廣播
注意事項
無
參數
opts

返回值
local result = ble:adv_create(opts)
result

示例

ble_device:adv_start()
功能
開始廣播
注意事項
對于外圍設備模式, 如果被斷開了連接, 則需要重新開始廣播, 才能被重新搜索到
參數
無
返回值
local result = ble_device:adv_start()
result

示例

ble_device:adv_stop()
功能
主動停止廣播
注意事項
無
參數
無
返回值
local result = ble_device:adv_stop()
result

示例

ble_device:write_notify(opts,value)
功能
寫入帶通知的特征值
注意事項
外圍設備使用,主動向中心設備發送通知數據
參數
opts

value

返回值
local result = ble_device:write_notify(opts,value)
result

示例

ble_device:write_indicate(opts,value)
功能
寫入帶指示的特征值
注意事項
外圍設備使用,主動向中心設備發送指示數據
參數
opts

value

返回值
local result = ble:write_indicate(opts,value)
result

示例

ble_device:write_value(opts,value)
功能
寫入特征值
注意事項
無
參數
opts

value

返回值
local result = ble_device:write_value(opts,value)
result

示例

ble_device:read_value(opts)
功能
讀取特征值
注意事項
無
參數
opts

返回值
local result = ble_device:read_value(opts)
result

示例

ble_device:notify_enable(opts,enable)
功能
開關通知監聽
注意事項
中心設備使用,配置是否接收外圍設備發送的通知消息
參數
opts

enable

返回值
local result = ble_devie:notify_enable(opts,enable)
result

示例

ble_device:indicate_enable(opts,enable)
功能
開關指示監聽
注意事項
中心設備使用,配置是否接收外圍設備發送的指示消息
參數
opts

enable

返回值
local result = ble_device:indicate_enable(opts,enable)
result

示例

ble_device:adv_decode(data)
功能
解碼廣播數據
注意事項
廣播數據通常來自于ble.EVENT_SCAN_REPORT 事件的ble_param.data
參數
data

返回值
local adv_data = ble_device:adv_decode(data)
adv_data

示例

ble.mac()
功能
獲取藍牙MAC
注意事項
無
參數
無
返回值
local mac = ble.mac
mac

示例

五、LuatOS上的BLE 應用開發流程
本部分將深入一項具體實踐:在「外圍設備模式」下進行 BLE 應用開發。
5.1 總體設計框圖

5.2 分析項目代碼
這個ble peripheral demo中的readme文件,以及代碼中的注釋都比較詳細,接下來我用vscode直接打開這份demo項目代碼,和大家一起分析下項目代碼;
程序結構:

文件說明:
main.lua:主程序入口文件。
ble_peripheral_main.lua:ble 外圍設備主程序,進行 ble 初始化,設置廣播內容,處理各類 ble 事件(連接、斷開連接、寫入請求等)。
ble_peripheral_receiver.lua:BLE 外圍設備接收數據處理。
ble_peripheral_sender.lua:BLE 外圍設備發送數據處理。
ble_timer_app.lua:ble 外圍設備定時器處理邏輯,啟動兩個循環定時器,一個是以 notify 方式主動向中心設備推送數據(需中心設備先開啟 notify 訂閱),另一個是使用 write 方式,更新特征值數據,中心設備需要主動讀取特征值獲取最新數據。
ble_uart_app.lua:ble 外圍設備接 uart 處理邏輯,將收到的中心設備的寫入數據,通過 uart 發送到 pc 端串口工具。
check_wifi.lua:Air8000 的藍牙功能依賴 WiFi 協處理器,需確保 WiFi 固件為最新版本。本腳本文件檢查當前 Air8000 模組的 WiFi 固件是否為最新版本,若不是則自動啟動升級(需插入可聯網的 SIM 卡)
5.3 Air8000開發板上運行演示這個項目
準備硬件環境:
1、Air8000開發板一塊+2.4gwifi天線一根:
天線裝到開發板上
2、TYPE-C USB數據線一根 + USB轉串口數據線一根,Air8000開發板和數據線的硬件接線方式為:
Air8000開發板通過TYPE-C USB口供電;(外部供電/USB供電 撥動開關 撥到 USB供電一端)
TYPE-C USB數據線直接插到核心板的TYPE-C USB座子,另外一端連接電腦USB口;
六、BLE外圍設備模式常見問題分析
6.1 燒錄示例demo后,無法搜到藍牙
Air8000
1、首先檢查demo,固件是否是最新的,若不是則需更新的最新的版本測試,若已經是最新的,看第2步
2、luatools日志全局搜 AIRLINK_READY,查看WIFI固件版本打印(因為Air8000的藍牙功能依賴WiFi協處理器)

version后面的數字代表的是wifi固件的版本,目前最新發布的是14。
如果不是最新的14,此時需要升級wifi固件,目前有兩種wifi的升級方式,可自由選擇:
(1)4g遠程升級wifi
在示例demo中的main.lua中,會有下面這句話,打開require "check_wifi"即可通過4g升級wifi,不過注意要插上能夠正常上網的sim卡。

(2)本地線刷升級wifi
參考下面這篇文檔,進行線刷升級wifi固件
https://docs.openluat.com/air8000/luatos/app/updatwifi/update/
若升級好后,測試依舊有問題,請向技術人員反饋。
Air8101
首先檢查demo,固件是否 都是最新的,若不是則需更新demo以及固件版本測試;若檢查已經是最新的還是測試有問題,請向我們技術人員反饋。
6.2 使用Air8000/Air8101 作為外圍設備,向已經建立連接的手機藍牙調試軟件發送數據,發現手機調試軟件接收到的數據不全。
原因:
MTU設置的問題,Air8000/Air8101支持的MTU默認是256字節,如果手機上的藍牙調試軟件的MTU較小,會以小的為準。
解決方案:
1、可以通過Air8000讀到對端藍牙設備的MTU大小,根據讀到的MTU的大小做分包處理即可。(讀取對端設備MTU的功能還在開發中)
2、調大對端藍牙設備的MTU。
七、LuatOS 上的中心設備模式應用開發流程
7.1 前置知識了解
7.1.1 UUID
7.1.1.1 UUID 是什么?
UUID 是藍牙 GATT 協議的 “數字身份證”,通過標準化的唯一標識機制,實現了跨廠商設備的功能互認(標準 UUID)與廠商個性化功能的擴展(自定義 UUID)
藍牙協議通過 UUID 實現設備間的標準化通信,使用藍牙對外提供服務的設備,需要有對應的服務功能,服務是藍牙設備中功能劃分的單元,每個服務都對應著一種特定的功能或數據傳輸需求。
例如,當一個藍牙設備(如智能手環)向外界廣播服務時,會攜帶對應的 UUID,其他設備(如手機)通過識別這些 UUID,就能知道該設備提供哪些功能(如心率監測、數據傳輸等),并建立針對性的連接。
一個藍牙設備可以包含多個服務(Service),每個服務通過一個 UUID(服務 UUID) 進行標識。
每個服務下包含多個特征(Characteristic),每個特征都擁有一個獨立的 UUID(特征 UUID)作為其唯一標識。
特征是最小的數據單元,我們通過讀寫特征來與設備交互。
1、服務(Service)
是什么:服務是藍牙設備功能的邏輯分組,類似于一個"功能模塊"。
例如:心率監測服務、電池電量服務等。
作用:定義設備能做什么(如測量心率、監控電量)。通過 UUID 唯一標識。
示例:

2、特征(Characteristic)
是什么:特征是服務的子元素,是服務中的具體數據點,用于實際的數據讀寫操作。
例如:心率值、電池電量百分比。
作用:存儲具體數據(如 71 bpm)。通過 UUID 和 屬性(Properties) 定義操作權限(讀/寫/通知等)。
示例:

3、描述符(Descriptor)
是什么:描述符是特征的子元素,是特征的附加信息,用于細化特征的行為或配置。
例如:啟用數據通知、設置數據格式。
作用:配置特征的行為(如開啟實時通知)。補充描述特征(如單位、數據范圍)。
最常見描述符:。
Client Characteristic Configuration Descriptor (CCCD)
用于啟用/禁用特征的 NOTIFY 或 INDICATE 功能。
三者的層級關系:

實際示例(手環):

7.1.1.2 UUID 的格式:
藍牙 UUID 的標準格式為 128 位,通常表示為 32 個十六進制字符,以 8-4-4-4-12 的格式分組,共 36 個字符(包括 4 個連字符):
格式:8-4-4-4-12
示例:0000180D-0000-1000-8000-00805F9B34FB
標準 UUID:
由藍牙技術聯盟(Bluetooth SIG)定義,用于常見服務。
標準的 UUID 為:0000xxxx-0000-1000-8000-00805F9B34FB。
為了節省帶寬,標準 UUID 通常使用 16 位或 32 位短格式,實際通信時自動擴展為 128 位。每一個藍牙技術聯盟定義的屬性有一個唯一的 16 位 UUID,以代替上面的基本 UUID 的‘x’部分。
若 16 bit UUID 為 xxxx,那么 128 bit UUID 為 0000xxxx-0000-1000-8000-00805F9B34FB。
若 32 bit UUID 為 xxxxxxxx,那么 128 bit UUID 為 xxxxxxxx-0000-1000-8000-00805F9B34FB。
自定義 UUID:
用于私有服務或廠商特定功能,需開發者自行生成,通常使用 UUID 隨機生成器生成 128 位 UUID,確保全球唯一性
7.1.1.3 UUID 的分類
藍牙規定好的 uuid 如下:
0x180x 開頭 → 只能當 Service UUID
0x2Axx 開頭 → 只能當 Characteristic UUID
0x29xx 開頭 → 只能當 Descriptor UUID
0x180x 開頭 UUID(Service UUID)
0x180x 區間只能當 Service UUID。

0x2Axx 開頭 UUID(Characteristic UUID)
0x2Axx (0x2A00 – 0x2AFF) 區間只能當 Characteristic UUID。

0x29xx 開頭 UUID(Descriptor UUID)
0x29xx 開頭只能當 Descriptor UUID,即描述符 UUID。
這里僅介紹一個使用最頻繁的 UUID:0x2902
0x2902 - Client Characteristic Configuration(CCC,客戶端特征配置描述符)
這是一個可寫的描述符,允許客戶端設備(如手機、電腦)配置如何從服務器設備(BLE 外設)接收數據更新。主要用于啟用或禁用通知(Notifications) 和指示(Indications) 功能。
BLE 實時數據推送(如傳感器數據、狀態更新)都需要通過正確配置 0x2902 描述符來實現。
UUID 格式:
完整 UUID:00002902-0000-1000-8000-00805f9b34fb
縮寫:0x2902
類型:Descriptor(描述符)
有效值:
0xFFxx 開頭 UUID(Vendor Specific)
0xFF00 ~ 0xFFFF 區間為 SIG 的公共預留池(Vendor-Specific 區間) 任何廠商都可以臨時借用。
這個區間 SIG 作為公共預留區間,一般用作示例測試參考,屬于臨時方案,想要作為產品,要么去 SIG 申請正式分配,要么直接用 128-bit 自建 UUID。
注意事項:
1、整個 16-bit 空間都由 Bluetooth SIG 的官方文檔 《Assigned Numbers》統一管理
2、商用不要使用已存在的 UUID,可以用 128-bit 自定義 UUID,或者在 SIG 申請正式分配。
3、同一設備,不同特征 UUID 任何時候都不能一樣。
4、自定義的 128-bit UUID,服務 UUID 可以和 特征 UUID 一樣,SIG 規定的 16-bit 的服務和特征值的 UUID 不能一樣。

7.1.2 Properties
特征的關鍵屬性(Properties)
特征通過 “屬性” 定義數據的操作方式,常見屬性包括:

7.2 demo 項目總體設計框圖
demo 項目的總體設計框圖如下:

7.3 源碼分析
7.3.1 文件說明

1、main.lua:主程序入口文件。
2、ble_client_main.lua:BLE 中心設備主程序,進行 BLE 初始化,處理各類 BLE 事件(連接、斷開連接、掃描報告、GATT 操作完成等)。
3、ble_client_receiver.lua:BLE 中心設備接收數據處理。
4、ble_client_sender.lua:BLE 中心設備發送數據處理。
5、ble_timer_app.lua:BLE 中心設備定時器處理邏輯,啟動兩個循環定時器,一個用于定時讀取外圍設備特征值 UUID 數據,一個用于定時向外圍設備特征值 UUID 發送數據。
6、ble_uart_app.lua:BLE 中心設備接 uart 處理邏輯,將收到的 notify 數據,通過 uart 發送到 pc 端串口工具。
7、check_wifi.lua:Air8000 的藍牙功能依賴 WiFi 協處理器,需確保 WiFi 固件為最新版本。本腳本文件檢查當前 Air8000 模組的 WiFi 固件是否為最新版本,若不是則自動啟動升級(需插入可聯網的 SIM 卡)
7.3.2 ble_client_main.lua
本文件為 ble client 主應用功能模塊,整個應用通過 sysplus.taskInitEx 啟動主任務,實現了完整的 BLE 中心設備功能,包括設備發現、連接管理、數據收發和異常恢復機制。核心業務邏輯為:
7.3.2.1 初始化與配置
加載依賴模塊( ble_client_receiver 用于數據接收處理, ble_client_sender 用于數據發送處理)。
定義配置參數(目標設備名稱、服務 UUID、特征值 UUID、超時時間等)。
調用 ble_init(),初始化藍牙功能。
7.3.2.2 設備掃描與連接
創建并啟動 BLE 掃描(默認參數:公共地址模式、掃描間隔 100ms、掃描窗口 100ms)。
通過 is_target_device 函數過濾掃描到的設備(匹配設備名稱)。
發現目標設備后停止掃描并發起連接。
連接超時處理和重連機制。
7.3.2.3 事件處理
通過 ble_event_cb 回調函數處理各類 BLE 事件:
連接成功(EVENT_CONN)
斷開連接(EVENT_DISCONN)
掃描報告(EVENT_SCAN_REPORT)
GATT 操作完成(EVENT_GATT_DONE)
讀取特征值完成(EVENT_READ_VALUE)
7.3.2.4 業務功能
GATT 服務發現完成后,自動啟用目標特征值的通知監聽。
接收并處理來自其他模塊的讀取請求(READ_REQ)。
通過消息隊列與其他模塊通信。
7.3.2.5 異常處理
掃描超時或連接失敗時觸發異常處理。
斷開連接后自動清理消息隊列并嘗試重連。
異常情況下 5 秒后重新開始掃描連接。
7.3.3 ble_client_receiver.lua
7.3.3.1 主要功能
數據分類處理 :接收兩類數據(外圍設備通知數據和主動讀取到的數據)。
數據分發 :根據數據類型(通過特征值 UUID 區分)發布到不同的消息隊列,供其他模塊處理。
7.3.3.2 核心實現
提供proc(service_uuid, char_uuid, data)接口函數,接收服務 UUID、特征值 UUID 和數據。
通過判斷特征值 UUID 是否匹配配置中的target_notify_char或target_read_char來區分數據類型。
對于外圍設備的通知數據,通過sys.publish("RECV_BLE_NOTIFY_DATA", ...)發布。
對于主動讀取到的數據,通過sys.publish("RECV_BLE_READ_DATA", ...)發布。
7.3.3.3 數據流轉
當ble_client_main模塊接收到EVENT_READ_VALUE事件時,會調用此模塊的 proc 函數。
本模塊將數據分類后發布到對應的消息主題。
其他訂閱了這些消息主題的模塊可以接收并處理數據。
7.3.4 ble_client_sender.lua
其他模塊只需發布"SEND_DATA_REQ"消息即可請求中心設備向外圍設備發送數據。
7.3.4.1 主要功能
消息訂閱:訂閱"SEND_DATA_REQ"消息,接收其他模塊的發送請求。
隊列管理:維護發送隊列 send_queue,存儲待發送的數據項(包含服務 UUID、特征值 UUID、數據、回調信息)。
任務調度:通過任務處理函數 ble_client_sender_task_func 處理各類 BLE 事件。
數據發送:按順序發送隊列中的數據,并通過回調通知發送結果。
7.3.4.2 核心實現
其他模塊通過sys.publish("SEND_DATA_REQ", ...)發布 發送請求。
send_data_req_proc_func函數將請求數據加入發送隊列,并通知任務。
任務處理函數根據 BLE 事件狀態(連接成功、斷開連接等)處理隊列數據。
send_item_func函數負責實際發送數據。
send_item_cbfunc函數處理發送結果,調用用戶回調。
7.3.4.3 事件處理
CONNECT_OK:BLE 連接成功,開始發送隊列數據。
SEND_REQ:有新數據需要發送,繼續處理隊列。
DISCONNECTED:連接斷開,清空隊列并通知所有發送請求失敗。
7.3.5 ble_uart_app.lua
UART 初始化:打開 UART1 接口,配置波特率 115200、數據位 8、停止位 1、無奇偶校驗。
數據接收:訂閱 "RECV_BLE_NOTIFY_DATA" 消息,接收來自 BLE 外圍設備的通知數據。
數據轉發:將接收到的 BLE 數據(包含服務 UUID、特征值 UUID 和實際數據)格式化后通過 UART1 發送到 PC 端。
7.3.6 ble_timer_app
7.3.6.1 主要功能
創建兩個獨立的 5 秒循環定時器
一個用于定時 發送 數據到外圍設備特定特征值 UUID。
一個用于定時 讀取 外圍設備特定特征值 UUID 的數據。
7.3.6.2 核心實現
定義了目標服務 UUID( FA00 )和特征值 UUID(寫: EA02 ,讀: EA03 )。
實現數據發送結果回調函數 send_data_cbfunc ,用于處理發送成功/失敗的通知。
實現兩個定時器回調函數:send_data_req_timer_cbfunc:發布SEND_DATA_REQ消息到 ble_client_sender 模塊。read_data_req_timer_cbfunc:發送READ_REQ請求到 ble_client_main 模塊。
啟動兩個 5 秒循環定時器,分別綁定上述兩個回調函數。
7.3.6.3 數據流轉
發送流程:定時器觸發 → 發布SEND_DATA_REQ消息 →ble_client_sender處理 → 回調通知結果。
讀取流程:定時器觸發 → 發送READ_REQ請求 →ble_client_main處理 → 結果通過事件返回。
7.4 日志分析
接下來用兩個 Air8000 核心板,一個燒錄外圍設備的 demo,另一個燒錄中心設備的 demo,來演示中心設備如何讀,寫操作。
1、中心設備訂閱外圍設備特征通知(Notify)

2、中心設備寫入特征值(Write)

3、中心設備主動讀取特征值數據(Read)

八、LuatOS 上的廣播模式應用開發流程
8.1 前置知識了解
8.1.1 ibeacon 介紹
1、ibeacon 技術是 Apple 公司在 2013 年 9 月發布的一種基于 BLE 藍牙的通信協議,主要用于短距離傳送少量數據。
它通過周期性廣播包含唯一標識符(UUID、Major、Minor)的數據包,使智能設備在接收信號后,結合信號強度(RSSI)估算距離,實現室內定位、場景觸發等功能。
2、ibeacon 規定了一個 30 個字節的廣播包。其中需要重點解析的是后21 個字節(即從 UUID 開始),此前字節重在標識是否為 ibeacon 協議。
ibeacon 廣播數據包的完整格式如下:

一個 30 字節的完整的 iBeacon 可做如下拆解:
AD Structure1(Advertising Data Structure)
長度字段(1 字節):此處一般為 0x02(即十進制 2),表示該 AD Structure 后續數據的總字節數
類型字段(1 字節):0x01(Flags,廣播標志位)
數據(1 字節):0x06(Flags 的值,表示可被發現且支持 BLE 通用模式,Flags 見 7.2 章節)
AD Structure2
長度字段(1 字節):此處一般為 0x1A(即十進制 26)表示后續數據的總字節數
類型字段(1 字節):固定為 0xFF,表示廠商特定數據。
數據(此處為公司標識符)(2 字節):蘋果的公司 ID 為 0x004C(小端存儲為 0x4C 0x00)。
iBeacon 有效載荷(仍屬于 AD Structure2)
iBeacon 類型標識符(1 字節):固定為 0x02,表示子類型為 iBeacon
iBeacon 數據長度(1 字節):固定為 0x15,表示 ibeacon 后續數據長度為 21 字節后續數據長度為需要重點解析的 21 字節
Proximity UUID(16 字節):設備的唯一標識符(如 UUID)。
Major(2 字節):用于區分區域(如建筑樓層)。
Minor(2 字節):用于更細粒度的定位(如具體房間)。
Tx Power(1 字節):校準信號強度的參考值(RSSI at 1m)。
AD Structures 是什么?
在 BLE 協議中,設備通過廣播包(Advertising Packet)向外發送數據。
一個廣播包可能包含多個 AD Structure(Advertising Data Structure),每個 AD Structure 用于描述不同的信息(例如設備名稱、服務 UUID、廠商數據等)。
每個 AD Structure 的格式固定為:
[長度(1字節)] + [類型(1字節)] + [數據(N字節)]
長度字段(1 字節):表示類型 + 數據的總字節數(即類型1字節 + 數據N字節)。
類型字段(1 字節):定義數據的用途(例如0xFF表示廠商數據,0x09表示設備名稱)。
數據字段(N 字節):具體內容,長度由長度字段-1決定(因為類型占 1 字節)。
AD Structure 的解析規則:
順序無關:AD Structure 的順序不固定。
長度限制:總長度不超過 31 字節(若為擴展廣播,可更長,但 iBeacon 不支持)。
類型唯一性:同一類型可能重復出現(例如多個廠商數據塊)。
在解析時,可以通過以下步驟遍歷所有 AD Structure:
從廣播包首字節開始。
讀取長度字段(1 字節),確定當前 AD Structure 的總長度(包括類型和數據)。
讀取類型字段(1 字節),判斷數據類型。
根據類型,處理后續數據。
常見 AD Structure 類型對照表:
其中標志位,長度,類型我們不需要處理,我們只需要關注 ibeacon 的有效載荷部分,接下來詳細介紹下這部分字段內容:
廠商標識符(2 字節):是藍牙技術中用于唯一標識設備制造商或品牌方的 2 字節(16 位)編碼,范圍是0x0000~0xFFFF(即 0~65535),它的核心作用是區分不同廠商的藍牙設備,確保數據解析和兼容性。
ibeacon 類型標識符(1 字節):固定為 0x02, 表示子類型為 ibeacon。
ibeacon 數據長度(1 字節):固定為 0x15,表示 ibeacon 數據長度 21 字節。
Proximity UUID(16 字節):通用唯一標識符。
這是一個 128 位(16 字節)的唯一標識符,用于區分你所在的 iBeacon 網絡。 例如,一個商店的所有 iBeacon 可以使用同一個 UUID,這樣你的應用就可以知道用戶進入了該商店區域。 通常,一個組織或一個應用使用同一個 UUID,然后通過 Major 和 Minor 來進一步細分區域和設備。
Major(2 字節):主標識,用于區分同一組織(UUID 相同)下的不同區域或組別。
Major 是一個 16 位的無符號整數,用于將一組相關的設備進行分組。 例如,一個連鎖商店的每個分店可以使用相同的 Major 值,這樣應用就知道用戶進入了哪個分店。
Minor(2 字節):次標識,用于在同一個 Major 組內進行更細粒度的區分。
Minor 也是一個 16 位的無符號整數,用于標識特定的 iBeacon。 例如,在一個分店內,每個貨架或區域可以有一個唯一的 Minor 值。這樣,應用就可以知道用戶接近哪個具體的貨架。
Signal Power(1 字節):校準信號強度的參考值,單位 dBm。(該位為 8 位有符號數據,范圍為-128 到 127,最高位是符號位)
這個字段是 8 位有符號整數,表示在距離 iBeacon 設備 1 米處測量到的信號強度(RSSI)。這個值用于校準,幫助估算與設備之間的實際距離。設備接收到信標的信號強度(RSSI)后,與這個校準值進行比較,通過信號衰減模型來估算距離。 例如:0xC0 對應-64dBm
十六進制 0xC0 的二進制表示為 11000000
作為有符號整數,最高位 1 表示負數
取反加 1 計算補碼值:01000000 = 64
因此,0xC0 對應十進制-64
注:
1、如何獲取廠商標識符?
(1)向藍牙技術聯盟(SIG)直接申請。
(2)使用已授權廠商的 ID,申請得到其授權。
2、Signal Power 是 8 位有符號整數,例如:0xC0 的二進制表示是 1100 0000,最高位 1 代表負數,對應十進制是-64。
3、廠商標識符是按照小端序存儲的,例如:Apple 的公司 ID 是0x004C(大端序),但在藍牙數據包中按規范存儲為4C 00(小端序)。
注意:Apple 的 ID 是 0x004C,但是 demo 中需按照 0x4C,0x00 的方式寫入存儲。
原因:在 BLE 協議中,公司 ID 按照小端序存儲。
大端序:高位字節存儲在低地址,低位字節存儲在高地址,0x004C在大端序中存儲為00 4C

小端序:高位字節存儲在高地址,低位字節存儲在低地址,0x004C 在小端序中存儲為4C 00

8.1.2 ibeacon 如何利用 Signal Power 和 RSSI 進行距離估算?
ibeacon 通過 Signal Power(出廠校準信號強度) 和 RSSI(接收信號強度) 估算設備與 ibeacon 之間的距離,其核心原理基于藍牙信號衰減模型。簡單來講就是設備出廠前先根據實際情況,測算在 1 米距離時的信號強度是多少,作為基準值,然后基于藍牙信號衰減模型,根據實際信號值 RSSI 推算出實際距離。以下是具體方法和實現步驟:
注意:不同的藍牙設備或相同設備不同的工況甚至不同的場地環境,都會影響 Signal Power 值,因此這個值雖然可以測量,但一定程度上是個經驗值,很難測準。故 ibeacon 的距離估算功能只是估算大概范圍,并不能用于精準定位。
1、關鍵概念
2、距離估算公式
iBeacon 使用 對數路徑損耗模型(Log-distance Path Loss Model)計算距離:

d:估算距離(米)。
n:環境衰減因子(通常 2~4,空曠環境=2,普通室內=2.5-3,復雜環境多障礙物=3.5-4),環境越復雜信號衰減越快。
Tx Power:Beacon 的校準信號強度(通過實際環境測量擬合,需預先標定)。
RSSI:手機實際測得的信號強度。
3、示例計算
Tx Power = -60 dBm
RSSI = -80 dBm
n = 2.5(室內環境)

8.2 源碼分析
8.2.1 文件說明
1、main.lua:主程序入口文件。
2、ble_ibeacon.lua:iBeacon 功能的具體實現,負責藍牙初始化、廣播配置和異常處理。
3、check_wifi.lua:Air8000 的藍牙功能依賴 WiFi 協處理器,需確保 WiFi 固件為最新版本。本腳本文件檢查當前 Air8000 模組的 WiFi 固件是否為最新版本,若不是則自動啟動升級(需插入可聯網的 SIM 卡)
8.2.2 ble_ibeacon.lua
8.2.2.1 全局變量定義
device_name :廣播設備名稱,
adv_state :廣播狀態標志,用于跟蹤 iBeacon 廣播的開啟/關閉狀態,
ibeacon_data :iBeacon 廣播數據包,包含以下結構:
廠商標識符(2 字節):0x004C,本例演示的是 ibeacon,所以采用 Apple 的 ID:0x004C(iBeacon 是 Apple 的專有技術,采用 Apple 的 ID 才能顯示成 ibeacon)
ibeacon 類型標識符(2 字節):固定為 0x02,0x15, 表示子類型為 ibeacon。
Proximity UUID(16 字節):0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10
Major(2 字節):0x00,0x01
Minor(2 字節):0x00,0x02
Signal Power(1 字節):0xC0

8.2.2.2 事件回調函數 (ble_callback)
處理 BLE 設備的各種事件:
ble.EVENT_ADV_START :廣播成功啟動時設置 adv_state 為 true
ble.EVENT_ADV_STOP :廣播停止時設置 adv_state 為 false

8.2.2.3 核心任務函數 (ble_ibeacon_task_func)
這是模塊的主要功能實現,采用無限循環結構確保廣播穩定運行:
初始化藍牙核心 :創建 bluetooth_device 實例
初始化 BLE 功能 :創建 ble_device 實例并注冊回調
配置廣播參數 :通過 adv_create 方法設置:
廣播地址模式 (ble.PUBLIC)
廣播通道 (ble.CHNLS_ALL)
廣播間隔 (intv_min/max = 120)
廣播數據 (包含標志位、iBeacon 數據和設備名稱)
啟動廣播 :調用 adv_start()方法
狀態監控 :通過 while adv_state 循環監控廣播狀態
異常處理 :使用 goto EXCEPTION_PROC 標簽統一處理各種初始化失敗情況
資源清理與重試 :在異常情況下停止廣播并重新初始化,間隔 5 秒后重試

8.3 日志分析
luatools 日志比較簡單,只有開啟廣播的 log 打印

重點看 nrf connect 掃描出來的 ibeacon 信息:

九、LuatOS 上的掃描模式應用開發流程
9.1 前置知識了解
9.1.1 掃描窗口和掃描間隔
掃描窗口(scan_window):
是指 BLE 設備在掃描過程中,打開接收器去監聽廣播設備的時間段。這個時間段是設備實際進行掃描操作的時間,也稱為掃描事件的持續時間。掃描窗口的單位通常是 0.625ms,并且它的值必須小于或等于掃描間隔。
掃描間隔(scan_interval):
表示兩次掃描事件之間的間隔時間。掃描間隔的單位與掃描窗口相同,單位也是 0.625ms。
注:
1、如果掃描窗口與掃描間隔一樣長,表明主機一直在掃描。
2、掃描窗口和掃描間隔是在 ble_device:scan_create 創建掃描需要填寫的參數。
默認參數, addr_mode=0, scan_interval=100, scan_window=100

9.1.2 掃描到的廣播數據如何解碼?
ble.EVENT_SCAN_REPORT 事件的 ble.param 包含如下內容:
addr_type :整數類型,表示藍牙設備的地址類型
adv_addr :設備的廣播地址,可以通過 :toHex() 方法轉換為十六進制字符串形式的 MAC 地址
rssi :整數類型,表示接收信號強度,單位為 dBm
data :二進制數據類型,表示接收到的原始廣播數據,可以通過 :toHex() 方法轉換為十六進制字符串
其中的廣播數據 data 可以通過 ble_device:adv_decode(data) 來解碼。
ble_device:adv_decode(data)
功能
解碼廣播數據
注意事項
廣播數據通常來自于 ble.EVENT_SCAN_REPORT 事件的ble_param.data
參數
data

返回值
local adv_data = ble_device:adv_decode(data)
adv_data

示例

9.2 源碼分析
9.2.1 文件說明
1、main.lua:主程序入口文件。
2、ble_scan.lua:ble_scan.lua 是 Air8000 的藍牙掃描功能實現模塊,主要負責初始化藍牙框架、配置并執行設備的掃描操作,并通過回調函數處理掃描到的設備信息。
3、check_wifi.lua:Air8000 的藍牙功能依賴 WiFi 協處理器,需確保 WiFi 固件為最新版本。本腳本文件檢查當前 Air8000 模組的 WiFi 固件是否為最新版本,若不是則自動啟動升級(需插入可聯網的 SIM 卡)
9.2.2 ble_scan.lua
9.2.2.1 全局變量定義
scan_state :掃描狀態標志,用于跟蹤 BLE 掃描的開啟/關閉狀態,初始值為 false 表示未掃描

9.2.2.2 處理掃描報告事件 (handle_scan_report)
功能:當掃描到 BLE 設備時,處理掃描報告事件。
處理內容:記錄并輸出發現設備的信息,包括 RSSI 值、設備地址和廣播數據等,可以根據需求篩選數據。
示例演示了如何篩選 ibeacon 廣播數據。

9.2.2.3 事件回調函數 (ble_callback)
處理 BLE 設備的各種掃描事件:
ble.EVENT_SCAN_INIT :掃描初始化成功時,記錄日志并設置 scan_state 為 true
ble.EVENT_SCAN_REPORT :接收到掃描報告時,調用 handle_scan_report 函數處理掃描數據
ble.EVENT_SCAN_STOP :掃描停止時,記錄日志并設置 scan_state 為 false

9.2.2.4 核心任務函數 (ble_scan_task_func)
這是模塊的主要功能實現,采用無限循環結構確保掃描穩定運行:
初始化藍牙核心 :創建 bluetooth_device 實例
初始化 BLE 功能 :創建 ble_device 實例并注冊回調
配置掃描參數 :通過 scan_create()方法設置掃描參數(地址模式、掃描間隔、掃描窗口等)
啟動掃描 :調用 scan_start()方法開始掃描周圍 BLE 設備
狀態監控 :通過 while scan_state 循環監控掃描狀態
異常處理 :使用 goto EXCEPTION_PROC 標簽統一處理各種初始化失敗情況
資源清理與重試 :在異常情況下停止掃描并重新初始化,間隔 5 秒后重試

9.3 日志分析
luatools 日志,可以查看掃描到的 ibeacon 的廣播包數據信息

最后再結合 ibeacon 應用,進行簡單的距離估算:
代碼:

十、常見問題
10.1 ibeacon 應用,為什么無法顯示名稱?
答:

一個完整的 BLE 廣播數據包最長可以有 37 個字節,其中前 6 個字節固定用于設備 MAC 地址,剩下的 31 個字節才是我們可以自由配置的廣播數據區域。這 31 個字節會被劃分為若干個廣播數據結構體(AD Structure)。
也就是 BLE 廣播包 廣播數據區域不超過 31 字節,那么 iBeacon 包含的數據和包含 flag 的 AD Structure 已經占了 30 個字節,如果要設置設備命名,會超出 31 字節。
可能有人會問,不是還有 1 個字節的空間嗎,設備名稱用一個字節不可以嗎?
答:
名稱:"1"(1 字符)。
AD Structure 長度:1(數據) + 1(類型) + 1(長度) = 3 字節。
總長度:27(iBeacon) + 3(Flags) + 3(名稱) =33 字節→ 仍超出。
10.2 什么是 Flags?
ble.FLAGS 說明
在 BLE 中,標志(flags)通常出現在廣播數據中,這些標志用于指示設備的能力和可發現性等。
根據藍牙核心規范(Bluetooth Core Specification),廣播數據中的 Flags 字段是一個 8 位的位圖(bitmask),每個位代表特定的含義,以下是各個位的定義(從 LSB 到 MSB):
Bit 0: LE Limited Discoverable Mode(有限可發現模式)
Bit 1: LE General Discoverable Mode(通用可發現模式,設備持續可被發現)
Bit 2: BR/EDR Not Supported(不支持經典藍牙)
Bit 3: Simultaneous LE and BR/EDR to Same Device Capable(同一設備同時支持 BLE 和經典藍牙)
Bit 4: Simultaneous LE and BR/EDR to Different Devices Capable(支持同時連接不同設備的 BLE 和經典藍牙)
Bit 5-7: 保留(Reserved)
注意:Bit 0 和 Bit 1 不能同時被設置。如果同時設置,則視為無效。
Bit1 和 Bit2 被設置時,Flags 字段的值為 0x06(二進制 0000 0110),
Bit2 被設置時,Flags 字段的值為 0x04(二進制 0000 0100)。
10.3 常見的 BLE 斷開連接 reason

示例:
1、中心設備和外圍設備在數據傳輸過程中,把外圍設備斷電
中心設備會提示 8 的錯誤碼,即數據傳輸過程中超時斷開連接。

2、中心設備和外圍設備連接時,中心設備主動發起 disconnect
中心設備會提示 22 的錯誤碼,即本地主機終止連接。

外圍設備會提示 19 的錯誤碼,即遠程用戶終止連接。

今天的內容就分享到這里了~
審核編輯 黃宇
-
藍牙
+關注
關注
119文章
6312瀏覽量
178689 -
物聯網
+關注
關注
2945文章
47818瀏覽量
414824 -
BLE
+關注
關注
13文章
776瀏覽量
66339 -
LuatOS
+關注
關注
0文章
156瀏覽量
2693
發布評論請先 登錄
由淺入深,藍牙4.0/BLE協議棧開發攻略大全(3)
【TI CC2541申請】在linux平臺下開發BLE套件
初級小白實戰資料,零基礎入門rk3399平臺下linux4.4+android8.1開發
LuatOS是什么?
從開發工具包到定制硬件的軟件遷移是否有任何最佳實踐?
LuatOS的故事——從通信模塊到系統級主控
LuatOS平臺下BLE藍牙開發從入門到實踐
評論