ESP32 IDF的蓝牙广播demo 说明 - MilkeZhang 的网络笔记

蓝牙广播多种不同类型的广播,其中:1. 1M phy extend adv使用1Mbps的PHY速率,可连接广播。2. 2M phy extend adv使用2MBps的PHY高速广播,可扫描。3. 1M phy legacy adv, ADV_IND1M 高速广播,4. coded phy extend advcoded phy广播,可连接。1. 参数设置首先需要定义发送广播需要的几个参数:定义

ESP32 IDF的蓝牙广播demo 说明

ESP32 IDF的蓝牙广播demo 说明

阅读:1045  点赞:0   留言:0


蓝牙广播多种不同类型的广播,其中:

1. 1M phy extend adv

使用1Mbps的PHY速率,可连接广播。

2. 2M phy extend adv

使用2MBps的PHY高速广播,可扫描。

3. 1M phy legacy adv, ADV_IND

1M 高速广播,

4. coded phy extend adv

coded phy广播,可连接。

1. 参数设置

首先需要定义发送广播需要的几个参数:

定义6个字节的地址:

// 定义一个 1M PHY 的地址
uint8_t addr_1m[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x01};

定义广播数据AD Structure

// 定义 1M PHY 的扩展广播数据
static uint8_t raw_adv_data_1m[] = {
        0x02, 0x01, 0x06, // 广播标志
        0x02, 0x0a, 0xeb, // 16 位厂商 ID
        0x11, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', // 设备名称
        'D', 'V', '_', '1', 'M'
};

定义启用广播的扩展参数

// 定义 1M PHY 的扩展广播参数
esp_ble_gap_ext_adv_t ext_adv[4] = {
    // 实例,持续时间,间隔
    [0] = {0, 0, 0}
};

定义扩展广播参数

esp_ble_gap_ext_adv_params_t ext_adv_params_1M = {
    .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE, // 广播类型为可连接
    .interval_min = 0x30, // 广播间隔最小值
    .interval_max = 0x30, // 广播间隔最大值
    .channel_map = ADV_CHNL_ALL, // 广播信道
    .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, // 过滤策略
    .primary_phy = ESP_BLE_GAP_PHY_1M, // 主要物理层
    .max_skip = 0, // 最大跳过次数
    .secondary_phy = ESP_BLE_GAP_PHY_1M, // 次要物理层
    .sid = 0, // 广播 ID
    .scan_req_notif = false, // 扫描请求通知
    .own_addr_type = BLE_ADDR_TYPE_RANDOM, // 自身地址类型
    .tx_power = EXT_ADV_TX_PWR_NO_PREFERENCE, // 发射功率
};

定义GAP事件

// 定义 GAP 事件处理函数
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    switch (event) {
    case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT:
        // 设置随机地址完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d", param->ext_adv_set_rand_addr.status);
        break;
    case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT:
        // 设置参数完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->ext_adv_set_params.status);
        break;
    case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT:
        // 设置广播数据完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d", param->ext_adv_data_set.status);
        break;
    case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT:
        // 设置扫描响应数据完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d", param->scan_rsp_set.status);
        break;
    case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT:
        // 启动广播完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d", param->ext_adv_start.status);
        break;
    case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT:
        // 停止广播完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d", param->ext_adv_stop.status);
        break;
    default:
        break;
    }
}

2. 启动广播流程

  1. 1.初始化蓝牙适配器
  2. 2.启用蓝牙控制器
  3. 3.初始化蓝牙协议栈
  4. 4.启用蓝牙协议栈
  5. 5.注册GAP事件
  6. 6.设置扩展广播参数
  7. 7.启动广播

3.源代码

/*
 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */

/****************************************************************************
*
* 本演示展示了 BLE GATT 服务器。它可以发送广播数据,被客户端连接。
* 运行 gatt_client 演示,客户端演示将自动连接到 gatt_server 演示。
* 客户端演示将在连接后启用 gatt_server 的通知。两个设备将交换数据。
*
****************************************************************************/


#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_bt.h"

#include "esp_gap_ble_api.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"

#include "sdkconfig.h"

#include "freertos/semphr.h"

#define LOG_TAG "MULTI_ADV_DEMO"

// 定义一个宏,用于发送消息并等待信号量
#define FUNC_SEND_WAIT_SEM(func, sem) do {        esp_err_t __err_rc = (func);        if (__err_rc != ESP_OK) {             ESP_LOGE(LOG_TAG, "%s, message send fail, error = %d", __func__, __err_rc);         }         xSemaphoreTake(sem, portMAX_DELAY); } while(0);
// 定义一个信号量,用于等待消息发送完成
static SemaphoreHandle_t test_sem = NULL;

// 定义一个 1M PHY 的地址
uint8_t addr_1m[6] = {0xc0, 0xde, 0x52, 0x00, 0x00, 0x01};

// 定义一个 1M PHY 的扩展广播参数
esp_ble_gap_ext_adv_params_t ext_adv_params_1M = {
    .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE, // 广播类型为可连接
    .interval_min = 0x30, // 广播间隔最小值
    .interval_max = 0x30, // 广播间隔最大值
    .channel_map = ADV_CHNL_ALL, // 广播信道
    .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, // 过滤策略
    .primary_phy = ESP_BLE_GAP_PHY_1M, // 主要物理层
    .max_skip = 0, // 最大跳过次数
    .secondary_phy = ESP_BLE_GAP_PHY_1M, // 次要物理层
    .sid = 0, // 广播 ID
    .scan_req_notif = false, // 扫描请求通知
    .own_addr_type = BLE_ADDR_TYPE_RANDOM, // 自身地址类型
    .tx_power = EXT_ADV_TX_PWR_NO_PREFERENCE, // 发射功率
};

// 定义 1M PHY 的扩展广播数据
static uint8_t raw_adv_data_1m[] = {
        0x02, 0x01, 0x06, // 广播标志
        0x02, 0x0a, 0xeb, // 16 位厂商 ID
        0x11, 0x09, 'E', 'S', 'P', '_', 'M', 'U', 'L', 'T', 'I', '_', 'A', // 设备名称
        'D', 'V', '_', '1', 'M'
};

// 定义 1M PHY 的扩展广播参数
esp_ble_gap_ext_adv_t ext_adv[4] = {
    // 实例,持续时间,间隔
    [0] = {0, 0, 0}
};

// 定义 GAP 事件处理函数
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    switch (event) {
    case ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT:
        // 设置随机地址完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, status %d", param->ext_adv_set_rand_addr.status);
        break;
    case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT:
        // 设置参数完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT, status %d", param->ext_adv_set_params.status);
        break;
    case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT:
        // 设置广播数据完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT, status %d", param->ext_adv_data_set.status);
        break;
    case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT:
        // 设置扫描响应数据完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT, status %d", param->scan_rsp_set.status);
        break;
    case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT:
        // 启动广播完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status %d", param->ext_adv_start.status);
        break;
    case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT:
        // 停止广播完成事件
        xSemaphoreGive(test_sem);
        ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT, status %d", param->ext_adv_stop.status);
        break;
    default:
        break;
    }
}

void app_main(void)
{
    esp_err_t ret;

    // 初始化 NVS
    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );

    // 释放经典蓝牙控制器
    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();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret) {
        ESP_LOGE(LOG_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    // 启用蓝牙控制器
    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret) {
        ESP_LOGE(LOG_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    // 初始化蓝牙协议栈
    ret = esp_bluedroid_init();
    if (ret) {
        ESP_LOGE(LOG_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    // 启用蓝牙协议栈
    ret = esp_bluedroid_enable();
    if (ret) {
        ESP_LOGE(LOG_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    // 注册 GAP 事件处理函数
    ret = esp_ble_gap_register_callback(gap_event_handler);
    if (ret){
        ESP_LOGE(LOG_TAG, "gap register error, error code = %x", ret);
        return;
    }

    vTaskDelay(200 / portTICK_PERIOD_MS);

    // 创建信号量
    test_sem = xSemaphoreCreateBinary();

    // 设置 1M PHY 的扩展广播参数
    FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_params(0, &ext_adv_params_1M), test_sem);

    // 设置 1M PHY 的扩展广播随机地址
    FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_set_rand_addr(0, addr_1m), test_sem);

    // 配置 1M PHY 的扩展广播数据
    FUNC_SEND_WAIT_SEM(esp_ble_gap_config_ext_adv_data_raw(0, sizeof(raw_adv_data_1m), &raw_adv_data_1m[0]), test_sem);

    // 启动所有广播
    FUNC_SEND_WAIT_SEM(esp_ble_gap_ext_adv_start(4, &ext_adv[0]), test_sem);

    return;
}

广播包信息

程序烧写运行后,可以通过手机蓝牙调试APP查看到广播信息

设备Services

连接设备后,可以看到两个默认的Servicecs,它们通用属性配置文件(GATT)服务,该服务用于在BLE设备上发现服务、特征和描述符。

  • 00001801-0000-1000-8000-00805f9b34fb:通用属性配置文件(GATT)服务,用于在 BLE 设备上发现服务、特征和描述符;
  • 00001800-0000-1000-8000-00805f9b34fb:通用访问配置文件(GAP)服务,用于管理 BLE 设备的连接和广播。它包括了设备名称、外观、首选连接参数和广播数据等信息。









编写于:2023/12/13 15:59:22
发布 IP 属地:广东省深圳市

版权声明

本站内容均来自网络转载或网友提供,如有侵权请及时联系我们删除!本站不承担任何争议和法律责任!


艾金森

每一个童年的梦想都值得用青春去捍卫!




用户地图 心情地图 日记地图 笔记地图 时间轴地图 投票地图 习题地图 你们的岩床实相及其可能的群组,太阳系,太空旅行,神经的改变和意识的交会18、19周Generated by ChatGPT兄妹日常2021年7月26日2007年星洲日报的文章来自2005年美国的华文报纸。满山的猴子我腚最红 的日记 2024/04/07 12:53:29兄妹日常2021年9月13日兄妹日常2021年8月2日jedahdohma 的日记 2024/03/12 09:28:06MosiS 的日记 2024/04/21 20:08:19今早早起了半小时(转发崔庆龙微博24-5-9 6:54 阴)织金洞外无洞天!#空气一少,医生的手术刀就在你的身体乱乱开刀106天后的重新登录归零2024/5/33月10日记兄妹日常2021年10月4日芊. 的日记 2024/05/01 20:12:46兄妹日常2021年10月6日3月16日记平庸之恶夏谢秋 的日记 2024/04/22 23:21:21《魔鬼代言人》龙升虎自闲 的日记 2024/02/24 08:54:25克服表达欲2024-02-11 日记【家族沟南烧烤】无病呻吟雪尽染 的日记 2023/12/27 23:08:47写给爷爷的信兄妹日常2021年8月14日000009-无悔100-211-无悔100-4圣诞兄妹日常2021年9月1日夏谢秋 的日记 2024/04/19 22:17:02平安夜2023年12月29日 星期五 晴 志愿者金台寺一个小确幸求求你别想心选姐了无条件的快乐和无根据的自信乱七八糟兄妹日常2021年7月31日夏谢秋 的日记 2024/06/12 22:45:17兄妹日常2021年8月13日浪子回头金不换 的日记 2024/03/22 17:12:19addition tokey4127 的日记 2024/01/14 23:02:60赛斯记录站The Triumph of Spitzjedahdohma 的日记 2024/06/09 21:02:40困惑虚无的重复日常夏谢秋 的日记 2024/05/18 23:05:27兄妹日常2021年9月28日兄妹日常2021年8月27日兄妹日常2021年9月8日2024年3月14日цитат из "Как Закалялась Сталь"2024-03-27 Web开发记录【后台强化 与 内部数据结构调整】兄妹日常2021年9月26日夏谢秋 的日记 2024/05/23 23:10:38Generated by ChatGPT直面恐惧~~~兄妹日常2021年9月6日Journey to Freedom随笔记4月7日兄妹日常2021年8月12日Prank and Orchester DesperationGenerated by ChatGPT夏谢秋 的日记 2024/04/20 22:33:57the Trigonometric Tango2023年12月27日 星期三 晴 心理咨询师 新人学习第3天鲸落. 的日记 2024/05/20 20:21:36兄妹日常2021年9月12日走吧FMSL/JiA 的日记 2024/01/20 14:23:182024-02-07 日记【哥斯拉的数学题】2024.4.10 论文准备投稿#2007年是星州日报最后一年写文3月18日记摔跤兄妹日常2021年9月7日一封不会寄出的信兄妹日常2021年9月5日兄妹日常2021年8月25日28/5/2024 和阿庆的小吵架3月30日记专业见习(5)1226兄妹日常2021年8月3日兄妹日常2021年10月16日夏谢秋 的日记 2024/06/14 21:18:11七宗罪Generated by ChatGPTjedahdohma 的日记 2024/05/28 14:47:34#十年如一日的煮一点都不焦的饭。兄妹日常2021年8月21日...【Datasheet】QMI8658A 六轴陀螺仪芯片笔记本扩展外屏【内存不足】判断题疑难点74-78 程序你想活出怎样的人生。【Datasheet】FD6288T 三个独立的半桥栅极驱动集成电路芯片感冒笔记1人间值得。20231227回家 近期周处除三害好吧20240426如果你是别人,你也会讨厌我的家用服务器被迫推移,新款服务器选择困难记清明出行。记录一下自己装电视支架的历程,踩雷经验分享无主题。契机。我不怕死亡。只害怕遗忘。证券短线波段SolidWorks装配体保存成零件方法混乱的一个月底。文章练习2标题怎么起。文章练习4哲理卡牌游戏玩家目的分析判断题疑难点66-67 图片音频文件春天吗。放弃这一次证券股投机,等待3个月之后的机会目标【用户意见】2024-05-17 【Bug的修复】【Datasheet】FE2.1 USB 2.0高速7端口集线器控制器【再一次为生在这个家庭而感到幸运】Better Man塔罗被禁了?!也许这样也不错。《健身先健脑》判断题疑难点43-57 基本办公软件【Datasheet】CH342K USB转双串口芯片jedahdohma 的笔记 2024/05/17 15:38:42为无知道歉,却又羡慕年少。哲理一辈子的底气。道具灵感不知道是想写日记还是笔记。把脑子重新捡起来。ad及时止损就是赚对吧。对吧。判断题疑难点28-34 不常用软件与工具操你妈的,你妈了个逼【2024年】个人家用电脑配置,NAS小服务器29/3/2024 和妈妈手机里大吵了一架C# <summary>注释实现换行我抠出来了!!!【用户意见】2024-03-24 【Bug的修复】《走遍德国》B2 S106阅读翻译练习判断题疑难点21-27 压缩与编码觉着活着没意思的,推荐一个视频。Matthew H. Kramer:《菲尼斯式的报应主义》节选翻译I铂鹿 的笔记 2024/06/10 11:48:09文章练习3casxsax 的笔记 2024/05/09 10:38:48刻意的伪装成不经意。赫兹伯格的卫生理论2024年6月19日Android Studio 【SeekBar】基本用法哲理【鱼露】调味料是什么【Datasheet】AX3071UA DC-DC电源判断题疑难点68-73 操作系统PRD产品需求文档 | 实例撰写指南【非原创】【Datasheet】Amlogic A311D AI芯片参数规格OC_角色_上簇观OC_角色_乱象OC_角色_窃贼小姐【Datasheet】SCT2A10STER DC-DC电源芯片判断题疑难点1-20 python编程相关练习1我爱我的国。我爱我的家。熊市末端持股策略,下跌何时结束。【Datasheet】SiC461, SiC462, SiC463, SiC464 DC-DC电源芯片判断题疑难点58-65 数字的表示20240512不想学外语的思考判断题疑难点35-42 计算机系统相关【Datasheet】地平线 旭日X3芯片箪食瓢饮。其乐无穷。Zachary Hoskins: Fair Play, Political Obligation, and Punishment节选翻译Android Studio 快捷键大全