w494143467 发表于 2021-6-13 17:55

【环境专家之智能手表】Part5:设备之间数据通信设计

本帖最后由 w494143467 于 2021-6-14 17:01 编辑

<p><strong>1.介绍</strong></p>

<p>在设备之间数据通信上,在Mesh和广播之间纠结,不过最终还是选择用自己熟悉的广播方式来传输数据。</p>

<p><strong>2.代码分析</strong></p>

<p>首先选择一个例程作为设计的起始程序,我这里选择了【ble_peripheral_server_hrp】例程,这是一个心率服务例程,其中拥有了心率的UUID,不过我不需要这个,因为我需要自定义广播协议。那么就先来分析一下源码吧。</p>

<pre>
<code class="language-cpp">#define APP_DEVICE_NAME_DEFAULT         "#RSL10_00001"
#define APP_COMPANY_ID                  {0x62, 0x3}
#define HRPS_SERVICE_UUID               {0x0D, 0x18}

void APP_SetAdvScanData(void)
{
    uint8_t companyID[] = APP_COMPANY_ID;
    uint8_t devName[]   = APP_DEVICE_NAME_DEFAULT;
    uint8_t hrp_uuid[]= HRPS_SERVICE_UUID;

    /* Set advertising data as device name */
    app_adv_info.host.adv_data_len = 0;
    GAPM_AddAdvData(GAP_AD_TYPE_COMPLETE_NAME, devName,
                  sizeof(APP_DEVICE_NAME_DEFAULT)-1, app_adv_info.host.adv_data,
                  &amp;app_adv_info.host.adv_data_len);

    /* Set scan response data as heart rate UUID and company ID */
    app_adv_info.host.scan_rsp_data_len = 0;
    GAPM_AddAdvData(GAP_AD_TYPE_SERVICE_16_BIT_DATA, hrp_uuid,
                  sizeof(hrp_uuid), app_adv_info.host.scan_rsp_data,
                  &amp;app_adv_info.host.scan_rsp_data_len);
    GAPM_AddAdvData(GAP_AD_TYPE_MANU_SPECIFIC_DATA, companyID,
                  APP_COMPANY_ID_LEN, app_adv_info.host.scan_rsp_data,
                  &amp;app_adv_info.host.scan_rsp_data_len);
}</code></pre>

<p>设置广播内容的函数如上所示,其中定义了三个变量,这三个变量都需要写入广播包中,【APP_COMPANY_ID】为自定义变量,不过前两个字节为厂商名,这个编号需要申请,安森美就有自己的厂商名;【APP_DEVICE_NAME_DEFAULT】为设备名,就是在蓝牙搜索中显示的名称,这个可以任意设置,但是长度有限,尽量控制在20字节以内;【HRPS_SERVICE_UUID】为心率的UUID,设置为16Bit,具体用法我暂时还没用过,是蓝牙一种特殊的功能,还有电池的UUID,如果设置了之后,再设置一些特殊的操作,就可以在手机上显示电池的电量。</p>

<p>其中蓝牙名字放在广播包中,而心率UUID和厂商编号放在扫描回应包中。</p>

<p>通过上面的设置,在手机端就可以看到相关的信息(图1)。</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p style="text-align: center;">图1</p>

<p>实际的广播内容如图2所示,其中第一行是【对&nbsp;Same Device Capable(Host)&nbsp;支持&nbsp;BLE】的意思;第二行为设备名称;第三行就是心率的UUID;第四行为厂商自定义的内容;</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p style="text-align: center;">图2</p>

<p><strong>3.协议设计</strong></p>

<p>广播解析完毕了之后,那么就是设备之间的通信协议设计了,大概设计了一下广播的协议,具体如下图3所示。</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p style="text-align: center;">图3</p>

<p>这里我主要用广播包,扫描回应包预留出来了,可以看到未使用的字节数还是非常多的,把该传输的内容都放在了广播包中,这样接收机就可以通过这个协议解析设备中的信息了。</p>

<p>接下来就是代码的修改了,名字上电之后不会再变,就剩后面的数据会不停的改变,所以需要重新实现广播包内容的设置,具体如下。</p>

<pre>
<code class="language-cpp">void APP_SetAdvScanData(void)
{
    uint8_t devName[]   = APP_DEVICE_NAME_DEFAULT;

    /* Set advertising data as device name */
    app_adv_info.host.adv_data_len = 0;
    GAPM_AddAdvData(GAP_AD_TYPE_COMPLETE_NAME, devName,
                  sizeof(APP_DEVICE_NAME_DEFAULT)-1, app_adv_info.host.adv_data,
                  &amp;app_adv_info.host.adv_data_len);
}

#define BROADCASTER_DATA_LEN         9
uint8_t Broadcaster_Data = {0x08, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
void APP_FollowSetAdvScanData(void)
{
        app_adv_info.host.adv_data_len = 14;

    GAPM_AddAdvData(GAP_AD_TYPE_MANU_SPECIFIC_DATA, Broadcaster_Data,
                                    BROADCASTER_DATA_LEN, app_adv_info.host.adv_data,
                  &amp;app_adv_info.host.adv_data_len);

}</code></pre>

<p>【APP_SetAdvScanData】是默认设置,主要设置广播包的名字,【APP_FollowSetAdvScanData】为实际要修改的数据,每次修改完数据之后,修改广播包的内容,然后重新打开广播,这样修改后的内容就在无线广播中了,从而实现动态广播数据。下面这个是心率服务例程封装好初始化蓝牙配置的函数,其中有包括广播包的初始化。</p>

<pre>
<code class="language-cpp">static void HRPS_Setup(void)
{
    HRPS_Initialize(TIMER_SETTING_S(1),
            HRPS_BODY_SENSOR_LOC_CHAR_SUP | HRPS_ENGY_EXP_FEAT_SUP | HRPS_HR_MEAS_NTF_CFG,
            HRS_LOC_CHEST,
            &amp;app_adv_info,
            APP_HRPS_HeartRateMeasurementUpdate,
            APP_HRPS_EnergyExpResetInd);
    APP_HRPS_Initialize();
}</code></pre>

<p>最终设备广播包的内容如下所示;</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p style="text-align: center;">图4</p>

<p><strong>4.总结</strong></p>

<p>广播包发送数据的流程就是这样,也是比较简单的,该踩的坑也踩了,大家需要修改广播包内容,照着操作就可以了。接下来就开始和传感器进行通信了。</p>

Jacktang 发表于 2021-6-14 10:50

<p>该踩的坑也踩了,终于踩上来了</p>

<p>想问一下,楼主的自定义广播协议与那个心率服务例程有什么不同</p>

<p>&nbsp;</p>

w494143467 发表于 2021-6-14 11:21

Jacktang 发表于 2021-6-14 10:50
该踩的坑也踩了,终于踩上来了

想问一下,楼主的自定义广播协议与那个心率服务例程有什么不同

&nbsp; ...

<p>心率服务会再广播包中给出UUID,上位机连接之后会有个心率服务,到时候上位机就可以通过这个服务获取心率数据。</p>
页: [1]
查看完整版本: 【环境专家之智能手表】Part5:设备之间数据通信设计