BT&BLE_Coexistence_Demo__CN.pages

Similar documents
<453A5CCEC4B5B55C C41CBAAB2F5D4C6BDD3BFDACAB9D3C3CBB5C3F756312E305F E646F63>

4B-ESP8266__AT Command Examples__CN.pages

ESP-TOUCH_User_Guide__CN.pages

ESP-Jumpstart

5A-ESP8266__SDK__SSL_User_Manual__CN.pages

ESP-PSRAM64_ESP-PSRAM64H_Datasheet__CN

ESP32_FAQs__CN

Nodemcu-32s WIFI 模组 V1 Nodemcu-32s 规格书 版本 V1 版权 2019 Copyright 2019 Shenzhen Ai-Thinker Technology Co., Ltd All Rights Reserved

Microsoft Word - SC700003SS1-SCICALA霜蝉云接口使用说明V1.0.1_ docx

威 福 髮 藝 店 桃 園 市 蘆 竹 區 中 山 里 福 祿 一 街 48 號 地 下 一 樓 50,000 獨 資 李 依 純 105/04/06 府 經 登 字 第 號 宏 品 餐 飲 桃 園 市 桃 園 區 信 光 里 民

CC213

穨_1_.PDF

标题

目 录 一 重 要 提 示... 3 二 公 司 主 要 财 务 数 据 和 股 东 变 化... 3 三 重 要 事 项... 8 四 附 录 / 28

构建 Bluetooth 移动应用 主讲人 : 任凯 微信 :kaiser-tech 2016 年 5 月 6 日 3

ESP32-LyraT_User_Guide__CN.pages

新・解きながら学ぶJava

概述

0C-ESP-WROOM-02_Datasheet_CN.pages

ESP-WROOM-02D_ESP-WROOM-02U_Datasheet_CN.pages

谚语阐因

PIC_SERVER (11) SMTP ( ) ( ) PIC_SERVER (10) SMTP PIC_SERVER (event driven) PIC_SERVER SMTP 1. E-

ESP8089_Datasheet__CN

Kubenetes 系列列公开课 2 每周四晚 8 点档 1. Kubernetes 初探 2. 上 手 Kubernetes 3. Kubernetes 的资源调度 4. Kubernetes 的运 行行时 5. Kubernetes 的 网络管理理 6. Kubernetes 的存储管理理 7.

公務員服務法第13條相關解釋彙整表

大陸教育部等6個部門公佈「現代職業教育體系建設規劃 ( 年)」規劃到2015年初步形成現代職業教育體系框架,到2020年基本建成「中國」特色現代職業教育體系

资 讯 速 递 台 基 于 大 数 据 的 学 校 督 导 评 估 系 统 建 设 上 海 市 闵 行 区 人 民 政 府 教 育 督 导 室 ( 摘 要 ) 闵 行 教 育 在 深 化 教 育 改 革 探 索 管 办 评 分 离 的 背 景 下, 把 教 育 督 导 评 估 系 统 建 设 作 为

B1

浙江师范大学2014年度毕业生就业质量报告

目 录 监 管 资 讯 2016 年 全 国 保 险 监 管 工 作 会 议 召 开...3 协 会 动 态 赤 峰 保 险 行 业 协 会 召 开 数 据 统 计 和 信 息 宣 传 总 结 表 彰 会 议...5 赤 峰 市 保 险 行 业 协 会 秘 书 处 召 开 2015 年 度 述 职

同 时, 采 取 提 供 新 闻 线 索 和 素 材 安 排 专 访 等 方 式 主 动 为 新 闻 媒 体 服 务, 为 采 访 报 道 活 动 创 造 便 利 条 件 建 设 网 络 信 息 发 布 平 台 2013 年 9 月 开 通 中 央 纪 委 监 察 部 网 站,2015 年 1 月

時間軸上的竹蓮記憶 學務主任 黃雅彙 我不是竹蓮國小的畢業校友 但對於身為新竹人的我來 說 仔細回想起來 似乎和竹蓮有著一種特別的緣分 對竹蓮國小最初的印象是在小學的時候 猶記得年幼的 我經過一段時日的啦啦隊舞蹈訓練後 老師便帶著我們從學 校步行到竹蓮國小來參加比賽 一踏入竹蓮校門 映入眼簾 的是黑

B1

Microsoft Word - 临政办发6.doc

概述

Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco

第 一 节 认 识 自 我 的 意 义 一 个 人 只 有 认 识 自 我, 才 能 够 正 确 地 认 识 到 自 己 的 优 劣 势, 找 出 自 己 的 职 业 亮 点, 为 自 己 的 顺 利 求 职 推 波 助 澜 ; 一 个 人 只 有 认 识 自 我, 才 能 在 求 职 中 保 持

Leica IC90 E Leica IC90 E: USB 20 HDMI 22 SD () CLR ( ) 30 CLR ( ) 31 EXPSURE () 32 RESLUTIN ( ) 33 SETUP CAMER

C6_ppt.PDF

Intruduction to the NGINX stream subsystem and OpenResty's support

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

工 作 热 点 庆 五 一 我 省 举 行 庆 五 一 暨 劳 模 表 彰 大 会 4 月 27 日 上 午, 广 东 省 庆 祝 五 一 国 际 劳 动 节 暨 劳 模 表 彰 大 会 在 广 州 举 行 省 委 书 记 胡 春 华, 省 委 副 书 记 省 长 朱 小 丹, 省 人 大 常 委

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

中文模板

新美大酒店开放平台SDK(.NET版)使用说明.pages

开原天气参加铁岭市“三公开”教研活动 暨开原市农村小学语文识字

「行政院及所屬各機關出國報告綜合處理要點」

城 乡 建 设 并 上 报 国 家 国 土 资 源 部 深 化 土 地 审 批 与 征 收 制 度 改 革, 建 立 联 系 省 市 县 国 土 资 源 部 门 的 建 设 用 地 远 程 报 批 系 统, 提 供 了 直 通 车 服 务 制 定 出 台 节 约 集 约 用 地 考 核 标 准 和

新・解きながら学ぶC言語

新版 明解C言語入門編

新・明解C言語入門編『索引』

production_testing_guide__CN.pages

EPSON

模量 100, 通用型 气相法硅橡胶 ( 续 ) RBB-70 系列 RBB-2100 系列 RBB 硅橡胶 RBB 硅橡胶 RBB 硅橡胶 RBB 硅橡胶 RBB 硅橡胶 RBB 硅橡胶 RBB 硅橡胶 R

响应式在iOS开发中的应用 For PDF

完 成 1.51 亿 元, 占 预 算 的 113.1%, 同 比 增 长 22.1% 分 县 ( 市 ) 完 成 情 况 : 东 乡 县 0.69 亿 元, 同 比 增 长 24.7%; 积 石 山 县 1.25 亿 元, 同 比 增 长 18.5%; 临 夏 县 1.48 亿 元, 同 比 增

ESP32-LyraTD-SYNA_User_Guide__CN

< Essential LEDtube > | < Philips >

云商城



ESP32_Bluetooth_Architecture__CN

mvc

EPSON

Microsoft Word - 01.DOC

epub 61-2

获取 Access Token access_token 是接口的全局唯一票据, 接入方调用各接口时都需使用 access_token 开发者需要进行妥善保存 access_token 的存储至少要保留 512 个字符空间 access_token 的有效期目前为 2 个小时, 需定时刷新, 重复


ebook 86-15

新版 明解C++入門編

ESP32-LyraTD-DSPG_User_Guide__cn

本实验需要用到两个特征值, 两个特征值的属性各不相同, 我们同样在 SimpleGATTProfile 中新建即可, 接下来就开始吧 新建特征值表 : 表 3.3 串口透传特征值属性 长度 属性 UUID 功能 (byte) SIMPLEPROFILE_CHA R6 15 可读可写 FFF6 服务器

江西省2015届高校毕业生

% % 43.13% % % % %

1

(Microsoft Word - Motion Program \270\305\264\272\276\363 \307\245\301\366 \271\327 \270\361\302\367.doc)

( 总 第 1124 期 ) 浙 江 省 人 民 政 府 主 办 2016 年 7 月 18 日 出 版 目 省 政 府 令 浙 江 省 行 政 执 法 证 件 管 理 办 法 ( 浙 江 省 人 民 政 府 令 第 346 号 ) (3) 省 政 府 办 公 厅 文 件 浙 江 省 人 民 政 府

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

esp32_at_instruction_set_and_examples_cn


Go构建日请求千亿微服务最佳实践的副本

( CIP) /. :, ( ) ISBN TP CIP ( 2005) : : : : * : : 174 ( A ) : : ( 023) : ( 023)


关于印发广东省“互联网+”现代农业行动计划( 年)的通知

untitled

untitled

<ADB6ADB1C25EA8FAA6DB2D4D56432E706466>

Microsoft PowerPoint - ch6 [相容模式]

机关团体 31 的步子迈得更实更好 报告 审议通过 中国共产党如皋市 落实到党的建设各个方面 以良好作风保障经济社会又好 十一届代表第四次会议决议 经济技术开发区 城北街 又快发展 省委督导组副组长汪以力到会指导 南通市委 道 如皋工业园区 如城街道 白蒲镇 搬经镇 市发改 督导组组长葛维先出席会议

第 14 行调用 of_demo_controller_register 注册 demo controller 驱动,xlate 函数设置的都是 of_demo_simple_xlate, 这个函数完成对 user 传来的参数的处理 1. int of_demo_controller_registe

EJB-Programming-3.PDF

跨領域學位學程

HD ( ) 18 HD ( ) 18 PC 19 PC 19 PC 20 Leica MC170 HD Leica MC190 HD 22 Leica MC170 HD Leica MC190 HD Leica MC170 HD

方針-C (供上網)

严 格 遵 守 党 的 政 治 纪 律 政 治 规 矩 组 织 纪 律 和 廉 政 纪 律 正 确 处 理 管 理 工 作 和 个 人 学 术 工 作 的 关 系, 全 身 心 投 入 学 校 管 理 工 作, 减 少 社 会 兼 职 和 学 术 活 动, 党 委 书 记 和 院 长 不 担 任 科

FY.DOC



Microsoft Word - PHP7Ch01.docx

台灣科學工業園區科學工業同業公會

Transcription:

ESP32 BT&BLE 双模 蓝 牙共存说明 版本 1.0 版权 2018

关于本 手册 本 文档为 ESP32 BT&BLE 双模蓝 牙共存说明 发布说明 日期版本发布说明 V1.0 首次发布 文档变更更通知 用户可通过乐鑫官 网订阅技术 文档变更更的电 子邮件通知 证书下载 用户可通过乐鑫官 网下载产品证书

目录 1. BT&BLE 共存结构图... 1 2. 流程说明... 2 2.1. 初始化流程... 2 2.2. 广播说明... 3 2.3. 连接流程... 3... 4 3.1. 初始化... 4 3.1.1. 初始化流程... 4 3.1.2. 初始化并使能 controller... 4 3.1.3. 初始化并使能 host... 4 3.1.4. 在 DEV_B 中初始化 BT SPP acceptor 和 GATT server... 5 3.1.5. 在 DEV_A 中初始化 BT SPP initiator 和 GATT client... 7 3.2. 连接... 10 3.3. 数据发送与接收... 11 3.4. 性能说明... 11

1. BT&BLE 共存结构图 1. BT&BLE 共存结构图 图 1-1. BT&BLE 共存系统结构图 Espressif 1/12

2. 流程说明 2. 流程说明 2.1. 初始化流程 DEV_A 上电后将初始化 BT SPP initiator 和 BLE GATT client 功能 初始化完成后, 开始查找经典蓝 牙 (SPP) 设备, 找到设备后进 行行连接 SPP 连接完成后开始搜索 BLE 广播, 搜索到设备后进 行行连接 DEV_A 配置如下图 2-1 所示 图 2-1. DEV_A 配置界 面 DEV_B 上电后将初始化 BT SPP acceptor 和 BLE GATT server 功能 初始化完成后, 经典 蓝 牙开始 inquire scan 和 BLE 广播, 等待被连接 DEV_B 配置如下图 2-2 所示 图 2-2. DEV_B 配置界 面 注意 : 在 menuconfig 中必须选中 Classic Bluetooth SPP 和 GATTC/GATTS 选项 Espressif 2/12

2. 流程说明 2.2. 广播说明 经典蓝 牙 inquiry scan 时的设备名称 (EIR 中 ) 与 BLE 广播时的设备名称可以是同 一个名称, 也可以是不不同名称 若需区分两者的设备名称,BLE 可以使 用 esp_ble_gap_config_adv_data_raw() 函数, 广播特定的蓝 牙设备名称 2.3. 连接流程 DEV_B 初始化完成后会 自动进 入 BT inquiry scan 状态, 并且进 行行 BLE 广播,DEV_A 的 BT SPP initiator 搜索到对应设备后进 行行连接, 然后再开始搜索 BLE 设备, 搜索到设备后进 行行连接 DEV_A 和 DEV_B 之间的通信, 请 见图 2-3 图 2-3. DEV_A 和 DEV_B 测试流程图 Espressif 3/12

3.1. 初始化 3.1.1. 初始化流程 esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); ESP_ERROR_CHECK( ret ); 3.1.2. 初始化并使能 controller esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); ESP_LOGE(BT_BLE_COEX_TAG, "%s initialize controller failed\n", func ); ret = esp_bt_controller_enable(esp_bt_mode_btdm); ESP_LOGE(BT_BLE_COEX_TAG, "%s enable controller failed\n", func ); 注意 : 这 里里如需使 用双模蓝 牙, 则必须将 controller 初始化为 ESP_BT_MODE_BTDM, 且在 menuconfig 中 选择相应的选项 3.1.3. 初始化并使能 host ret = esp_bluedroid_init(); ESP_LOGE(BT_BLE_COEX_TAG, "%s init bluetooth failed\n", func ); ret = esp_bluedroid_enable(); ESP_LOGE(BT_BLE_COEX_TAG, "%s enable bluetooth failed\n", func ); Espressif 4/12

3.1.4. 在 DEV_B 中初始化 BT SPP acceptor 和 GATT server Controller 和 host 初始化完成后, 则开始初始化 BT SPP 和 BLE GATT server: bt_spp_init() ble_gatts_init() 具体代码如下 : void bt_spp_init(void) { // 注册 SPP 的 callback esp_err_t ret = esp_spp_register_callback(esp_spp_cb); ESP_LOGE(BT_SPP_TAG, "%s spp register failed\n", func ); ret = esp_spp_init(esp_spp_mode); ESP_LOGE(BT_SPP_TAG, "%s spp init failed\n", func ); static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { switch (event) { case ESP_SPP_INIT_EVT: //SPP callback 注册成功后, 将返回 ESP_SPP_INIT_EVT 事件, 在此事件中设置蓝牙名称, 设置经典蓝牙 Scan 模式 ESP_LOGI(BT_SPP_TAG, "ESP_SPP_INIT_EVT\n"); esp_bt_dev_set_device_name(bt_device_name); esp_bt_gap_set_scan_mode(esp_bt_scan_mode_connectable_discoverable); esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME); case ESP_SPP_DISCOVERY_COMP_EVT: ESP_LOGI(BT_SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT\n"); //SPP 连接成功后, 将返回 ESP_SPP_OPEN_EVT 事件 case ESP_SPP_OPEN_EVT: ESP_LOGI(BT_SPP_TAG, "ESP_SPP_OPEN_EVT\n"); //SPP 断开后, 将返回 ESP_SPP_CLOSE_EVT 事件 case ESP_SPP_CLOSE_EVT: ESP_LOGI(BT_SPP_TAG, "ESP_SPP_CLOSE_EVT\n"); case ESP_SPP_START_EVT: ESP_LOGI(BT_SPP_TAG, "ESP_SPP_START_EVT\n"); case ESP_SPP_CL_INIT_EVT: Espressif 5/12

ESP_LOGI(BT_SPP_TAG, "ESP_SPP_CL_INIT_EVT\n"); case ESP_SPP_DATA_IND_EVT: #if (SPP_SHOW_MODE == SPP_SHOW_DATA) ESP_LOGI(BT_SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d\n", param->data_ind.len, param->data_ind.handle); esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len); #else gettimeofday(&time_new, NULL); data_num += param->data_ind.len; if (time_new.tv_sec - time_old.tv_sec >= 3) { print_speed(); #endif case ESP_SPP_CONG_EVT: ESP_LOGI(BT_SPP_TAG, "ESP_SPP_CONG_EVT\n"); case ESP_SPP_WRITE_EVT: ESP_LOGI(BT_SPP_TAG, "ESP_SPP_WRITE_EVT\n"); case ESP_SPP_SRV_OPEN_EVT: ESP_LOGI(BT_SPP_TAG, "ESP_SPP_SRV_OPEN_EVT\n"); gettimeofday(&time_old, NULL); default: static void ble_gatts_init(void) { esp_err_t ret = esp_ble_gatts_register_callback(gatts_event_handler); if (ret){ ESP_LOGE(BT_BLE_COEX_TAG, "gatts register error, error code = %x", ret); ret = esp_ble_gap_register_callback(gap_event_handler); if (ret){ ESP_LOGE(BT_BLE_COEX_TAG, "gap register error, error code = %x", ret); ret = esp_ble_gatts_app_register(profile_a_app_id); if (ret){ ESP_LOGE(BT_BLE_COEX_TAG, "gatts app register error, error code = %x", ret); ret = esp_ble_gatts_app_register(profile_b_app_id); if (ret){ ESP_LOGE(BT_BLE_COEX_TAG, "gatts app register error, error code = %x", ret); Espressif 6/12

esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500); if (local_mtu_ret){ ESP_LOGE(BT_BLE_COEX_TAG, "set local MTU failed, error code = %x", local_mtu_ret); xtaskcreate(notify_task, "notify_task", 2048, NULL, configmax_priorities - 6, NULL); gatts_semaphore = xsemaphorecreatemutex(); if (gatts_semaphore) { 注意 : GATTS 的相关 API 不不在这 里里 一 一说明, 具体可参考 ESP_IDF gatt_server demo 中的 GATT_SERVER_EXAMPLE_WALKTHROUGH.md 3.1.5. 在 DEV_A 中初始化 BT SPP initiator 和 GATT client Controller 和 host 初始化完成后, 开始初始化 BT SPP initiator 和 BLE GATT client: bt_spp_init(); ble_gattc_init() 具体代码如下 : void bt_spp_init(void) { esp_err_t ret = esp_bt_gap_register_callback(esp_bt_gap_cb); ESP_LOGE(SPP_TAG, "%s gap register failed\n", func ); // 注册 SPP callback, 注册成功后对应的 callback 中会有 ESP_SPP_INIT_EVT 事件回调 ret = esp_spp_register_callback(esp_spp_cb); ESP_LOGE(SPP_TAG, "%s spp register failed\n", func ); ret = esp_spp_init(esp_spp_mode); ESP_LOGE(SPP_TAG, "%s spp init failed\n", func ); static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) { switch(event){ // 搜索到的扫描结果会在 ESP_BT_GAP_DISC_RES_EVT 中, 查找符合条件的设备, 然后连接 Espressif 7/12

case ESP_BT_GAP_DISC_RES_EVT: ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_RES_EVT"); esp_log_buffer_hex(spp_tag, param->disc_res.bda, ESP_BD_ADDR_LEN); for (int i = 0; i < param->disc_res.num_prop; i++){ if (param->disc_res.prop[i].type == ESP_BT_GAP_DEV_PROP_EIR && get_name_from_eir(param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)){ if (strlen(remote_spp_name) == peer_bdname_len && strncmp(peer_bdname, remote_spp_name, peer_bdname_len) == 0) { memcpy(peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN); esp_spp_start_discovery(peer_bd_addr); esp_bt_gap_cancel_discovery(); case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: ESP_LOGI(SPP_TAG, "ESP_BT_GAP_DISC_STATE_CHANGED_EVT"); case ESP_BT_GAP_RMT_SRVCS_EVT: ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVCS_EVT"); case ESP_BT_GAP_RMT_SRVC_REC_EVT: ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVC_REC_EVT"); default: static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { switch (event) { case ESP_SPP_INIT_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT"); esp_bt_dev_set_device_name(excample_device_name); esp_bt_gap_set_scan_mode(esp_bt_scan_mode_connectable_discoverable); esp_bt_gap_start_discovery(inq_mode, inq_len, inq_num_rsps); case ESP_SPP_DISCOVERY_COMP_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT status=%d scn_num=%d",param- >disc_comp.status, param->disc_comp.scn_num); if (param->disc_comp.status == ESP_SPP_SUCCESS) { esp_spp_connect(sec_mask, role_master, param->disc_comp.scn[0], peer_bd_addr); case ESP_SPP_OPEN_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT"); //BLE 开始扫描 uint32_t duration = 30; Espressif 8/12

esp_ble_gap_start_scanning(duration); esp_spp_write(param->srv_open.handle, SPP_DATA_LEN, spp_data); gettimeofday(&time_old, NULL); case ESP_SPP_CLOSE_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT"); case ESP_SPP_START_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT"); case ESP_SPP_CL_INIT_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT"); case ESP_SPP_DATA_IND_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT"); case ESP_SPP_CONG_EVT: #if (SPP_SHOW_MODE == SPP_SHOW_DATA) ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT cong=%d", param->cong.cong); #endif if (param->cong.cong == 0) { esp_spp_write(param->cong.handle, SPP_DATA_LEN, spp_data); case ESP_SPP_WRITE_EVT: #if (SPP_SHOW_MODE == SPP_SHOW_DATA) ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT len=%d cong=%d", param->write.len, param- >write.cong); esp_log_buffer_hex("",spp_data,spp_data_len); #else gettimeofday(&time_new, NULL); data_num += param->write.len; if (time_new.tv_sec - time_old.tv_sec >= 3) { print_speed(); #endif if (param->write.cong == 0) { esp_spp_write(param->write.handle, SPP_DATA_LEN, spp_data); case ESP_SPP_SRV_OPEN_EVT: ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT"); default: Espressif 9/12

{ // 注册 callback 功能至 GAP esp_err_t ret = esp_ble_gap_register_callback(esp_gap_cb); if (ret){ ESP_LOGE(GATTC_TAG, "%s gap register failed, error code = %x\n", func, ret); // 注册 callback 功能至 GATTC ret = esp_ble_gattc_register_callback(esp_gattc_cb); if(ret){ ESP_LOGE(GATTC_TAG, "%s gattc register failed, error code = %x\n", func, ret); ret = esp_ble_gattc_app_register(profile_a_app_id); if (ret){ ESP_LOGE(GATTC_TAG, "%s gattc app register failed, error code = %x\n", func, ret); esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500); if (local_mtu_ret){ ESP_LOGE(GATTC_TAG, "set local MTU failed, error code = %x", local_mtu_ret); xtaskcreate(gattc_notify_task, "gattc_task", 2048, NULL, 10, NULL); 注意 : GATTC 代码相关 API 说明可以参考 ESP_IDF gatt_client demo 中的 gatt_client_example_walkthrough.md 3.2. 连接 DEV_A 在完成初始化后, 开始搜索经典蓝 牙设备, 搜索到设备后会在 esp_bt_gap_cb 函数中回调 ESP_BT_GAP_DISC_RES_EVT, 符合条件后调 用 esp_spp_start_discovery(peer_bd_addr) 连接设备 设备连接成功后会在 esp_spp_cb 函数中回调 ESP_SPP_OPEN_EVT, 在此事件中开始发送 SPP 数据, 计算 SPP 速率, 并开始搜索 BLE 设备 BLE 搜索到 广播后会回调 esp_gap_cb 函数中的 ESP_GAP_SEARCH_INQ_RES_EVT 事件, 找到符合条件的设备后使 用 esp_ble_gattc_open() 连接, 连接成功后会回调 gattc_profile_event_handler 中的 ESP_GATTC_CONNECT_EVT 事件 BLE 连接成功后会注册对端设备 GATT notification, 为后续的数据发送做准备 Espressif 10/12

3.3. 数据发送与接收 DEV_A SPP 连接以后使 用 esp_spp_write() 函数发送 SPP 数据并计算速率 DEV_A BLE 连接成功后, 注册对端设备的 GATT notification, 并开始监听, 接收 GATT notification 数据后会回调 gattc_profile_event_handler 中的 ESP_GATTC_NOTIFY_EVT 事件, 统计数据 长度并计算速率 DEV_B 的 SPP 被连接以后, 等待对端设备发送 SPP 数据 DEV_B BLE 被连接后, DEV_A 会使能 DEV_B 的 GATT notification DEV_B 在 GATTS init 时初始化了了 notify_task, 当 notify_task 检测到 GATT notification 被使能后, 调 用 esp_ble_gatts_send_indicate() 发送 GATT notification 数据 3.4. 性能说明 BT SPP 和 BLE 连接成功以后会 自动发送数据, 计算吞吐率 单独运 行行 BT SPP 的速率为 230 KB/s 左右, 单独运 行行 BLE 的速率为 40 KB/s 左右 ( 优化后有 90 KB/s) 目前, 在 BLE 中仅计算了了 GATT notification 的速率, 使 用当前的参数速率 BT SPP 120 KB/s BLE GATT notification 30 KB/s 左右,BT SPP 和 BLE GATT notification 的速率是可调的 具体可以通过调节 BLE 的连接参数, 发送 GATT notification 的 长度和频率调整 SPP 和 GATT 的吞吐量量 log, 请 见图 3-1 图 3-1. SPP 和 GATT 的吞吐量量 log Espressif 11/12

免责申明和版权公告本 文中的信息, 包括供参考的 URL 地址, 如有变更更, 恕不不另 行行通知 文档 按现状 提供, 不不负任何担保责任, 包括对适销性 适 用于特定 用途或 非侵权性的任何担保, 和任何提案 规格或样品在他处提到的任何担保 本 文档不不负任何责任, 包括使 用本 文档内信息产 生的侵犯任何专利利权 行行为的责任 本 文档在此未以禁 止反 言或其他 方式授予任何知识产权使 用许可, 不不管是明示许可还是暗示许可 Wi-Fi 联盟成员标志归 Wi-Fi 联盟所有 蓝 牙标志是 Bluetooth SIG 的注册商标 乐鑫 IoT 团队 www.espressif.com 文中提到的所有商标名称 商标和注册商标均属其各 自所有者的财产, 特此声 明 版权归 2018 乐鑫所有 保留留所有权利利