色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

聚豐項目 > 基于AB32VG1的藍牙通信小程序

基于AB32VG1的藍牙通信小程序

藍訊驕龍 AB32VG1 是中科藍訊在 2020 RT-Thread 開發者大會上首度面向通用市場發布的其自主 RISC-V 內核 32 位 MCU 芯片,具有豐富的軟硬件資源和低成本優勢,微信小程序作為微信公眾號和app不足之處的補充,能夠提供更好的用戶體驗,多元性的曝光,在餐飲行業,服務行業,電子商務行業等領域有顯著的用戶流量。本設計意在為AB32開發板提供更多的應用方向。

尋游記 尋游記

分享
0 喜歡這個項目
團隊介紹

尋游記 尋游記

團隊成員

尋游記 嵌入式軟件

分享
項目簡介
藍訊驕龍 AB32VG1 是中科藍訊在 2020 RT-Thread 開發者大會上首度面向通用市場發布的其自主 RISC-V 內核 32 位 MCU 芯片,具有豐富的軟硬件資源和低成本優勢,微信小程序作為微信公眾號和app不足之處的補充,能夠提供更好的用戶體驗,多元性的曝光,在餐飲行業,服務行業,電子商務行業等領域有顯著的用戶流量。本設計意在為AB32開發板提供更多的應用方向。
硬件說明

RT-Thread使用情況概述:

整個方案涉及的技術有:rtt模塊化任務代碼設計,BLE-GATT,微信小程序軟件開發(wxml+wxss+js);

內核部分:使用了線程、信號量、定時器 、PWM

設備驅動:

GPIO/PWM/BLE 等


PC端將程序燒錄到MCU,通過downloader調用ble命令開始開發板藍牙廣播,使其處于可被發現狀態;小程序端打開藍牙搜索,找到開發板,獲取Notify/read/write信息;


這里著重說一下BLE-GATT。

現在低功耗藍牙(BLE)連接都是建立在 GATT (Generic Attribute Profile) 協議之上。GATT 是一個在藍牙連接之上的發送和接收很短的數據段的通用規范,這些很短的數據段被稱為屬性(Attribute)。

詳細介紹 GATT 之前,需要了解 GAP(Generic Access Profile),它在用來控制設備連接和廣播。GAP 使你的設備被其他設備可見,并決定了你的設備是否可以或者怎樣與合同設備進行交互。例如 Beacon 設備就只是向外廣播,不支持連接,小米手環就等設備就可以與中心設備連接。

GAP 給設備定義了若干角色,其中主要的兩個是:外圍設備(Peripheral)和中心設備(Central)。

外圍設備:這一般是簡單的低功耗設備,用來提供數據,并連接到一個更加相對強大的中心設備。這里指我們的開發板。
中心設備:中心設備相對比較強大,用來連接其他外圍設備。這里指手機端。

GAP 的廣播工作流程如下圖所示cen-per.png

    

GATT通信的雙方是C/S關系。外設作為GATT服務端(Server),它維持了ATT的查找表以及service和characteristic的定義。中心設備是GATT客戶端(Client),他向Server發起請求。需要注意的是,所有的通信事件,都是由客戶端(也叫主設備,Master)發起,并且接收服務端(也叫從設備,Slava)的響應。而GATT事務是建立在嵌套的Profiles,Services和Characteristics之上的,如下如所示:

GATT結構.png


Profile :

Profile并不是實際存在于BLE外設上的,它只是一個被Bluetooth SIG或者外設設計者預先定義的Service的集合。例如我們的例程心率Profile(Heart Rate Profile)就是結合了Heart Rate Service和Device Information Sercvice。所有官方通過GATT Profile的列表可以從這里找到。

這里給出官網的列表Assigned Numbers


Service:

Service是把數據分成一個個的獨立邏輯項,它包含一個或者多個Characteristic。每個Service有一個UUID唯一標識。UUID有16bit的,或者128bit的。16bit的UUID是官方通過認證的,需要花錢購買,128bit是自定義的,這個就可以自己隨便設置。
官方通過了一些標準Service,完整列表在這里。以Heart Rate Service為例,可以看到它的官方通過16bitUUID是0x180D,包含3個Characteristic:Heart Rate Measurement,Body Sensor Location和Heart Control Point,并且定義了只有一個第一個必須的,它是可選實現的。

Characteristic :

Characteristic 在GATT事務中的最低界別的是Characteristic,Characteristic是最小的邏輯數據單元,當然它可能包含一個組關聯的數據,例如加速度計的X/Y/Z三軸值。與Service類似,每個Characteristic用16bit或者128bit的UUID唯一標識。你可以免費使用Bluetooth SIG官方定義的標準Characteristic,使用官方定義的,可以確保BLE的軟件和硬件能相互理解。當然,你可以自定義Characteristic,這樣的話,就只有你自己的軟件和外設能夠相互理解。
舉個例子,Heart Rate Measurement Characteristic,這是上面提到的Heart Rate Service必需實現的Characteristic,它的UUID是0x2A37。它的數據結構是,開始8bit定義心率數據格式(是UINT8還是UINT16?),接下來就是對應格式的實際心率數據。
實際上,和BLE外設打交道,主要是通過Characteristic。你可以從Characteristic讀取數據,也可以往Characteristic寫數據。這樣就實現了雙向的通信。所以你可以自己實現一個類似串口(UART)的service,這個Service中包含兩個Characteristic,一個被配置只讀的通道(RX),另一個配置為只寫的通道(TX)。


軟件說明

軟件部分設計邏輯還是十分明確的;

開發板:打開ble,開始廣播等待被發現。建立通信后,按照主機端的請求發送相應數據;

小程序:打開藍牙適配器,搜索周圍藍牙,獲取搜索過程中所搜索到的設備信息,連接想要連接的設備,獲取服務、特征值,進行數據交互;


貼上代碼:

在進行完基本初始化之后,進行對BLE的設置:

    //設置回調函數

    ble_hs_cfg.sync_cb = blehr_on_sync;

    //初始化定時器

    ble_npl_callout_init(&blehr_tx_timer, nimble_port_get_dflt_eventq(),

                    blehr_tx_hrate, NULL);

    ble_npl_callout_init(&my_notify_tx_timer,nimble_port_get_dflt_eventq(),

                    my_notify_tx,NULL);

    //初始化gatt服務

    rc = gatt_svr_init();

    assert(rc == 0);

    //設備默認名字

    //這里可以更改設備名字

    rc = ble_svc_gap_device_name_set(device_name);


我在DEVICE_INFO Service里添加了String(0x2A3D)0X5A5D 的自定義characteristic;

屬性分別為READ和NOTIFY

{

            /*Characteristic:Model number string */

            .uuid=BLE_UUID16_DECLARE(GATT_STRING_UUID),

            .access_cb=gatt_svr_chr_access_device_info,

            .flags=BLE_GATT_CHR_F_READ,

        },

 

        {

            /*Characteristic:Model number string */

            .uuid=BLE_UUID16_DECLARE(GATT_RIGHT_UUID),

            .access_cb=gatt_svr_chr_access_device_info,

            .val_handle = &my_notify_handle,

            .flags=BLE_GATT_CHR_F_NOTIFY,

        },

給2A3D的value為:"ab32vg1";

在blehr中寫了(0x5A5D)notify的實現;

代碼如下:


//my notify--

static void my_notify_stop(void)

{

    ble_npl_callout_stop(&my_notify_tx_timer);

}


//重置

static void my_notify_reset(void)

{

    int rc;


    rc = ble_npl_callout_reset(&my_notify_tx_timer, RT_TICK_PER_SECOND);

    assert(rc == 0);

}



static void my_notify_tx(struct ble_npl_event* ev2)

{

    static char my_notify_hrm[2];

    int rc;

    struct os_mbuf *om;


    if (!notify_state) {

        my_notify_stop();

        XXX = 15;

        return;

    }


    my_notify_hrm[0] = 0x02;   /* contact of a sensor *///傳感器的聯系

    my_notify_hrm[1] = XXX; /* storing dummy data *///儲存虛擬數據

    /* Simulation of heart beats *///模擬心跳

        XXX++;

    if (XXX == 50) {

        XXX = 90;

    }



    om = ble_hs_mbuf_from_flat(my_notify_hrm, sizeof(my_notify_hrm));


    rc = ble_gattc_notify_custom(my_notify_conn_handle, my_notify_handle, om);


    assert(rc == 0);

    my_notify_reset();

}


在blehr的gap事件函數中設置notify事件:

    case BLE_GAP_EVENT_SUBSCRIBE:

        //對等方訂閱狀態的狀態更改1?2:3

        MODLOG_DFLT(INFO, "subscribe event; cur_notify=%d\n value handle; "

                          ,"val_handle2=%d\n",

                    event->subscribe.cur_notify, my_notify_handle);

        if (event->subscribe.attr_handle !=0) {

            if (event->subscribe.attr_handle==my_notify_handle)

            {

                notify_state = event->subscribe.cur_notify;

                my_notify_conn_handle = event->subscribe.conn_handle;

                my_notify_reset();

            }

                       

            } else if (event->subscribe.attr_handle != (&my_notify_handle)) {

                notify_state = event->subscribe.cur_notify;

                notify_conn_handle = 0;

                my_notify_conn_handle=0;

                my_notify_stop();

        }

        break;


最后進行定時器的初始化:

        ble_npl_callout_init(&my_notify_tx_timer,nimble_port_get_dflt_eventq(),my_notify_tx,NULL);


現在進行測試:

img_20211212175540.jpg


img_20211212174808.jpg

search.jpg

img_20211212174808.jpg




開發板程序運行正常!



現在展示小程序的代碼:

wxml:


<view class="content">

  <text>\ntext>

  <view class="p2bindtap="getBluetoothDevices">

    <text style="margin-left:36px">可用設備text>

  view>

  <block wx:if="{{show_available_devices_switch === 0}}">

    <block wx:for="{{devices}}">

      <view>

        <text style="margin-left:36px"  class="p3id="{{item.deviceId}}" data-device-name="{{item.name}}" bindtap="connectTO">{{item.name}}text>

      view>

    block>

  block>

  <block wx:if="{{connected_device_switch === 0}}">

    <view>

      <text class="p3style="margin-left:36px">{{device_name}} 已連接text>

    view>

  block>

  <text>\n\n\ntext>



  <view>

    <text class="p2style="margin-left:36px">接收字符串 text>

  view>

  <view>

    <text class="p3style="margin-left:36px">{{cur_string}}《-text>

  view>

  <text>\ntext>

  

  <view>

    <text class="p2style="margin-left:36px">接收訂閱text>

  view>

  <view>

    <text class="p3style="margin-left:36px">{{cur_notify}}《-text>

  view>

  <text>\ntext>


wxss:

page {

  color: #333;

}

.devices_summary {

  margin-top: 30px;

  padding: 10px;

  font-size: 16px;

}

.device_list {

  height: 300px;

  margin: 50px 5px;

  margin-top: 0;

  border: 1px solid #EEE;

  border-radius: 5px;

  width: auto;

}

.device_item {

  border-bottom: 1px solid #EEE;

  padding: 10px;

  color: #666;

}

.device_item_hover {

  background-color: rgba(0, 0, 0, .1);

}

.connected_info {

  position: fixed;

  bottom: 0;

  width: 100%;

  background-color: #F0F0F0;

  padding: 10px;

  padding-bottom: 20px;

  margin-bottom: env(safe-area-inset-bottom);

  font-size: 14px;

  min-height: 100px;

  box-shadow: 0px 0px 3px 0px;

}

.connected_info .operation {

  position: absolute;

  display: inline-block;

  right: 30px;

}

.p1 {

  position: relative;

  left: 36px;

}

.p2 {

  font-size: 1.3em;

  font-weight: 500;

  font-family: 'Times New Roman', Times, serif;

}

.p3 {

  font-weight: 400;

  color: rgb(171, 171, 171);

}

.p4 {

  position: relative;

  right: 36px;

}

.p5 {

  font-family: SimSun;

}


js后端:

   // 初始化藍牙適配器

      this.initBluetoothAdapter();

      // 本機藍牙適配器狀態

      this.getBluetoothAdapterState();

      // 開始搜索外圍設備

      this.startBluetoothDevicesDiscovery();


   /* 獲取在藍牙模塊生效期間所有已發現的藍牙設備。包括已經和本機處于連接狀態的設備。*/

   getBluetoothDevices: function() {

      var that = this;

      wx.getBluetoothDevices({

         success: function(res) {

            console.log('搜到的藍牙設備數目:' + res.devices.length);

            console.log(res.devices);

            that.setData({

               devices: res.devices,

               /* 顯示可用設備開關 */

               show_available_devices_switch: 0,

            });

         },

}

...

具體代碼在我的評論區


演示效果

微信小程序端展示

img_20211212180921.jpg

img_20211212181006.jpg

img_20211212181005.jpg

img_20211212181007.jpg




代碼地址:https://gitee.com/YYYYYao/ab32-vg1-ble.git


演示視頻:


附件

(6.94 MB)下載

評論區(1 )
  • 尋游記: 這里是代碼:https://gitee.com/YYYYYao/ab32-vg1-ble.git

    回復

主站蜘蛛池模板: 亚洲精品www久久久久久| 十七岁日本免费完整版BD| 欧美最猛12teevideos| 亚洲欧美一级久久精品| 国产产乱码一二三区别免费| 欧美午夜a级精美理论片| 中文日产无乱码AV在线观| 色色男_免费| 亚洲蜜桃AV永久无码精品放毛片 | 国产精品内射久久久久欢欢 | 久久综合色一综合色88中文| 青青草在现线免费观看| 97超视频在线观看| 露露的性战k8经典| 日本理伦片午夜理伦片| 北条麻妃快播| 日本亚欧热亚洲乱色视频| 纯肉高H啪短文合集| 视频一区国产在线第一页| 国产精亚洲视频综合区| 亚洲国产区中文在线观看| 精品人妻伦九区久久AAA片69| 欧美末成年videos丨| 亚洲欧美一区二区三区导航| 京香在线观看| 色噜噜色啪在线视频| 国产a级黄色毛片| 免费完整版观看| 亚洲精品视频区| 久久秋霞理伦片| gayxxxxgay呻吟受日本| 日本十八禁无遮拦啪啪漫画| 国产精品久久久久久久久齐齐| 亚洲AV无码一区二区三区牛牛| 俄罗斯mm| 人妻 中文无码 中出| 91进入蜜桃臀在线播放| 日本一卡二卡三卡四卡无卡免费播放 | 青柠高清在线观看完整版| 俄罗斯美女z0z0z0在线| 亚洲精品第一页|