本帖最后由 reayfei 于 2021-7-18 23:26 编辑
低功耗蓝牙设备通过广播信道发现其他设备,一个设备进行广播,而另一个设备进行扫描。
总接一下,BLE蓝牙广播有两个基本特点,分别是:
1.广播包数据最大长度为31字节(这个在代码里也有体现)
#define ADV_DATA_LEN 0x1F
2.数据格式为长度(1字节)类型(1字节)数据(n字节)......
其中长度=n+1
我的作品计划使用sense_bme680_bsec例程为base,这个例程已经实现了bme680传感器的驱动,还需要将ble_peripheral_server_hrp例程中蓝牙广播的驱动向sense_bme680_bsec中进行移植。
设置广播内容的函数,这里我还添加了我需要广播出去的数据,如下所示:
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,
&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,
&app_adv_info.host.adv_data_len);
}
在串口打印数据的地方添加蓝牙广播的内容,这里需要注意的是,修改广播之后想让修改的内容广播出去需要先关闭广播然后再开启广播,这样蓝牙广播内容才能修改成功。
extern void HRPS_Setup(void);
void App_BsecOutputReady(bsec_env_output_struct *output)
{
uint32_t temp = output->temperature;
Broadcaster_Data[3] = temp; //温度
temp = output->humidity;
Broadcaster_Data[4] = temp; //湿度
temp = output->raw_pressure;
Broadcaster_Data[6] = temp/65535%256; //气压高位
Broadcaster_Data[7] = temp/256%256; //气压中位
Broadcaster_Data[8] = temp%256; //气压低位
GAPM_CancelCmd();
APP_SetAdvScanData();
HRPS_Setup();
HRPS_StartAdvertisement();
//printf("[2J"); // clear screen
printf("BSEC output:\r\n");
printf(" timestamp = %lu ms\r\n", (uint32_t)(output->timestamp / 1000000));
#ifdef APP_USE_ANSI_COLORS
printf(" iaq = " COLORIZE("%.0f", GREEN) " (%d)\r\n", output->iaq,
output->iaq_accuracy);
printf(" temperature = " COLORIZE("%.2f �C", RED) " (%d)\r\n",
output->temperature, output->temperature_accuracy);
printf(" humidity = " COLORIZE("%.2f %%", CYAN) " (%d)\r\n",
output->humidity, output->humidity_accuracy);
#else
printf(" iaq = %.0f (%d)\r\n", output->iaq, output->iaq_accuracy);
printf(" temperature = %.2f �C (%d)\r\n",
output->temperature, output->temperature_accuracy);
printf(" humidity = %.2f %% (%d)\r\n",
output->humidity, output->humidity_accuracy);
#endif /* APP_USE_ANSI_COLORS */
printf(" raw_pressure = %f Pa\r\n", output->raw_pressure);
printf(" co2_equivalent = %.2f ppm (%d)\r\n", output->co2_equivalent,
output->co2_accuracy);
printf(" breath_voc_equivalent = %.2f ppm (%d)\r\n",
output->breath_voc_equivalent,
output->breath_voc_accuracy);
printf("\r\n\n");
}
蓝牙广播成功:
接下来,就是另一个设备进行扫描。
找到扫描广播刷新的回调函数【SCAN_ScreenUpdateTimeout】,设置“RSL”为接收蓝牙广播设备的合法名称。
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 < adv_report_list_size; i++)
{
const uint8_t target_name[] = {'R', 'S', 'L'};
if(memcmp(target_name, &adv_report_list[i].data[0], 3) == 0)
{
//Weather_info.rssi_value = 150 + adv_report_list.rssi; //信号强度
//Weather_info.activity = adv_report_list.data[21]; //活动状态
//Weather_info.temp_value = adv_report_list->data[22]; //温度
//Weather_info.humidity = adv_report_list->data[23]; //湿度
//Weather_info.light_value = adv_report_list->data[24]; //光照强度
oled_config_refresh(adv_report_list[i].data[15]);
}
#if 0
const uint8_t* addr = adv_report_list[i].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[i].rssi,
addr[5], addr[4], addr[3], addr[2], addr[1], addr[0], adv_report_list[i].data);
if(i == device_selection)
{
uart_tx_buffer[1] = 'X';
}
SCAN_UART_SendString(uart_tx_buffer);
#endif
}
SCAN_UART_SendString("\nConnected devices:\n");
for(uint8_t i = 0, j = 1; i < BLE_CONNECTION_MAX; i++)
{
if(GAPC_IsConnectionActive(i))
{
const uint8_t* addr = GAPC_GetConnectionInfo(i)->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[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
SCAN_UART_SendString(uart_tx_buffer);
}
}
}
|