日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】BLE 学习记录

發(fā)布時間:2024/4/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】BLE 学习记录 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文網(wǎng)址:http://m.blog.csdn.net/blog/chiooo/43985401

BLE 學(xué)習(xí)記錄

ANROID BLE 開發(fā),基于 bluetoothlegatt 分析

  • mBluetoothAdapter = mBluetoothManager.getAdapter(); 得到 手機(jī)上藍(lán)牙主機(jī)的適配器 mBluetoothAdapter

    public boolean initialize() {?
    // For API level 18 and above, get a reference to BluetoothAdapter through?
    // BluetoothManager.?
    if (mBluetoothManager == null) {?
    mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);?
    if (mBluetoothManager == null) {?
    Log.e(TAG, “Unable to initialize BluetoothManager.”);?
    return false;?
    }?
    }

    mBluetoothAdapter = mBluetoothManager.getAdapter(); if (mBluetoothAdapter == null) {Log.e(TAG, "Unable to obtain a BluetoothAdapter.");return false; }return true;

    }

  • 2.獲得mBluetoothGatt,注冊回調(diào)

    * Connects to the GATT server hosted on the Bluetooth LE device.** @param address The device address of the destination device.** @return Return true if the connection is initiated successfully. The connection result* is reported asynchronously through the* {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}* callback.public boolean connect(final String address) {if (mBluetoothAdapter == null || address == null) {Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");return false;}// Previously connected device. Try to reconnect.if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)&& mBluetoothGatt != null) {Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");if (mBluetoothGatt.connect()) {return true;} else {return false;}}final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 得到bluetoothdeviceif (device == null) {Log.w(TAG, "Device not found. Unable to connect.");return false;}// We want to directly connect to the device, so we are setting the autoConnect// parameter to false.mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback);//bluetoothdevice得到mBluetoothGatt 傳進(jìn)去的是 BluetoothGattCallback,從名字看就是回調(diào)。Log.d(TAG, "Trying to create a new connection.");mBluetoothDeviceAddress = address;return true; }

    3.讀寫B(tài)luetoothGattCharacteristic,使能notification

    mBluetoothGatt.readCharacteristic(characteristic); 讀 mBluetoothGatt.writeCharacteristic(characteristic); 寫* Enables or disables notification on a give characteristic.** @param characteristic Characteristic to act on.* @param enabled If true, enable notification. False otherwise.public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,boolean enabled) {if (mBluetoothAdapter == null || mBluetoothGatt == null) {Log.w(TAG, "BluetoothAdapter not initialized");return;}mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); }向下寫數(shù)據(jù): //設(shè)置數(shù)據(jù)內(nèi)容gattCharacteristic.setValue("send data->");//往藍(lán)牙模塊寫入數(shù)據(jù)mBLE.writeCharacteristic(gattCharacteristic); 讀數(shù)據(jù):if(gattCharacteristic.getUuid().toString().equals(UUID_KEY_DATA)){ //測試讀取當(dāng)前Characteristic數(shù)據(jù),會觸發(fā)mOnDataAvailable.onCharacteristicRead()mHandler.postDelayed(new Runnable() {@Overridepublic void run() {mBLE.readCharacteristic(gattCharacteristic);}}, 500);//接受Characteristic被寫的通知,收到藍(lán)牙模塊的數(shù)據(jù)后會觸發(fā)mOnDataAvailable.onCharacteristicWrite()mBLE.setCharacteristicNotification(gattCharacteristic, true);

    4.得到 supported services

    * Retrieves a list of supported GATT services on the connected device. This should be* invoked only after {@code BluetoothGatt#discoverServices()} completes successfully.** @return A {@code List} of supported services.public List<BluetoothGattService> getSupportedGattServices() {if (mBluetoothGatt == null) return null;return mBluetoothGatt.getServices(); }

    5.關(guān)系

    BluetoothGatt 代表一個連接,里面包含一個或者多個 BluetoothGattService , 而每個BluetoothGattService 包含多個BluetoothGattCharacteristic , 一個 BluetoothGattCharacteristic 里面可能包含0個或者多個 BluetoothGattDescriptor

    6.BLE 設(shè)備端LOG?
    條件:?
    主機(jī)端:BLEGATTLE 參考程序,?
    設(shè)備端: NODIC官方BLE UART 程序

    串口端LOG:

    main start trace uart_init ..\main.c:leds_init:137> enter_now ..\main.c:timers_init:149> enter_now ..\main.c:ble_stack_init:457> enter_now ..\main.c:gap_params_init:166> enter_now Start... ..\main.c:advertising_start:331> enter_now ..\main.c:ble_evt_dispatch:442> enter_now p_ble_evt->header.evt_id:16// connect event p_ble_evt->header.evt_id:16 p_ble_evt->header.evt_id:16 ..\main.c:ble_evt_dispatch:442> enter_now p_ble_evt->header.evt_id:20 p_ble_evt->header.evt_id:20// BLE_GAP_EVT_SEC_INFO_REQUEST p_ble_evt->header.evt_id:20 ..\main.c:ble_evt_dispatch:442> enter_now p_ble_evt->header.evt_id:19 p_ble_evt->header.evt_id:19// BLE_GAP_EVT_SEC_PARAMS_REQUEST p_ble_evt->header.evt_id:19 ..\main.c:ble_evt_dispatch:442> enter_now p_ble_evt->header.evt_id:80 // write event p_ble_evt->header.evt_id:80 p_ble_evt->header.evt_id:80 ..\main.c:ble_evt_dispatch:442> enter_now p_ble_evt->header.evt_id:80 // write event p_ble_evt->header.evt_id:80 ..\main.c:nus_data_handler:224> enter_now send data-> // received data p_ble_evt->header.evt_id:80 // write event ..\main.c:ble_evt_dispatch:442> enter_now p_ble_evt->header.evt_id:24// BLE_GAP_EVT_AUTH_STATUS p_ble_evt->header.evt_id:24 p_ble_evt->header.evt_id:24 ..\main.c:ble_evt_dispatch:442> enter_now p_ble_evt->header.evt_id:23 // BLE_GAP_EVT_AUTH_KEY_REQUEST p_ble_evt->header.evt_id:23 p_ble_evt->header.evt_id:23 ..\main.c:ble_evt_dispatch:442> enter_now p_ble_evt->header.evt_id:18 ..\main.c:on_conn_params_evt:279> enter_now p_ble_evt->header.evt_id:18 // BLE_GAP_EVT_CONN_PARAM_UPDATE p_ble_evt->header.evt_id:18

    7.BLE連接參數(shù)

    #define MIN_CONN_INTERVALMSEC_TO_UNITS(500, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.5 seconds). */6~3200, 就是說7.5MS~ 4S, 1.25MS單位。連接時間間隔。 #define MAX_CONN_INTERVALMSEC_TO_UNITS(1000, UNIT_1_25_MS)/**< Maximum acceptable connection interval (1 second). */ #define SLAVE_LATENCY0 跳過連接事件/**< Slave latency. */ #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds). */ 管理超時,如果超過此時間沒有連接成功事件,則認(rèn)為是連接丟失。

    實(shí)驗(yàn)驗(yàn)證:

    #define MIN_CONN_INTERVAL 16 /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */ #define MAX_CONN_INTERVAL 500 /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */ #define SLAVE_LATENCY 0 /**< slave latency. */ #define CONN_SUP_TIMEOUT 2000 /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */ #define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(20000, APP_TIMER_PRESCALER) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */ #define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */ #define MAX_CONN_PARAMS_UPDATE_COUNT 3

    測試記錄:

    當(dāng)APP剛連接上時,這之間用得連接參數(shù)是由手機(jī)端決定的,經(jīng)過FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS 后,手機(jī)端會發(fā)新的參數(shù)過來,我測試過的,手機(jī)端都是MAX_CONN_INTERVAL 來決定,SLAVE_LATENCY 不管我改成多少,下發(fā)的都是0。

    網(wǎng)絡(luò)上討論

  • 對于IOS設(shè)備來說, 蘋果設(shè)置了一系列規(guī)定, 不允許從設(shè)備的配置超出這些范圍. 其他主設(shè)備來說目前還沒有聽說有什么具體范圍設(shè)定. Android設(shè)備目前google也還沒有明確規(guī)定. 所以換句話說, 只要符合主設(shè)備的要求, 從設(shè)備是可以在主設(shè)備規(guī)定的范圍內(nèi)請求主設(shè)備對connection interval進(jìn)行改變的.
  • 你通過GAP_SetParamValue()只是設(shè)置了參數(shù), 最后是需要通過發(fā)送到主設(shè)備那里去請求修改的. 所以這里不正確.請參考 GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, ..) 函數(shù)的做法.
  • 你可以通過packet sniffer抓包, 在時間戳上很清楚能看到connection interval. 或者你也可以自己加點(diǎn)代碼, 從程序里面獲取, 或者以notify方式發(fā)給主設(shè)備, 從主設(shè)備看, 總之, 方法很多哈.?
    另外附上蘋果對connection interval的要求, 其實(shí)還有其他的連接參數(shù)要求, 比如slave latency, supervision timeout, 如果不滿足這些, IOS設(shè)備會拒絕.

    The connection parameter request may be rejected if it does not comply with all of these rules:?
    Interval Max * (Slave Latency + 1) ≤ 2 seconds?
    Interval Min ≥ 20 ms?
    Interval Min + 20 ms ≤ Interval Max?
    Slave Latency ≤ 4?
    connSupervisionTimeout ≤ 6 seconds?
    Interval Max * (Slave Latency + 1) * 3 < connSupervisionTimeout

  • 8.從設(shè)備怎么主動斷開連接

    你可以直接調(diào)用 GAPRole_TerminateConnection() 來主動斷開連接。?
    那個函數(shù)調(diào)用后,連接順利斷開后會收到 GAP_LINK_TERMINATED_EVENT 事件。?
    在這個事件之后,你再重新啟動廣播,即可

    轉(zhuǎn)載于:https://www.cnblogs.com/wi100sh/p/4422686.html

    總結(jié)

    以上是生活随笔為你收集整理的【转】BLE 学习记录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。