关于今日推文
【填坑和广播简介】
最近受到芯片涨价和断货的影响,公司几款批量的蓝牙产品都在寻找新方向,所以最近研究了几款蓝牙芯片的代码,主要面向应用,所以想顺带把ESP32的蓝牙也整理下,给想用ESP32的BLE部分的人抛个砖,谁知道ESP32的蓝牙和我想象的不太一样,不建议做BLE单品选择这个片子。这个以后文章中聊聊,聊回蓝牙产品何去何从。
我们几款产品一直用的是瑞昱(螃蟹)的RTL8762,当时搞的时候,原厂送的那个开发板叫“小蜜蜂”,我特别喜欢这个名字,因为小时候和蜜蜂干过架。螃蟹的片子平时量小不太好买,遇到现在这个情况更加不好买了,所以老大很久之前就想过要换。
替换方案我们的首选是Nordic,我们当时的做的新项目都是用的nrf52832,用起来非常舒服,SDK的demo也很丰富,基本上在demo的基础上改改,增加几个服务和特征就能解决项目。鬼知道这玩意受到疫情影响也断货涨价了。
所以近期受到出货压力,我们不得不重新选型,这一次我们的首选就是国产蓝牙芯片了,找了下,可选挺多了,例如:泰凌微、巨微、博通、汇顶,都有非常不错的BLE芯片,而泰凌微更是其中的佼佼者。说到这大家是不是觉得我们选择的是泰凌微?没有!!因为我们和沁恒的技术有点关系,能得到原厂的技术支持(协助解决次BUG,以后聊),所以默默的选择了沁恒的CH579,性能中等,用着非常舒服(可仿真,协议栈打包成lib,没有乱七八糟的下载操作,和单片机一样操作简单),价格也非常美丽。
不想知道协议栈具体工作
不想肯蓝牙协议规范文档
对蓝牙不太了解又不想深入研究的
偶尔做个项目要用
快速解决应用问题
只做从机(广播后被连接,然后交互数据)
用最直白的描述讲解BLE,所以当出现不规范的说法时,别见笑哈。
市面上大部分BLE产品都是作为广播者发送数据,被扫描者(例如手机)扫描到后,广播者可选择回复扫描应答包(也可不回)。
当扫描者(手机)切换到发起者(手机)发送连接请求后,BLE产品作为广播者发送连接应答。
连接成功后,发起者(手机)变主机(手机),广播者变从机(BLE产品),至此广播、扫描、连接流程结束,进入应用层数据交互。
此处有几个角色转换,而且整个过程是一切顺利,期间可能会出现很多异常情况,以后再说,初学者知道整个顺利的过程,入门再分析异常。
市面上很多关于广播的讲解,我写的大部分来源网络,修改掉其中特别难懂的,且不影响我们目标(做个BLE应用产品)的东西。
广播的类型一般分为四种:
可连接的非定向广播(Connectable Undirected ),BLE产品最常用的广播模式。做的大部分项目都是这个广播模式。
可连接的定向广播(Connectable Directed ),广播包中有广播者和发起者地址,并且广播事件必须每3.75ms重复一次,所以能够很快被发现,被连接。这种模式不常用。
不可连接的非定向广播(Non-connectable Undirected ),仅仅发送广播数据,最典型的应用场景是beacon。我做过一个beacon插座项目,广播插座的计量信息,然后做个扫描设备(网关),获取附近的插座信息。
可扫描的非定向广播(Scannable Undirected ),不能用于发起连接,但允许其他设备扫描该广播设备。这种模式不常用。
可连接的非定向广播
这是一种用途最广的广播类型,包括广播数据和扫描响应数据,它表示当前设备可以接受其他任何设备的连接请求。广播可以在没有被连接的情况下发送(在37,38,39信道循环发送),被连上后广播包就不发了,切换到从机了,和主机进行数据交互。
注意在一个广播事件中,前一个广播包的开始到相邻的下一个广播包的开始处的时间要小于等于 10ms 。以下几张图是广播时候,可能会遇到的事情。其实我们做应用的话都不用关心,只要配置好广播的几个参数和广播包数据,配置好扫描应答的数据,开启广播即可,但这是常识,了解下即可。
下图是只发送广播的示意图:
下图是发送广播包时候,收到扫描请求,并给出扫描应答的示意图:
下图是发送广播包结束,收到扫描请求,并给出扫描应答的示意图:
下图是发送广播包时候,收到连接请求的示意图:
BLE设备被连上后,就不发送包播包了。
不同的芯片不同的SDK,广播代码逻辑都是相同的,先配置广播参数,然后定义广播数据,最后开启广播,BLE就开始发送广播包了。
以下用ESP32的SDK举例:
ESP32的广播参数配置代码:
static void hci_cmd_send_ble_set_adv_param(void)
{
uint16_t adv_intv_min = 256; // 160ms
uint16_t adv_intv_max = 256; // 160ms
uint8_t adv_type = 0; // connectable undirected advertising (ADV_IND)
uint8_t own_addr_type = 0; // Public Device Address
uint8_t peer_addr_type = 0; // Public Device Address
uint8_t peer_addr[6] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85};
uint8_t adv_chn_map = 0x07; // 37, 38, 39
uint8_t adv_filter_policy = 0; // Process All Conn and Scan
uint16_t sz = make_cmd_ble_set_adv_param(hci_cmd_buf,
adv_intv_min,
adv_intv_max,
adv_type,
own_addr_type,
peer_addr_type,
peer_addr,
adv_chn_map,
adv_filter_policy);
esp_vhci_host_send_packet(hci_cmd_buf, sz);
}
ESP32的广播数据代码:(广播包数据最多31的字节)
static void hci_cmd_send_ble_set_adv_data(void)
{
char *adv_name = "ESP-BLE-HELLO";
uint8_t name_len = (uint8_t)strlen(adv_name);
uint8_t adv_data[31] = {0x02, 0x01, 0x06, 0x0, 0x09};
uint8_t adv_data_len;
adv_data[3] = name_len + 1;
for (int i = 0; i < name_len; i++) {
adv_data[5 + i] = (uint8_t)adv_name[i];
}
adv_data_len = 5 + name_len;
uint16_t sz = make_cmd_ble_set_adv_data(hci_cmd_buf, adv_data_len, (uint8_t *)adv_data);
esp_vhci_host_send_packet(hci_cmd_buf, sz);
}
ESP32开启广播代码:
static void hci_cmd_send_ble_adv_start(void)
{
uint16_t sz = make_cmd_ble_set_adv_enable (hci_cmd_buf, 1);
esp_vhci_host_send_packet(hci_cmd_buf, sz);
}
下一篇讲解下广播参数配置和广播数据的代码,讲讲每个参数的大致作用,遇到问题的时候方便修改修改。
市面上nordic的资料最多,我搜集了些,大家需要的话,自行下载。
公众号后台回复关键词【52832】,发送后收到链接即可下载。
举例:关键词【步进电机】
关注微信公众号