ESP32-BLE-NIMBLE蓝牙透传DEMO

news/2025/10/24 8:54:54/文章来源:https://www.cnblogs.com/stupidpeng/p/19145479

最近在对ESP32-S3的蓝牙调试使用,现记录一些关于蓝牙的理解与使用例子方便后续回顾

因为ESP32-S3只支持BLE,先只对BLE进行了解

协议栈结构

对于蓝牙整体的协议栈能找到很多的图来表示
例如
ce61b586-ab40-413c-abdc-c973abe54b42
整体的蓝牙协议为分成了很多层
要完善掌握整个蓝牙协议是要花很多的功夫的,难点肯定也很多,对于当前直接使用蓝牙的应用来说,并不需要去了解,物理层的信号是如何传输
以及底层Controller层的实现,只需要了解Host层里面的部分概念,知道每部分是干嘛用的就可以了,方便在调用的代码的时候可以对应起来就可以。
可以代码跑起来,再根据实际需要再深入了解相关的部分,这样效率相对会更高一些
像实现简单的蓝牙透传的示例,前期只需进行简单的通信连接的话,只需要了解GATT,GAP的概念就可以了

GAP(Generic Access Profile)

主要负责处理,前期蓝牙连接,断开连接等操作的事件

GATT(Generic Attribute Profile)

应用的数据交换应该就是发生在这里
GATT包含Service而又包含Characteristic,且Service跟Characteristic都有自己的UUID,且不相互关联
Characteristic就是我们负责数据通信的最基本的单元,
通过去Characteristic去赋权限,并添加相应的响应操作就实现了最基本的数据读写
2f371bef-66c0-41da-919e-ea33a638ad2a

默认状态下,通知每一个蓝牙连都会带一个GAP的服务(包括读取蓝牙名字的Characteristic),以及一个GATT的默认服务(这个服务没有只针对透传的应用的话也是可以正常使用,会少于一些扩展性,这个扩展性如何实现暂不了解)

DEMO示例

工程中配置好相对BLE的配置,不然include头文件跟调用的时候会发生错误

4cc76952-c70c-476e-b872-bb89553cfe96

添加被主调用函数,完成相应的初始化及配置相关联

void app_ble_add_task(void)
{nimble_port_init(); //初始化必须,加载NIMBLE这个协议栈ble_hs_cfg.sync_cb = ble_app_on_sync; //同步回调,开启蓝牙初始相关操作,主要是设置名字跟发起广播,并添加GAP服务的状态响应函数,比如可以使系统知道当前的蓝牙连接状态ble_svc_gap_init(); // 默认GAP服务,主要是蓝牙名称的读ble_svc_gatt_init(); //默认GATT,这个函数不注册也可以正常使用ble_gatts_count_cfg(user_ble_svc_gatt_defs); //自定义的透传蓝牙服务,这个是主要添加的相关代码ble_gatts_add_svcs(user_ble_svc_gatt_defs);nimble_port_freertos_init(ble_spp_server_host_task); // 创建蓝牙响应任务xTaskCreate(ble_notify_task, "ble_notify_task", 4096, NULL, 5, NULL);//透传轮咨任务,不加这个任务也不影响读写的响应
}//esp32 示例代码,freertos的一个一直运行的响应任务
void ble_spp_server_host_task(void *param)
{MODLOG_DFLT(INFO, "BLE Host Task Started");/* This function will return only when nimble_port_stop() is executed */nimble_port_run();nimble_port_freertos_deinit();
}

初始同步函数的定义,主要是设置名称与广播类型设置,GAP状态回调绑定,并开启广播

#define BLE_NAME    "HELLO_BLE"
static void ble_app_on_sync(void)
{ESP_LOGI(TAG, "BLE host synced, start advertising");struct ble_gap_adv_params adv_params = {0};adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;struct ble_hs_adv_fields fields = {0};fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;fields.name = (uint8_t *)BLE_NAME;fields.name_len = strlen(BLE_NAME);fields.name_is_complete = 1;ble_gap_adv_set_fields(&fields);ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, ble_server_gap_event, NULL);
}//GAP回调设置,主要是告诉系统连接状态及状态更新后添加一些自定义的响应操作
static int ble_server_gap_event(struct ble_gap_event *event, void *arg)
{struct ble_gap_conn_desc desc;int rc;switch (event->type) {case BLE_GAP_EVENT_CONNECT:is_ble_connected = 1;current_conn_handle = event->connect.conn_handle;ble_gap_adv_stop();return 0;case BLE_GAP_EVENT_DISCONNECT:is_ble_connected = 0;ble_app_on_sync();//重新广播就可以,用重新广播的操作函数,会更合适一些return 0;case BLE_GAP_EVENT_CONN_UPDATE:return 0;case BLE_GAP_EVENT_ADV_COMPLETE:return 0;case BLE_GAP_EVENT_MTU:ESP_LOGI("BLE", "MTU update: conn_handle=%d mtu=%d",event->mtu.conn_handle,event->mtu.value);return 0;default:return 0;}
}

效果如下

4bae3f57-e1e5-4daa-a7b0-b890a24f55fb

自定义服务,及characteristics用于当前透传的蓝牙应用实现

需要赋值权限,读,写,NOTIFY

#define BLE_SVC_SPP_UUID16                  0xABF0
#define BLE_SVC_SPP_CHR_UUID16              0xABF1static const struct ble_gatt_svc_def user_ble_svc_gatt_defs[] = {{.type = BLE_GATT_SVC_TYPE_PRIMARY,.uuid = BLE_UUID16_DECLARE(BLE_SVC_SPP_UUID16),.characteristics = (struct ble_gatt_chr_def[]){{.uuid = BLE_UUID16_DECLARE(BLE_SVC_SPP_CHR_UUID16),.access_cb = ble_svc_gatt_handler,.val_handle = &current_notify_handle,.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_NOTIFY,},{0,}},},{0,},
};

效果如下

3b0c8e0d-55aa-48cb-b7d1-f3f2d06e2914

Characteristic读写回调响应

static int  ble_svc_gatt_handler(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{switch (ctxt->op) {case BLE_GATT_ACCESS_OP_READ_CHR:MODLOG_DFLT(INFO, "Callback for read");int read_id = 0x1234;uint8_t r_tmp[2];r_tmp[0] = read_id;r_tmp[1] = read_id >> 8;os_mbuf_append(ctxt->om, r_tmp, 2);break;case BLE_GATT_ACCESS_OP_WRITE_CHR:MODLOG_DFLT(INFO, "Data received in write event,conn_handle = %x,attr_handle = %x", conn_handle, attr_handle);int len = OS_MBUF_PKTLEN(ctxt->om);uint8_t w_tmp[100];os_mbuf_copydata(ctxt->om, 0, len, w_tmp);printf("receive data len:%d\n", len);for(int i = 0; i < len; i++){printf("0x%02x\n", w_tmp[i]);}break;default:MODLOG_DFLT(INFO, "\nDefault Callback");break;}return 0;
}

对于问询式的通信方式用读写方式可以实现基本通信,但用于透传这样的应用,这样就有些不太够用,需要客户端发起问询也可以返回数据

介于这个问题,需要添加一个NOTIFY的任务,实时的轮询等有数据就通过NOTIFY的形式将数据发送出去,不需要客户端发起读数据的请求
notify发送数据的时候,需要知道一个conn_handle跟一个notify_handle这两个值,这两个值相当于是关联操作的characteristic。
notity_handle是定义characteristic时定义的, conn_handle是连接的时候,或者读写响应的时候,可以记录出来,
具体的参数区别,目前对这些参数的含义还不是很了解,照这样用可以实现当前NOTIFY的数据传输,手机端需要开启NOTIFY的开关,就可以收到定时接收的数据

void ble_notify_task(void *arg)
{uint32_t counter = 0;while (1) {if (current_conn_handle != 0 && is_ble_connected) { // 已连接char msg[100];sprintf(msg, "Count: %lu\n", counter++);struct os_mbuf *om = ble_hs_mbuf_from_flat(msg, strlen(msg));ble_gatts_notify_custom(current_conn_handle, current_notify_handle, om);printf("Notify: %s\n", msg);}vTaskDelay(pdMS_TO_TICKS(1000)); // 每秒发一次}
}

效果如下

81343e8d8a9132b35a4bd7d18494af9f

总结

实现简单的透传DEMO,可以不用太了解蓝牙的协议栈的整体结构,有个初略的认识就可以,对相关概念有一点了解,先将代码跑起来就可以
像UUID,以及不同种类UUID的一些官方的资料,暂不了解,
官方对常用的一些应用服务,做了专门的UUID分配也需要去,做得识别好一些,也需要去了解这部分的内容,像当前的DEMO,手机上的应用并不能识别当前自定义服务ID
可以多查看下官方的DEMO代码,对修改代码有所帮助

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/944869.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

致敬1024,《手搓》轻量级EventBus

致敬1024,《手搓》轻量级EventBus一、.NET事件总线一般使用MediatR笔者手搓事件总线和MediatR对比一下二、事件处理的基本概念 1. 事件表示已经发生的事情,需要通知其他模块进行处理2. 事件发布器负责发布事件的对象3.…

2025年化工原料厂家推荐排行榜:双氧水/片碱/盐酸/磷酸/PAC/聚丙烯酰胺/消泡剂/阻垢剂等工业级化学品供应商精选

2025年化工原料厂家推荐排行榜:双氧水/片碱/盐酸/磷酸/PAC/聚丙烯酰胺/消泡剂/阻垢剂等工业级化学品供应商精选 一、行业背景与发展趋势 工业化学品作为现代制造业的基础原料,在国民经济中占据着举足轻重的地位。随着…

2025年10月深圳近视手术医生推荐榜:五强排行与选择要点

深圳白领小林每天戴隐形眼镜超过十小时,眼睛干涩到影响提案汇报;高三班主任陈老师因为镜片起雾,看不清学生举手;自由摄影师阿杰则担心高原拍摄时框架眼镜滑落。他们都在搜索同一组关键词:深圳近视手术医生。2024年…

2025年10月深圳近视手术医生推荐榜:朱少栋李伟力领衔对比

国庆后摘镜高峰将至,不少深圳上班族、准大学生和外地来深就医者开始集中比对近视手术医生。大家普遍关心:在公立三甲背景与民营专项机构之间,如何快速锁定手术量大、设备新、复查体系完整的医生?2024年深圳卫健委统…

数据库内部错误00600 故障处理

1.open数据库报ORA-00600[kcratr_nab_less_than_odr] SQL> ALTER DATABASE OPEN; ALTER DATABASE OPEN * 第 1 行出现错误: ORA-00600: 内部错误代码, 参数: [kcratr_nab_less_than_odr], [1], [99189], [43531], […

Docker镜像库配置

很多同学在执行DockerFile的时候,拉取一些jdk或其他的基础镜像超时失败。造成这个的主要原因就是Docker默认的镜像仓库是DockerHub,国内是连不上的,这时候我们就需,下面就是我整理好的,总有一个能拉取成功的。 如果你是…

ref和reactive和.value

在 Vue 3 中,您描述的这种需要通过 .value 来访问值的特性,是 ref 函数所独有的。reactive 函数创建的对象没有这种统一的 .value 属性,其属性是直接访问的。 下面这个表格清晰地展示了两者的核心区别。特性对比ref…

2025年工作服厂家推荐排行榜,防静电/劳保/国网/餐厅/工厂/电工/防酸碱/电力/车间/航空/员工工作服,文化衫/t恤/polo衫/冲锋衣/t恤衫公司精选

2025年工作服厂家推荐排行榜:防静电/劳保/国网等专业工装企业精选 在工业4.0时代背景下,工作服行业正经历着深刻变革。随着安全生产意识的提升和职场文化的演进,专业工作服已从简单的劳动保护用品,升级为集安全防护…

VSCode建立python虚拟环境

ctrl+shift+p打开命令行,选择: 然后选择: 之后选择存放虚拟环境的文件夹进行创建: 选择python版本:等待右下角创建完成微信搜索“Kconfig”,获取支持...

2025年10月深圳近视手术医生排名榜:五家医院真实数据对比

正在准备摘镜的你,也许已经翻遍社交平台,却被“全飞秒”“半飞秒”“ICL”绕得头晕;也许对比过价格,却发现同一术式报价相差数千元;更担心术后干眼、眩光、回退。深圳近视手术市场2025年预计年手术量突破12万例,…

2025年10月销毁公司推荐:森蓝领衔服务榜对比

把过期食品、瑕疵化妆品、积压文件或缺陷家电堆在仓库,不仅占地方,还可能因监管抽查被高额处罚;找回收站“一卖了之”,又担心流入二级市场带来品牌风险——这是生产、零售、电商、物流和公共机构在每年第四季度集中…

2025年危险品运输企业权威推荐榜:专业资质与安全口碑兼具的合规运输服务商精选

2025年危险品运输企业权威推荐榜:专业资质与安全口碑兼具的合规运输服务商精选 危险品运输作为特种物流领域的重要分支,其专业性和安全性要求远高于普通货物运输。随着我国化工产业的快速发展,危险品运输市场规模持…

P1600 [NOIP 2016 提高组] 天天爱跑步 分析

题目概述 题目链接:https://www.luogu.com.cn/problem/P1600。 给你一棵树,每个节点上有一个观察时间,现在有 \(m\) 个选手,选手会以每秒一个节点的速度,从 \(s_i\) 到 \(t_i\)。 求对于每个节点的观察时间能观察…

2025年10月上海装修公司推荐榜:千州装饰等五家深度对比

在上海这样的一线城市,装修不仅关乎居住舒适度,更直接影响房屋保值与生活质量。多数业主面临“预算有限、工期紧张、风格难定、增项频发”四大痛点,尤其在2025年三季度上海住宅成交环比回升12%的背景下,装修需求集…

2025年10月淡化痘印产品推荐对比:从色素代谢到修护通路全解析

痘印比痘痘更顽固,是多数人在“战痘”后期最耗心力的阶段。临床观察显示,炎症后色素沉着在东亚人群中发生率可达65%—80%,平均自然淡化周期3—6个月,若护理不当可延长至1年以上。2025年第三季度国家药监局《化妆品…

2025年10月上海装修公司对比榜:千州装饰等五强口碑解析

把钥匙交到装修公司手里,就像把未来生活的剧本交给导演:风格、预算、工期、环保、售后,任何一环掉链子,入住后都会变成“加长版遗憾”。上海家装市场年均开工量保持在12万套以上,2024年住宅装饰产值突破1100亿元,…

2025年10月敏感肌美白面霜推荐榜:淡斑修护综合排名

入秋以后,昼夜温差拉大,紫外线强度虽下降却更穿透,敏感肌人群常在换季期出现“红后反黑”——炎症褪去却留下顽固色沉。社交平台“美白+修护”关键词搜索量连续三周环比上升42%,其中“敏感肌可用”成为筛选首选项。…

SQL - 递归查询子节点

SQL - 递归查询子节点递归查询子节点:表a中有id, parent_id两个字段,parent_id存id的上一级id。请帮我写一个SQL语句,给定一个id,递归查询出所有子id,该id为第一列,后面每有一个子id增加一列。非常好,✅你的意思…

2025年10月色斑淡化产品对比榜:五款精华通路机制深度解析

入秋后紫外线强度虽降,但夏季累积的黑色素仍在表皮深处持续显色,不少人在10月前后首次发现色斑颜色加深或面积扩大。医美机构调研显示,每年9至11月咨询“居家淡斑”的消费者占比连续五年上升,2024年同比增长18.6%,…

2025年10月医美项目后用什么产品评测榜:术后舒缓精华口碑对比

刚做完光子、点阵或超皮秒,脸上又干又红,护肤品一抹就刺痛,这是不少医美用户的共同记忆。术后屏障暂时受损,外界刺激更容易引发色沉、反黑或持续潮红,选错护肤品等于把刚花出去的治疗费打折扣。国家药监局2024年医…