reayfei 发表于 2021-7-18 22:47

【小型家用气象站】探索RSL10蓝牙广播

本帖最后由 reayfei 于 2021-7-18 23:26 编辑

<p><span style="font-size:16px;">&nbsp; &nbsp; &nbsp; &nbsp;低功耗蓝牙设备通过广播信道发现其他设备,一个设备进行广播,而另一个设备进行扫描。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;">&nbsp; &nbsp; &nbsp; &nbsp;总接一下,BLE蓝牙广播有两个基本特点,分别是:</span></p>

<p><span style="font-size:16px;">&nbsp; &nbsp; &nbsp; &nbsp;1.广播包数据最大长度为31字节(这个在代码里也有体现)</span></p>

<pre>
<code>#define ADV_DATA_LEN      0x1F</code></pre>

<p><span style="font-size:16px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2.数据格式为长度(1字节)类型(1字节)数据(n字节)......</span></p>

<p><span style="font-size:16px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;其中长度=n+1</span></p>

<p>&nbsp;</p>

<p style="text-indent:24.0pt; text-align:justify"><span style="font-size:10.5pt"><span style="font-family:&quot;Times New Roman&quot;,serif"><span style="font-size:12.0pt"><span style="font-family:&quot;微软雅黑&quot;,&quot;sans-serif&quot;"><span style="font-weight:normal">我的作品计划使用sense_bme680_bsec例程为base,这个例程已经实现了bme680传感器的驱动,还需要将ble_peripheral_server_hrp例程中蓝牙广播的驱动向sense_bme680_bsec中进行移植。</span></span></span></span></span></p>

<p style="text-indent:24.0pt; text-align:justify">&nbsp;</p>

<p><span style="font-size:16px;">设置广播内容的函数,这里我还添加了我需要广播出去的数据,如下所示:</span></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);

        app_adv_info.host.adv_data_len = 7;
    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>&nbsp;</p>

<p><span style="font-size:16px;">在串口打印数据的地方添加蓝牙广播的内容,这里需要注意的是,修改广播之后想让修改的内容广播出去需要先关闭广播然后再开启广播,这样蓝牙广播内容才能修改成功。</span></p>

<pre>
<code class="language-cpp">extern void HRPS_Setup(void);
void App_BsecOutputReady(bsec_env_output_struct *output)
{
    uint32_t temp = output-&gt;temperature;
    Broadcaster_Data = temp;        //温度
    temp = output-&gt;humidity;
    Broadcaster_Data = temp;        //湿度
    temp = output-&gt;raw_pressure;
    Broadcaster_Data = temp/65535%256;        //气压高位
    Broadcaster_Data = temp/256%256;        //气压中位
    Broadcaster_Data = temp%256;        //气压低位
    GAPM_CancelCmd();
    APP_SetAdvScanData();
    HRPS_Setup();
    HRPS_StartAdvertisement();

    //printf(""); // clear screen
    printf("BSEC output:\r\n");

    printf("timestamp = %lu ms\r\n", (uint32_t)(output-&gt;timestamp / 1000000));

#ifdef APP_USE_ANSI_COLORS
    printf("iaq = " COLORIZE("%.0f", GREEN) " (%d)\r\n", output-&gt;iaq,
            output-&gt;iaq_accuracy);

    printf("temperature = " COLORIZE("%.2f �C", RED) " (%d)\r\n",
            output-&gt;temperature, output-&gt;temperature_accuracy);

    printf("humidity = " COLORIZE("%.2f %%", CYAN) " (%d)\r\n",
            output-&gt;humidity, output-&gt;humidity_accuracy);
#else
    printf("iaq = %.0f (%d)\r\n", output-&gt;iaq, output-&gt;iaq_accuracy);

    printf("temperature = %.2f �C (%d)\r\n",
            output-&gt;temperature, output-&gt;temperature_accuracy);

    printf("humidity = %.2f %% (%d)\r\n",
            output-&gt;humidity, output-&gt;humidity_accuracy);

#endif /* APP_USE_ANSI_COLORS */
    printf("raw_pressure = %f Pa\r\n", output-&gt;raw_pressure);

    printf("co2_equivalent = %.2f ppm (%d)\r\n", output-&gt;co2_equivalent,
            output-&gt;co2_accuracy);

    printf("breath_voc_equivalent = %.2f ppm (%d)\r\n",
            output-&gt;breath_voc_equivalent,
            output-&gt;breath_voc_accuracy);

    printf("\r\n\n");
}</code></pre>

<p>蓝牙广播成功:</p>

<p></p>

<p><span style="font-size:16px;">接下来,就是另一个设备进行扫描。</span></p>

<p><span style="font-size:16px;">找到扫描广播刷新的回调函数【SCAN_ScreenUpdateTimeout】,设置&ldquo;RSL&rdquo;为接收蓝牙广播设备的合法名称。</span></p>

<pre>
<code class="language-cpp">void SCAN_ScreenUpdateTimeout(void)
{
    /* VT100 codes for clearing the screen. Works on VT100 terminals only */
    /* Clear ("\033[2J") and move cursor ("\033[0;0H") */
    SCAN_UART_SendString("\033[2J\033[0;0H");
    SCAN_UART_SendString("Scanned devices:\n");

    for (int i = 0; i &lt; adv_report_list_size; i++)
    {
            const uint8_t target_name[] = {'R', 'S', 'L'};
      if(memcmp(target_name, &amp;adv_report_list.data, 3) == 0)
      {
              //Weather_info.rssi_value        = 150 + adv_report_list.rssi;                //信号强度
                        //Weather_info.activity         = adv_report_list.data;        //活动状态
                        //Weather_info.temp_value         = adv_report_list-&gt;data;        //温度
                        //Weather_info.humidity                 = adv_report_list-&gt;data;        //湿度
                        //Weather_info.light_value         = adv_report_list-&gt;data;        //光照强度
              oled_config_refresh(adv_report_list.data);
      }

#if 0
      const uint8_t* addr = adv_report_list.adv_addr.addr;
      /* Create a UART string entry with device index, rssi, address, device name */
      /* Indicate which device was selected for a connection */
      snprintf(uart_tx_buffer, UART_TX_BUFFER_SIZE,
               "[ ] %02d | %02d dBm | 0x%02x%02x%02x%02x%02x%02x | %s\n", i+1, adv_report_list.rssi,
               addr, addr, addr, addr, addr, addr, adv_report_list.data);

      if(i == device_selection)
      {
            uart_tx_buffer = 'X';
      }

      SCAN_UART_SendString(uart_tx_buffer);
#endif

    }

    SCAN_UART_SendString("\nConnected devices:\n");

    for(uint8_t i = 0, j = 1; i &lt; BLE_CONNECTION_MAX; i++)
    {
      if(GAPC_IsConnectionActive(i))
      {
            const uint8_t* addr = GAPC_GetConnectionInfo(i)-&gt;peer_addr.addr;
            /* Create a UART string entry with device index, rssi, address, device name */
            /* Indicate which device was selected for a connection */
            snprintf(uart_tx_buffer, UART_TX_BUFFER_SIZE,
                     "%02d | 0x%02x%02x%02x%02x%02x%02x \n", j++,
                     addr, addr, addr, addr, addr, addr);

            SCAN_UART_SendString(uart_tx_buffer);
      }
    }
}</code></pre>

<p>&nbsp;</p>
页: [1]
查看完整版本: 【小型家用气象站】探索RSL10蓝牙广播