小白入門教程 | 小夢老師帶你學藍牙,四種常用模式一文通曉


圖片

大家好啊,我是夢程~合宙Cat.1模塊1.3主線固件支持雙模藍牙,今天就簡單說一下藍牙應該如何使用。

本教程以Air820開發板為例,講解BLE的廣播和從機功能。

我們將從經典藍牙、Beacon、Broadcast、Slave四種模式進行具體講解,在大多數的使用環境下,基本離不開這四種模式。

經典藍牙示例


1.1 藍牙功能系統信息

首先了解一下藍牙功能里面的一些系統消息服務,我們要使用這些服務進行邏輯編排。
圖片

1.2 經典藍牙函數

圖片圖片

1.3 經典藍牙示例代碼
--- 模塊功能:經典藍牙示例
-- @author Darren Cheng
-- @module bluetooth.bt
-- @license MIT
-- @copyright openLuat-
- @release 2021.08.24
-- @注意 需要使用core(Luat_VXXXX_RDA8910_BT_FLOAT)版本
module(..., package.seeall)
require "audio"

local vol = 50
local musicstatus = 1
local keyMap = {{},{},{},{},{},{},{},{},{},{}}

keyMap[0] = {}
keyMap[255] = {}
keyMap[2][0] = "ENTER"
keyMap[2][1] = "DOWN"
keyMap[1][0] = "UP"
keyMap[1][1] = "ESC"
keyMap[255][255] = "PWK"



local function keyMsg(msg)   
      if keyMap[msg.key_matrix_row][msg.key_matrix_col] == "PWK" and msg.pressed then

        btcore.setavrcpsongs(musicstatus)     

   if musicstatus == 0 then

            musicstatus = 1
        elseif musicstatus == 1 then
            musicstatus = 0
        end
        log.info("bt", "musicstatus",musicstatus)    end
    if msg.pressed then
        if keyMap[msg.key_matrix_row][msg.key_matrix_col] == "ENTER" then
            btcore.setavrcpsongs(3)        

           log.info("bt","下一曲")   
     elseif keyMap[msg.key_matrix_row][msg.key_matrix_col] == "ESC" then

            btcore.setavrcpsongs(2)     

           log.info("bt","上一曲")    
    elseif keyMap[msg.key_matrix_row][msg.key_matrix_col] == "UP" then

            vol = vol + 10
            if vol > 127 then
                vol = 127
            end
            btcore.setavrcpvol(vol)        

           log.info("bt","加音量", vol)   
     elseif keyMap[msg.key_matrix_row][msg.key_matrix_col] == "DOWN" then

            vol = vol - 10
            if vol < 0 then
                vol = 0
            end
            btcore.setavrcpvol(vol)   

           log.info("bt","減音量", vol)   
     end

  end

end

rtos.on(rtos.MSG_KEYPAD,keyMsg)

rtos.init_module(rtos.MOD_KEYPAD,0,0x7F,0x7F)



local function init()

    log.info("bt", "init")
    rtos.on(rtos.MSG_BLUETOOTH, function(msg)
        if msg.event == btcore.MSG_OPEN_CNF then
            sys.publish("BT_OPEN", msg.result) --藍牙打開成功
        elseif msg.event == btcore.MSG_BT_HFP_CONNECT_IND then
        sys.publish("BT_HFP_CONNECT_IND", msg.result) --hfp連接成功
	elseif msg.event == btcore.MSG_BT_HFP_DISCONNECT_IND then
            log.info("bt", "bt hfp disconnect") --hfp斷開連接
        elseif msg.event == btcore.MSG_BT_HFP_CALLSETUP_OUTGOING then
            log.info("bt", "bt call outgoing") --建立呼出電話
        elseif msg.event == btcore.MSG_BT_HFP_CALLSETUP_INCOMING then
            log.info("bt", "bt call incoming") --呼叫傳入    
            sys.publish("BT_CALLSETUP_INCOMING", msg.result)   
    elseif msg.event == btcore.MSG_BT_HFP_RING_INDICATION then

            log.info("bt", "bt ring indication") --呼叫傳入鈴聲
        elseif msg.event == btcore.MSG_BT_AVRCP_CONNECT_IND then          sys.publish("BT_AVRCP_CONNECT_IND", msg.result) --avrcp連接成功
		elseif msg.event == btcore.MSG_BT_AVRCP_DISCONNECT_IND then
            log.info("bt", "bt avrcp disconnect") --avrcp斷開連接
        end
    end)

end



sys.taskInit(function()

    sys.wait(5000)    -- audio.setChannel(1) -- 可調用此api切換播放通道,默認spk
    init()  -- 初始化

    log.info("bt", "poweron")
    btcore.open(2)  --打開經典藍牙
    sys.waitUntil("BT_OPEN", 5000) --等待藍牙打開成功

    log.info("bt", "設置藍牙參數")
    btcore.setname("Cat1BT")-- 設置廣播名稱
    btcore.setvisibility(0x11)-- 設置藍牙可見性
    log.info("bt", "藍牙可見性",btcore.getvisibility())    
    local _, result = sys.waitUntil("BT_AVRCP_CONNECT_IND") --等待連接成功
    if result ~= 0 then
        return
    end
    log.info("bt", "連接成功")  

  while true do

        vol = btcore.getavrcpvol()        if vol == -1 then
            log.info("bt", "獲取音量失敗", vol)        elseif vol == -2  then
            log.info("bt", "設備不支持獲取音量", vol)   

     else

            log.info("bt", "設備音量", vol)  

      end

        sys.wait(1000)  

  end

end)

代碼效果解釋:

  • 模塊成功開機后會初始化藍牙並廣播名稱為“Cat1BT”的藍牙設備

  • 使用手機連接名為“Cat1BT”的設備

  • 按POWER鍵控制音樂播放與暫停

  • 按DOWN鍵減小音量,單位為10

  • 按UPWARD鍵增大音量,單位為10

  • 按ENTER鍵切換下一首音樂

  • 按ESC鍵切換上一首音樂

  • 部分手機可能不支持音量調節和獲取

源碼下載鏈接:

https://gitee.com/openLuat/X-MagicBox-820/blob/master/demo/bt-learn/bt.lua
 
 

BLE-Beacon示例


Beacon:一種特殊的廣播,多用於藍牙定位環境。

系統信息及函數說明詳見:
https://doc.openluat.com/article/3495#BLEBeacon_393

2.1 BLE-Beacon示例代碼
--- 模塊功能:藍牙功能測試
-- @author openLuat
-- @module bluetooth.beacon
-- @license MIT
-- @copyright openLuat
-- @release 2020.09.27
-- @注意 需要使用core(Luat_VXXXX_RDA8910_BT_FLOAT)版本module(..., package.seeall)



local function init() 

       log.info("bt", "init")         

       rtos.on(rtos.MSG_BLUETOOTH, function(msg)
      

        if msg.event == btcore.MSG_OPEN_CNF then               sys.publish("BT_OPEN", msg.result) --藍牙打開成功   

      end


    end)

end



sys.taskInit(function()
  

      sys.wait(5000) 

      init() -- 初始化 

  

      log.info("bt", "poweron")      

      btcore.open(0) --打開藍牙從模式
   

      sys.waitUntil("BT_OPEN", 5000) --等待藍牙打開成功

  



      log.info("bt", "設置藍牙參數")       

 btcore.setadvparam(0x80,0xa0,0,0,0x01,0) 

--廣播參數設置 (最小廣播間隔,最大廣播間隔,廣播類型,廣播本地地址類型,廣播channel map,廣播過濾策略,定向地址類型,定向地址)
    btcore.setbeacondata("AB8190D5D11E4941ACC442F30510B4AB",10107,50179) --beacon設置  (uuid,major,minor)
    
  



 btcore.advertising(1)-- 打開廣播

end)




源碼下載鏈接:

https://gitee.com/openLuat/X-MagicBox-820/blob/master/demo/bt-learn/beacon.lua
 

2.2 抓包分析

這是通過抓包獲取的Beacon數據包:

-----------------------------------------------+-------------------- - - -

|     Packet sniffer frame header               |

+-------+-------------+-------------------------+-------+----------------- - - -

|channel| Packet nbr. | Time stamp              | Length|  Packet data

+-------+-------------+-------------------------+-------+----------------- - - -

| 0x25  | 03 00 00 00 | 9D B0 E3 07 00 00 00 00 | 26 00 | 00 24 A2 65 44 C6 C2 C8 02 01 1A 1A FF 4C 00 02 15 AB 81 90 D5 D1 1E 49 41 AC C4 42 F3 05 10 B4 AB 27 7B C4 03 C5 

+-------+-------------+-------------------------+-------+----------------- - - -

請添加圖片描述
這里我們可以獲取的信息有:Channel就是為0x25,轉換成十進制就是37通道AdvA就是模塊的MAC地址AdvData為抓取的信息,這是封裝用戶數據生成的,在代碼中則為UUID的數據,即:AB 81 90 D5 D1 1E 49 41 AC C4 42 F3 05 10 B4 AB


這里沒有分析儀也可以使用手機app查看,推薦軟件為nRF Connect。
圖片圖片
 
 

BLE-Broadcast示例


系統信息及函數說明詳見:

https://doc.openluat.com/article/3495#BLEBroadcast_582

3.1 BLE廣播示例代碼
-- 模塊功能:BLE廣播示例
-- @author Darren Cheng
-- @module bluetooth.slave
-- @license MIT
-- @copyright openLuat
-- @release 2021.08.24
-- @注意 需要使用core(Luat_VXXXX_RDA8910_BT_FLOAT)版本
module(..., package.seeall)

local function init()

    log.info("bt", "init")
    rtos.on(rtos.MSG_BLUETOOTH, function(msg)
        if msg.event == btcore.MSG_OPEN_CNF then
            sys.publish("BT_OPEN", msg.result) --藍牙打開成功
        end
    end)
end


sys.taskInit(function()

    sys.wait(5000)

    init() --初始化
    log.info("bt", "開藍牙")
    btcore.open(0)  --打開藍牙從模式
    sys.waitUntil("BT_OPEN", 5000)  --等待藍牙打開成功

    log.info("bt", "設置藍牙參數")
    btcore.setname("Cat1BT") -- 設置廣播名稱

    ------------ 設置藍牙廣播數據(LTV格式) --------------
    advData = "64617272656e"
    advType = "08"
    advLenth = string.format("%02x",(advData:len()/2)+1)
    btcore.setadvdata(string.fromHex(advLenth .. advType .. advData))    ------------ 設置藍牙響應包數據(LTV格式) --------------
    rspData = "6368656e67"
    rspType = "08"
    rspLenth = string.format("%02x",(rspData:len()/2)+1)
    btcore.setscanrspdata(string.fromHex(rspLenth .. rspType .. rspData))

    btcore.setadvparam(0x80,0xa0,0,0,0x07,0)    --廣播參數設置 (最小廣播間隔,最大廣播間隔,廣播類型,廣播本地地址類型,廣播channel map,廣播過濾策略,定向地址類型,定向地址)
    btcore.advertising(1)   -- 打開廣播
end)

源碼下載鏈接:

https://gitee.com/openLuat/X-MagicBox-820/blob/master/demo/bt-learn/broadcast.lua

3.2 現象展示及分析

請添加圖片描述

通過抓取數據包得知:
設備會廣播設置好的數據64617272656e
當主機端發出scan請求時,設備端會回復響應包內容6368656e67
注意:
藍牙廣播數據和響應包數據務必要符合LTV格式
完成所有設置之后,再去調用打開廣播的API
 
 

BLE-Slave示例


系統信息及函數說明詳見:

https://doc.openluat.com/article/3495#BLESlave_810

4.1 BLE-Slave示例代碼
-- @module bluetooth.slave
-- @license MIT
-- @copyright openLuat
-- @release 2021.08.24
-- @注意 需要使用core(Luat_VXXXX_RDA8910_BT_FLOAT)版本
module(..., package.seeall)



local useUserService = true -- 用戶自定義服務,true啟用,false禁用

local function init()

    log.info("bt", "init")
    rtos.on(rtos.MSG_BLUETOOTH, function(msg)
        if msg.event == btcore.MSG_OPEN_CNF then
            sys.publish("BT_OPEN", msg.result) --藍牙打開成功
        elseif msg.event == btcore.MSG_BLE_CONNECT_IND then
            sys.publish("BT_CONNECT_IND", {["handle"] = msg.handle, ["result"] = msg.result}) --藍牙連接成功
		elseif msg.event == btcore.MSG_BLE_DISCONNECT_IND then
            log.info("bt", "ble disconnect") --藍牙斷開連接
        elseif msg.event == btcore.MSG_BLE_DATA_IND then
            sys.publish("BT_DATA_IND", {["result"] = msg.result})--接收到的數據內容
        end
    end)

end



sys.taskInit(function()

    sys.wait(5000)
    init() --初始化

    log.info("bt", "poweron")
    btcore.open(0) --打開藍牙從模式
    sys.waitUntil("BT_OPEN", 5000) --等待藍牙打開成功

    log.info("bt", "設置藍牙參數")
    btcore.setname("Cat1BT")-- 設置廣播名稱
	btcore.setadvparam(0x80,0xa0,0,0,0x07,0) --廣播參數設置 (最小廣播間隔,最大廣播間隔,廣播類型,廣播本地地址類型,廣播channel map,廣播過濾策略,定向地址類型,定向地址)
    
    if useUserService then
        log.info("bt", "useUserService")
        btcore.addservice(0xff88)     -- 添加服務uuid
        btcore.addcharacteristic(0xffe1,0x08,0x002)  --添加特征 可寫
        -- btcore.addcharacteristic(0xffe1,0x08+0x04,0x002)  --添加特征 可寫 特征屬性可以寫多個,用+連接
        btcore.addcharacteristic(0xffe2,0x10,0x001)  --添加特征 通知
        btcore.adddescriptor(0x2902,0x0001)      --添加描述
        btcore.addcharacteristic(0xffe3,0x02,0x001)  --添加特征 可讀
    end

    btcore.advertising(1)-- 打開廣播
    _, bt_connect = sys.waitUntil("BT_CONNECT_IND")    if bt_connect.result ~= 0 then
        return false
    end
    --鏈接成功
    log.info("bt","connect_handle",bt_connect.handle) -- 連接句柄
    while true do
        _, bt_recv = sys.waitUntil("BT_DATA_IND") -- 等待接收到數據
        local data = ""
        local len = 0
        local uuid = ""
        while true do
            local recvuuid, recvdata, recvlen = btcore.recv(3)            

           if recvlen == 0 then

                break
            end
            uuid = recvuuid       

           len = len + recvlen

            data = data .. recvdata        end
        if len ~= 0 then
            log.info("bt","recv_data:", data)            log.info("bt","recv_data_len", len)            log.info("bt","recv_uuid:", string.toHex(uuid))            if data == "close" then
                btcore.disconnect()--主動斷開連接
            end
            if useUserService then
                btcore.send(data, 0xffe2, bt_connect.handle)    -- 發送數據(數據 對應特征uuid 連接句柄)
            end
            btcore.send(data, 0xfee2, bt_connect.handle)    -- 發送數據(數據 對應特征uuid 連接句柄)
        end
    end

end)


源碼下載鏈接:

https://gitee.com/openLuat/X-MagicBox-820/blob/master/demo/bt-learn/slave2.lua

4.2 代碼效果展示:

用戶需根據需求設置useUserService,true為啟用用戶添加服務,false為禁用用戶添加服務,使用默認服務。

1)用戶不添加服務的情況下,會提供幾個默認服務,若用戶自行添加服務,則默認服務會被刪除。

圖片圖片

2)用戶添加自定義服務

圖片圖片

用戶可使用0xFFE1的UUID向模塊發送數據,發送的數據會回顯到0xFFE2,用戶可通過訂閱0xFFE2獲取數據。

注意:

  • 添加服務時不要與已有服務的UUID重復

  • 添加特征時,特征屬性和特征權限要按照規定的格式

  • 特征屬性和權限可使用多個,使用+連接

  • 用戶完成所有添加操作之后,再去調用打開廣播API

今天的內容就分享到這里了,建議大家閱讀本文的API相關知識,已經根據官方文檔做了部分翻譯和注釋,也提到了一些注意點。根據我編寫的一些小demo去學習和實踐,甚至可以說,改一改demo就是你自己的作品,期待大家可以使用藍牙去做一些更有意思的項目。

- 相關開發資料鏈接 -

Air820UG開發板資料

https://gitee.com/openLuat/X-MagicBox-820/

LuatOS-Air開發資料

https://gitee.com/openLuat/Luat_Lua_Air724U

LuatOS-SoC倉庫

https://gitee.com/openLuat/LuatOS

LuatOS開發指南/入門教程

https://doc.openluat.com/wiki/3?wiki_page_id=606

上海合宙通信模塊 - 合宙Luat,讓萬物互聯更簡單


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM