当前位置: 首页 > news >正文

ESP32-BLE-NIMBLE蓝牙透传DEMO

最近在对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.hskmm.com/?act=detail&tid=37805

相关文章:

  • 2025年10月深圳近视手术医生推荐榜:五强排行与选择要点
  • 2025年10月深圳近视手术医生推荐榜:朱少栋李伟力领衔对比
  • 数据库内部错误00600 故障处理
  • 2025年10月销毁公司推荐:森蓝领衔服务榜对比
  • 2025年危险品运输企业权威推荐榜:专业资质与安全口碑兼具的合规运输服务商精选
  • Docker镜像库配置
  • ref和reactive和.value
  • 2025年工作服厂家推荐排行榜,防静电/劳保/国网/餐厅/工厂/电工/防酸碱/电力/车间/航空/员工工作服,文化衫/t恤/polo衫/冲锋衣/t恤衫公司精选
  • 2025年10月淡化痘印产品推荐对比:从色素代谢到修护通路全解析
  • 2025年10月上海装修公司推荐榜:千州装饰等五家深度对比
  • 2025年10月上海装修公司对比榜:千州装饰等五强口碑解析
  • 2025年10月敏感肌美白面霜推荐榜:淡斑修护综合排名
  • 2025年10月色斑淡化产品对比榜:五款精华通路机制深度解析
  • 2025年10月医美项目后用什么产品评测榜:术后舒缓精华口碑对比
  • 题解:P4204 [NOI2006] 神奇口袋
  • 2025年超声波检测设备厂家权威推荐榜:相控阵/高频/水浸/液冷板/钎焊超声波检测系统,技术实力与选购指南深度解析
  • 一些c语言特殊用法
  • 2025年环氧板厂家推荐排行榜,环氧板加工,FR-4玻纤板,云母板,专业定制与优质材料供应商精选
  • 2025.10.24——1绿
  • 2025年精密弹簧厂家权威推荐榜单:压缩弹簧、拉伸弹簧、扭转弹簧、异形弹簧专业制造商综合评测与选购指南
  • PyQuokka框架存在Pickle反序列化远程代码执行漏洞
  • sql server查看所有表名以及注释
  • 2025年磨粉机厂家推荐排行榜,雷蒙磨粉机,环辊磨粉机,摆式磨粉机,矿石磨粉机,超细磨粉机,高压磨粉机,大型磨粉机公司推荐
  • 2025年润滑油厂家权威推荐榜:工业润滑油,汽车润滑油,发动机润滑油,甲醇发动机润滑油,三特/三球/安迪森润滑油,全合成润滑油,中国润滑油,长效发动机润滑油厂家精选
  • SQL Server 建表语句
  • 2025年氢氧化镁厂家权威推荐榜:矿石氢氧化镁/水镁石氢氧化镁/阻燃剂氢氧化镁/改性氢氧化镁源头企业综合评测与采购指南
  • SQL Server 报错引用了无效的表`表名`
  • 2025年粘度计厂家权威推荐榜:在线/旋转/振动/在线振动/在线旋转/实验室旋转/实验室在线/反应釜在线/管线在线振动/实验室振动粘度计专业选购指南
  • Nexpose 8.25.0 for Linux Windows - 漏洞扫描
  • 2025年冲压件厂家推荐排行榜,新能源冲压件,光伏冲压件,精密冲压件,异形冲压件,五金冲压件,铝冲压件,汽配冲压件,不锈钢冲压件,家具冲压件公司推荐