本文正在参加「金石方案 . 瓜分6万现金大奖」

前言

前面咱们现已入门了 GATT 的开发,更进一步,进行想要的数据通信 。

本来方案直接做一个蓝牙的小使用,首先得完结一下自己想要数据的传输,尽管咱们前面现已测验过示例的读写了,可是仍是发现一些问题,怎样传输自己想要的数据呢?

网上实在是没有现成的示例,博主只能自己一遍一遍测验,失利又失利,修正再修正,最终画了大半天时刻,总算是搞好了。

本文咱们来完结一下 GATT 的通讯,文中并不涉及蓝牙理论的专业各种剖析解说,博主也是蓝牙初学者, 只经过检查示例,检查源码进行的修正测验,成果是成功,能够完结自己传输自己想要的传感器数据。

关于了解蓝牙协议的同伴来说或许觉得太简单,由于没有太深化的理论支撑,博主的过程可能会走了弯路,还望了解。

我是矜辰所造成的,全网同名,尽量用心写好每一系列文章,不浮夸,不迁就,认真对待学常识的咱们,矜辰所造成的,金石为开!


1、通信问题考虑

仅仅依照自己实际的现象阐明考虑,只代表个人思路,不必定是正确的,所以仅供参考。

咱们意图是想用一个 characteristic 传输温湿度数据。首先能确保手机端能够接受到自己每次不同的想要发送的数据。

在咱们前面文章测验的过程中,尽管能够正常读取到数据,也能正常的写数据,看似依照自己界说的数据传输,可是存在一个问题,便是发送数据以后,读取到的数据会变成发送的数据:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

回头看了一下示例中的,READ事情:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

看到 gatt_server_service_table 示例中的 READ事情,啥也没做啊?这下疑问更多了,啥也没做手机怎样能收到数据?不是好歹得有个发送数据的函数?怎样才干传输不同的数据呢?

想起来咱们曾经在 gatt_server 示例中剖析过,想要发送什么数据在这个事情中写就能够了:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据
.

2、 怎样才干每次传输不同的数据

看了一下代码,新建了一个变量 rsp, 函数esp_ble_gatts_send_response也是有的,所以这个代码咱们直接仿制过来是没问题的,咱们来测验一下,直接仿制过来看一下是不是就固定了? 所以乎咱们改了下代码,如下图:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

这样咱们读数据,是不是每次都能够读到上面写的,然后设置一个变量,每次修正,就能够读到不同的数据了?

程序修正编译没有问题,下载测验,仍是老样子,没有改动,测验图就不重复放了,现象便是发送以后读取到的数据是自己发送的。

需求注意一下 LOG 输出的消息:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

第一次尝试失利!

琢磨了一阵子,考虑了一下想到了: 我想要传输数据,我应该使用一个单独的只读的 characteristic 用于数据传输,这样就不会被写的数据打扰了(在这个示例结构中是这样),对!

所以我不测验可读可写的 characteristic ,用示例中的只读 characteristic 测验:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

只读的 characteristic 思路是对的,可是使用 gatt_server 示例中的代码仍是不可,读到的仅仅初始化中的数据,这个数据是在初始化决议的,如同不太好改啊,怎样才干修正这个数据呢。

然后我又注意到,通知部分是临时界说的数组决议的值,不会由于写数据改动,然后想到通知部分的处理办法:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

我可不能够用通知这个地方的函数发送曩昔?不论行不可试一试再说!

修正代码:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

这儿仍是编译正常,在阐明测验成果之前,要说一下对 handle 的知道了解。

3、 对 handle 的知道

关于蓝牙的使用测验,咱们期初只介绍了基本概念在关于 ESP-IDF的示例咱们剖析也仅仅了解结构,设计离线和思路,函数意义咱们也没有深化解说,在本次测验过程中,由于测验这个问题,让我加深了某一小部分问题的了解,比如 handle 这个东西。

由于 WRITE 事情中有一句判断:

if (heart_rate_handle_table[IDX_CHAR_CFG_A] == param->write.handle && param->write.len == 2)

我要把这个用到 READ 事情中,所以看了看这部分代码,以前忽略的这些东西,略微了解了一些。

关于 handle 来说,如下图的总结:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

attribute 咱们前面说过,characteristic 每个值都是用 attribute 表达的:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

结合上面,关于咱们示例来说,对每个 characteristic 的办理都是经过这个 handle 来完结的,而这个 handle 在咱们示例中的对应关系为:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

上面的是枚举中,是不算 HRS_IDX_NB 仍是不算 IDX_SVC 不太清楚,图中这样不算 HRS_IDX_NB 从 0到 9 开端符号10个handle, 假如是不算 IDX_SVC , 从 1到 10开端符号也是 10 个handle 。

只需求记住的是 对 value 操作的值对应的 handle 即可,不论哪种方法,characteristic value 的 handle 值都不变,所以咱们完全能够确定自己要操作的是哪个 characteristic 的哪个特点,当然一般都是对 value 的操作。

4、继续尝试

完结上面剖析,咱们修正一下代码(上面贴出的代码中,忘了把 param->write.handle 改成 param->read.handle),咱们要操作的是 handle 为 45 的 B:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

作为测验还加了一句:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

编译正常,烧录测验一下:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

仍是有问题……

这样看来,使用示例中几个简单看上去能够发送的函数都不可,怎样办呢?

后来一会儿也不知道怎样办才好,去官方论坛查找相关问题,无果,不能吃现成的= =!

没办法,所以到官网去查找 gatt 相关的东西,尽管我也不知道要怎样找,翻看官网的函数 API ,感觉漫无意图的往下看,遽然看到一个函数,眼前一亮:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

5、测验成功

在官网看到的函数名称一看就知道什么东西,设置 characteristic 的值? …… …

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

… …

几乎便是醍醐灌顶,茅塞顿开:

读写得写,不便是对读 characteristic 的 value,写 characteristic 的 value ,初始化的时分给了 characteristic 一个 value,咱们能够正常读到,假如写了 characteristic ,便是改动了 value 的值,那么读到的数据当然是自己写的数据,咱们想要读自己的数据,就改动 characteristic 值就能够了!!!

所以立马看了看整函数,纳尼……………… 这么巧 (仍是自己太蠢了……)?

咱们前面2中方法测验的函数就在这个函数上面:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据
.

速度搞起! 这把必定行,立马修正测验起来:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

测验成果:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

先高兴一下,上成果:

ESP-IDF 蓝牙开发 之GATT 数据通信 — 发送自定义数据

改正来了!改正来了!

可是这儿注意一个细节,第一次读取 仍是原始的值,从第2次才改正来,阐明一个问题,便是读取的时分立马就取了其时 characteristic 的 value。

这个 ESP_GATTS_READ_EVT 事情应该是读取结束才会触发 。

这就阐明,假如咱们想要读取实时数据,不能在这个这个时刻触发后去修正数据,而应该在另外的地方把实时数据 更新到 characteristic 的 value ,比及客户端想要读取数据的时分,便是实时数据。

结语

本文其实算下来也算简单,首要要记住两个点:

每次的读取都是读取对应 characteristic 的 value,使用esp_ble_gatts_set_attr_value函数能够修正 characteristic 的 value 值。

ESP_GATTS_READ_EVT 事情是读取成功才会触发的。

好了,本文也算有必定收获,至少知道了怎样想要发送自界说数据,有了今日的测验基础,咱们下一篇文章就直接来更新使用 ESP32-C3 做蓝牙小使用了,小激动!

本文就到这儿,谢谢大家!