zoukankan      html  css  js  c++  java
  • CH579/CH573/CH583/CH57x/CH58x 蓝牙从机使用注意事项

    本文涉及到ble从机的:

    • 广播相关
    • 连接相关
    • 服务/特征相关
    • 数据收发相关
    • 其他

    1.[广播相关]

    广播内容:

    //设置/修改扫描回复以及广播数据,这种修改需要重启广播
    GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
    GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
     
    //或者 通过下面方式进行修改,实时生效
    bStatus_t GAP_UpdateAdvertisingData( uint8_t taskID,uint8_t adType,uint8_t dataLen,uint8_t *pAdvertData );
    

    广播间隔和类型:

    //获取当前的广播间隔
    //这里的值都是1=1.25ms
    uint16_t advInt;
    advInt = GAP_GetParamValue( TGAP_DISC_ADV_INT_MIN );
    PRINT("min adv %d
    ",advInt); 
    advInt = GAP_GetParamValue( TGAP_DISC_ADV_INT_MAX );
    PRINT("max adv %d
    ",advInt);
     
    //修改广播间隔
     
    /*注意,广播的参数修改,需要重启广播,才能生效
     *可以修改后,然后在广播 GAPROLE_WAITING(广播停止)状态产生后,然后立刻开启广播. 不能关闭广播后立刻开启广播.
     */
    //160*1.25ms == 200ms
    uint16_t advInt = 160;
    GAP_SetParamValue( TGAP_DISC_ADV_INT_MIN, advInt );
    GAP_SetParamValue( TGAP_DISC_ADV_INT_MAX, advInt );
    
    //修改广播类型
    // GAP_ADVERTISEMENT_TYPE_DEFINES GAP Advertising Event Types
    #define GAP_ADTYPE_ADV_IND                    0x00  //!< Connectable undirected advertisement
    #define GAP_ADTYPE_ADV_HDC_DIRECT_IND         0x01  //!< Connectable high duty cycle directed advertisement
    #define GAP_ADTYPE_ADV_SCAN_IND               0x02  //!< Scannable undirected advertisement
    #define GAP_ADTYPE_ADV_NONCONN_IND            0x03  //!< Non-Connectable undirected advertisement
    #define GAP_ADTYPE_ADV_LDC_DIRECT_IND         0x04  //!< Connectable low duty cycle directed advertisement
    
    //对于只广播的类型,如一些 beacon,可以用 GAP_ADTYPE_ADV_NONCONN_IND 类型,这样不可以连接,会比较省电,但是数据只能放到 GAPROLE_ADVERT_DATA 中不能放到 GAPROLE_SCAN_RSP_DATA 中
    uint8 adv_type = GAP_ADTYPE_ADV_IND;
    GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE,sizeof( uint8_t ),&adv_type);
    

    广播开关:

    //获取当前广播状态
    //0为非广播,非0为广播
    uint8_t adv_status;
    GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &adv_status );
     
    //开启广播
    //对应状态上报:GAPROLE_ADVERTISING
    uint8_t advertising_enable = true;
    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8_t ), &advertising_enable );
    
    //关闭广播
    //  对应的状态上报:
    // :GAPROLE_WAITING
    // :pEvent->gap.opcode == GAP_END_DISCOVERABLE_DONE_EVENT
    advertising_enable = false;
    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8_t ), &advertising_enable );
    
     
    //重启广播
    //要先关闭广播,然后在停止广播的状态产生后才能再去使能广播,不能刚执行完关闭广播,就去开启广播
    //否则会导致立刻开启失败,如当前在广播状态,执行关闭广播,然后立刻执行开始广播,这时候开始广播是不会调用成功的
    //因为这里只是设置协议栈状态机标识位,实际上广播并没有立刻停止,要等协议栈轮询处理后,才会真正关闭,如果现在去启动广播,协议栈会认为当前已经在广播状态
    
    

    2.[连接相关]

    2.1 状态和参数

    //连接参数
    //设置最大最小连接间隔,最小为6,这里通常是在初始化的时候设置
    //这里的最大最小范围要尽量的大,比如6,1000因为主机端连的时候,可能会不断的修改连接间隔,从而实现更快速的服务相关的查询
    //后面的连接间隔,通过GAPRole_PeripheralConnParamUpdateReq 函数去更新即可
    GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );
    GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );
    
    //在从机启动的api里面传入了几个回调函数:
    GAPRole_PeripheralStartDevice( Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs );
    
    //其中Peripheral_PeripheralCBs的定义类似下面:
    static gapRolesCBs_t Peripheral_PeripheralCBs = {
        peripheralStateNotificationCB,  // Profile State Change Callbacks,广播状态改变,连接断开连上都会调用这个回调
        peripheralRssiCB,               // When a valid RSSI is read from controller (not used by application),当读RSSI后,这里会产生 RSSI的回调,把rssi 值传进来.
        peripheralParamUpdateCB         // 连接参数更新,比如连接 间隔发生改变之类,都会传入到这个函数里
    };
     
    

    2.2 连接断开更新参数等相关API

    //断开连接
    ///这里的connHandle 就是在连接的时候传进来的时候的代表一个连接,多连接场景,这个值不同.
    extern bStatus_t GAPRole_TerminateLink( uint16 connHandle );
    
    //连接参数更新
    //这个是从机端,去向主机端请求连接更新
    //这里的gapConnHandle 就是在连接的时候传进来的时候的代表一个连接,多连接场景,这个值不同.
    //注意下面几个参数值,这几个值要按照ble的规范去写,如果是对接ios,ios的这几个值更为严格.
    GAPRole_PeripheralConnParamUpdateReq( gapConnHandle, 
                                          DEFAULT_DESIRED_MIN_CONN_INTERVAL, 
                                          DEFAULT_DESIRED_MAX_CONN_INTERVAL, 
                                          DEFAULT_DESIRED_SLAVE_LATENCY, 
                                          DEFAULT_DESIRED_CONN_TIMEOUT, 
                                          heartRate_TaskID );
    

    3.[服务/特征相关]

    4.[数据传输相关]

    5.[其他]

    修改发射功率

    初始化时候修改

    在协议栈出事时候的config.h文件中修改以下定义:

    #ifndef BLE_TX_POWER
    #define BLE_TX_POWER								LL_TX_POWEER_0_DBM
    #endif
    
    初始化以后修改

    这里的传参,和BLE_TX_POWER 中宏的取值范围一致

     extern bStatus_t  LL_SetTxPowerLevel( u8 power );
    

    BLE从机的名称

    BLE里面有两个地方涉及到名字:

    1. 广播/扫描回复包中
    2. GAP中

    在wch的例程里,分别对应下面两个地方
    (规范并没有规定,两个地方的名字必须一致,但是这里建议大家用一致.)
    如果程序中修改,上电时候改这两个数组就好了

    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8 scanRspData[ ] =
    {
      // complete name
      0x12,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      'S',   
      'i',   
      'm',   
      'p',   
      'l',   
      'e',   
      ' ',
      'P',   
      'e',   
      'r',   
      'i',   
      'p',   
      'h',   
      'e',   
      'r',   
      'a',   
      'l',   
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),   // 100ms
      HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
      LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),   // 1s
      HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };
    
    
    // GAP GATT Attributes
    static uint8 attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple Peripheral";
    // Set the GAP Characteristics
    GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );
    

    IOS中BLE设备的名称问题:

    对于ble设备有两个名称,一个是在广播/扫描回复 的字段中放着,一个是叫ATT device name,需要连接后去通过GATT读取。 并没有明确的要求二者必须一致,但是对于诸如N家,S家的SDK来看,二者是一致的,在IOS 获取BLE设备的名字时, 如果这个设备之前没有连接过,那默认是广播中的名字;当连接后,IOS会通过去读从机的ATT DEVICE NAME,然后私自建立MAC->ATT DEVICE NAME 映射表,当下次再扫描时候,直接根据mac地址匹配自己缓存的BLE设备名字,所以IOS开发者时不时抱怨,为什么广播的名字改了,扫描出来的名字却没变。IOS开发者需要每次都从广播/扫描回复数据中 拿BLE设备广播出来的名称即可。
    也可以在开发ble固件时候,强制让广播名字与ATT device name 一致,这样IOS端的代码就不用动.

    微信小程序中交换mtu问题

    微信的小程序的api中提供了 一个设置mtu的api: wx.setBLEMTU(Object object)
    具体官方链接:https://developers.weixin.qq.com/miniprogram/dev/api/device/bluetooth-ble/wx.setBLEMTU.html
    这个api 有多个返回:

    属性 类型 默认值 必填 说明
    deviceId string 用于区分设备的 id
    mtu number 最大传输单元(22,512) 区间内,单位 bytes
    success function 接口调用成功的回调函数
    fail function 接口调用失败的回调函数
    complete function 接口调用结束的回调函数(调用成功、失败都会执行)

    存在问题:当设备的mtu 不支持传入的值时候,会直接返回fail,而不会把从机支持的最大值给报上来。

  • 相关阅读:
    WiFi热点
    计算器
    flask的使用
    Python logging
    串口
    C# 定时器
    C# 控件
    cookie 和 session
    文件
    Linux命令
  • 原文地址:https://www.cnblogs.com/iot-fan/p/13623201.html
Copyright © 2011-2022 走看看