ESP32 非定向广播

ESP32 非定向广播

以下代码将用最简单的方式来展示 GATT 广播流程。 此方式并非适用于生产环境,仅仅用来理解ESP32的蓝牙非定向广播流程。 首先,包含广播程序需要的头文件 #include "esp_log.h" #include "esp_err.h" #include

以下代码将用最简单的方式来展示 GATT 广播流程。

此方式并非适用于生产环境,仅仅用来理解ESP32的蓝牙非定向广播流程。


首先,包含广播程序需要的头文件


#include "esp_log.h"
#include "esp_err.h"
#include "nvs_flash.h"

#include "esp_bt.h"             /* For bluetooth controller */
#include "esp_bt_main.h"        /* For bluedroid stack */
#include "esp_gap_ble_api.h"    /* For GAP */

首先包含需要的头文件。

设置需要的宏

#define ADVERTISING_TEST_TAG "ADVERTISING TEST"
#define DEVICE_NAME          "Moker's ESP32"
  • ADVERSITING_TEST_TAG: 为ESP_LOGI()/ESP_LOGE()函数提供一个打印标识。
  • DEVICE_NAME: 设置设备名称。

编写 ESP32 的 app_main()入口函数

打印自定义内容

ESP_LOGI(ADVERTISING_TEST_TAG, "--------------------------");
ESP_LOGI(ADVERTISING_TEST_TAG, "| Advertising test start |");
ESP_LOGI(ADVERTISING_TEST_TAG, "--------------------------");

定义接收函数返回值的变量

esp_err_t ret;
  • 此变量用来接收函数的返回值,从而判断函数执行状态。

初始化 nvs flash

    /* Initialize flash */
    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret = ESP_ERR_NVS_NEW_VRESION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);
    ESP_LOGI(ADVERTISING_TEST_TAG, "Initialized nvs flash.");

通过初始化操作,判断 nvs flash 中是否任存在空间,或者检查到新版本的 nvs flash ,则擦除整个 nvs flash,并重新初始化。

  • 有关 nvs flash 的详细内容,可在官网查询资料。

释放经典蓝牙控制器内存

ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));

初始化蓝牙控制器参数为缺省配置

esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();

初始化蓝牙控制器(物理层)

/* Initialize bluetooth controller */
ret = esp_bt_controller_init(&bt_cfg);
if (ret) {
    ESP_LOGE(ADVERTISING_TEST_TAG, "Bluetooth controller initialize failed, error code = %x", ret);
    return;
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Initialized bluetooth controller.");

创建一个蓝牙控制器配置,用BT_CONTROLLER_INIT_CONFIG_DEFAULT() 缺省配置。

以低功耗模式启动蓝牙控制器(物理层)

/* Enable bluetooth controller */
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
if (ret) {
    ESP_LOGE(ADVERTISING_TEST_TAG, "Bluetooth controller enable failed, error code = %x", ret);
    return;
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Enabled bluetooth controller.");

启动蓝牙控制器,选择低功耗模式,为后续蓝牙协议栈做准备。

初始化蓝牙协议栈 bluedroid

/* Initialize bluedroid */
ret = esp_bluedroid_init();
if (ret) {
    ESP_LOGI(ADVERTISING_TEST_TAG, "Bluedroid initialize failed, error code = %x", ret);
    return;
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Initialized bluedroid.");

启动 bluedroid 蓝牙协议栈

/* Enable bluedroid */
ret = esp_bluedroid_enable();
if (ret) {
    ESP_LOGE(ADVERTISING_TEST_TAG, "Bluedroid enable failed, error code = %x", ret);
    return;
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Enabled bluedroid.");

设置设备名称

/* Set device name */
esp_ble_gap_set_device_name(DEVICE_NAME);
ESP_LOGI(ADVERTISING_TEST_TAG, "Set device name: \"%s\"", DEVICE_NAME);

设置原始广播数据

/* Config raw advertisement data */ 
static uint8_t raw_adv_data[] = {
    0x02, 0x01, 0x06,
    0x02, 0x0A, 0xEB,
    0x03, 0x03, 0xAB, 0xCD
};
  • 广播数据详解:[[8. GATT 广播数据]]

配置原始广播数据

ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data));
if (ret) {
    ESP_LOGE(ADVERTISING_TEST_TAG, "Config raw advertisement data failed, error code = %x", ret);
}
ESP_LOGI(ADVERTISING_TEST_TAG, "Configure raw advertisement data success.");

设置广播参数

/* Config advertising parameters */
static esp_ble_adv_params_t adv_params = {
    .adv_int_min = 0x20,
    .adv_int_max = 0x40,
    .adv_type = ADV_TYPE_IND,
    .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
    .channel_map = ADV_CHNL_ALL,
    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};

开始广播

/* Start advertising */
while (true) {
    ret = esp_ble_gap_start_advertising(&adv_params);
    if (ret) {
        ESP_LOGE(ADVERTISING_TEST_TAG, "Start advertising failed, erorr code = %x", ret);
    }
    ESP_LOGI(ADVERTISING_TEST_TAG, "Start advertising success.");

    vTaskDelay(pdMS_TO_TICKS(100));
}

此处用一个无限循环来每隔 100ms 广播一次。

Comment