乐鑫Esp32学习之旅 21 esp32蓝牙配网blufi的高度封装,集成简单、使用简单、容易上手,提高开发效率!(附带demo)
Posted on 2019-12-10 10:49 CoreHouse 阅读(933) 评论(0) 编辑 收藏 举报- 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。
1、 爬坑学习新旅程,虚拟机搭建esp32开发环境,打印 “Hellow World”。
2、 巧用eclipes编辑器,官方教程在在Windows下搭建esp32开发环境,打印 “Hellow World”。
3、 认识基本esp32的GPIO接口,开始点亮您的第一盏 LED和中断回调实现按键功能 。
4、体会esp32的强大的定时器功能, 实现定时2s闪烁一盏LED灯。
5、接触实践esp32的pwm宽度脉冲功能, 实现呼吸效果闪烁一盏LED灯。
6、smartConfig和微信airKiss在esp32的实现,一键配网轻松快捷连接路由器。
7、利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。
8、esp32上实现本地 UDP 客户端和服务端角色,在局域网内实现通讯。
9、esp32上实现本地 TCP 客户端和服务端角色,可断线重连原路返回数据。
10、乐鑫esp32 SDK编程利用rmt驱动ws2812七彩灯,实现彩虹渐变效果。
11、入门 乐鑫esp-adf 音频框架开发,esp32造一个蓝牙耳机,实现切换歌曲,获取歌曲信息等功能。
12、开源一个微信公众号airkiss配网esp32以及局域网发现功能的工程,分享一个airkiss配网小工具。
13、esp32 内置 dns 服务器,无需外网访问域名返回指定网页。
14、esp32 sdk编程实现门户强制认证,连接esp32热点之后,自动强制弹出指定的登录界面。
15、认识本地离线语音唤醒识别框架 esp-skainet ,实现较低成本的硬件语音本地识别控制。
16、学习本地语音唤醒离线识别框架 esp-skainet ,如何修改唤醒词? 如何自定义命令词?如何做意图动作?
17、全网首发,乐鑫esp32 sdk直连京东微联·小京鱼 · IoT开放平台,实现叮咚音响语音智能控制。
18、入门京东微联·小京鱼的控制面板H5开发,读懂vue语法,做自己的控制页面。
19、重磅开源,如何在微信小程序上ble蓝牙配网esp32,blufi的那些事!
20、一篇好文,开发过程中编译esp32固件太大,无法正常启动?教你如何自定义分区表partitions.csv。
21、 esp32蓝牙配网blufi的高度封装,集成简单、使用简单、容易上手,提高开发效率!
一、前言;
配置esp32模块连接路由器是个必不可少的环节,做过了smartConfig配置,封装过微信airkiss配网,上几个月用官网的蓝牙配网例子,感觉太强大、太臃肿了,今天再做一个蓝牙配网的组件轮子,大大节省开发时间,提高开发效率;
“造轮子”是什么意思?我可以从中获取什么?
- 接口太复杂,不知道怎么用,搞明白太难!
- 需要在老轮子上添加新功能,然而老轮子代码难读无人可问,不知道何时能弄明白,看不到结果,容易放弃 眼界有限,不知道已有这样的轮子
- 就想锻炼自己,因为造轮子对自己的设计、编码能力有很大好处,对理解业务也有很大好处。
- 自己造轮子,有“控制感”,看得见摸的着,可以一步一步来,一个一个小目标迭代出大目标,不断成功的小激励,会带给自己前行编程的动力;
二、封装过程;
配网的目的就是让模块连接路由器,而少不了监听系统的wifi事件栈,一开始,我是想把监听wifi事件栈一度封装加密了,但是想想不太好,因为监听wifi事件栈也是非常常见的业务,于是乎,我还是把其提取出来让用户通知封装库吧!这样,就不用多处监听wifi事件栈的触发回调了!
运行流程:
当蓝牙连接、数据接收与数据处理完全独立,我们的业务就变得非常灵活复用,就可以完全让开发者做其自己的业务,这也达到了我造轮子的目的:灵活简单,高度解耦!
三、集成过程;
首先,你得有esp32开发环境,这个库建立在 master 分支上。
把《xBlufi》文件放在你的组件下面,下面开始集成:
首先调用: xBlufi_start();
开启配网流程,等待客户端连接!
之后,就可以监听封装库的全部事件了;
while (1)
{
if (xBlufiReceiveMsg(&msg))
{
ESP_LOGI(TAG, "ReceiveMsg %d", msg.type);
switch (msg.type)
{
case xBlufi_MSG_TYPE_NOTIFY_CONNECT_ACK:
//停止,释放内存
// xBlufi_stop_all();
// vTaskDelete(NULL);
break;
case xBlufi_MSG_TYPE_SATRT:
ESP_LOGI(TAG, "BLUFI deinit finish");
//初始化后设置任意蓝牙名字,不能大于16个字节
const uint8_t *addr = esp_bt_dev_get_address(); //查询蓝牙的mac地址,务必要在蓝牙初始化后方可调用!
sprintf(blufiName, "BLUFI_%02x%02x%02x", addr[0], addr[2], addr[5]);
XBlufi_notify_set_blufi_name(blufiName, strlen(blufiName));
break;
case xBlufi_MSG_TYPE_GET_BSSID: // 成功获取路由器mac地址
ESP_LOGI(TAG, " get bssid[len:%d]: %s", msg.dataLen, (char *)msg.data);
break;
case xBlufi_MSG_TYPE_GET_SSID: // 成功获取路由器名字
ESP_LOGI(TAG, " get ssid[len:%d]: %s", msg.dataLen, (char *)msg.data);
memcpy(wifi_config.sta.ssid, (char *)msg.data, msg.dataLen);
break;
case xBlufi_MSG_TYPE_GET_PASSWORD: // 成功获取路由器密码
ESP_LOGI(TAG, " get password[len:%d]: %s", msg.dataLen, (char *)msg.data);
memcpy(wifi_config.sta.password, (char *)msg.data, msg.dataLen);
break;
case xBlufi_MSG_TYPE_RECIEVE_CUSTON_DATA: //接收到了自定义的数据
{
ESP_LOGI(TAG, " get custon data[len:%d]: %s", msg.dataLen, (char *)msg.data);
//把接收到的自定义数据,原封不住返回回去给手机
XBlufi_notify_send_custom_data((uint8_t *)msg.data, msg.dataLen);
//如果发送是 stop 则断开连接
if (strcmp("stop", (char *)msg.data) == 0)
{
xBlufi_stop_all();
vTaskDelete(NULL);
}
break;
}
case xBlufi_MSG_TYPE_REQ_CONNECT_TO_AP: //手机要求接入热点
//连接路由器
ESP_ERROR_CHECK(esp_wifi_disconnect());
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_connect());
break;
case xBlufi_MSG_TYPE_REQ_DISCONNECT_TO_AP: //手机要求断开当前热点的接入
esp_wifi_disconnect();
break;
default:
break;
}
}
}
其次,还要把系统的Wifi事件栈回调通知封装库:
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
//wifi_mode_t mode;
ESP_LOGD(TAG, "system_event_handler, event_id: %d", event->event_id);
switch (event->event_id)
{
case SYSTEM_EVENT_STA_START:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
esp_wifi_set_auto_connect(false);
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
XBlufi_notify_got_ip(); //通知获取到了ip
break;
case SYSTEM_EVENT_STA_CONNECTED:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_CONNECTED");
XBlufi_notify_connected(event->event_info.connected.bssid); //连接成功路由器,发送路由器的mac地址
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
{
system_event_sta_disconnected_t *disconnected = &event->event_info.disconnected;
ESP_LOGI(TAG, "flagBlufiMode: %d ,SYSTEM_EVENT_STA_DISCONNECTED, reason: %d", flagBlufiMode, disconnected->reason);
//这里处理为了区别是否密码错误而断开非配网指令要求断开连接
if (flagBlufiMode && (disconnected->reason == WIFI_REASON_CONNECTION_FAIL
|| disconnected->reason == WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT ))
{
esp_wifi_connect();
XBlufi_notify_connect_fail();
flagBlufiMode = false;
}
break;
}
default:
break;
}
return ESP_OK;
}
再贴下封装库回调的类型有哪些?
typedef enum
{
xBlufi_MSG_TYPE_SATRT = 0, // 开始
xBlufi_MSG_TYPE_GET_BSSID, // 成功获取路由器mac地址
xBlufi_MSG_TYPE_GET_SSID, // 成功获取路由器名字
xBlufi_MSG_TYPE_GET_PASSWORD, // 成功获取路由器密码
xBlufi_MSG_TYPE_REQ_CONNECT_TO_AP, //客户端要求连接热点
xBlufi_MSG_TYPE_REQ_DISCONNECT_TO_AP, //客户端要求断开连接热点
xBlufi_MSG_TYPE_RECIEVE_CUSTON_DATA, // 接收到自定义数据
xBlufi_MSG_TYPE_SEND_ACK_TO_WEICHAT_OVER, // 配网成功后,设备端发送配网成功的ack到微信端
xBlufi_MSG_TYPE_CONNECTED_BLE, // 与蓝牙客户端成连接
xBlufi_MSG_TYPE_DIS_CONNECT_BLE, // 与蓝牙客户端断开连接
xBlufi_MSG_TYPE_NOTIFY_CONNECT_ACK, // 通知蓝牙客户端已成功连接路由器
} xBlufiMsgType;
还支持发送自定义消息哦!
/**
* @description: 发送自定义数据,比如 Hellowold
* @param {type}
* @return:
*/
esp_err_t XBlufi_notify_send_custom_data(uint8_t *data, uint32_t len);
四、其他;
这个封装库我命名为《XBlufi》,希望大家多多提出 issues
,
现封装库已开源使用,GitHub地址:https://github.com/xuhongv/StudyInEsp32/tree/master/15_XBlufi
有任何疑问联系本人下方邮箱或加qq群或文章留言,不要私信我,我已经屏蔽私信!多多支持!
另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈!
- 玩转
esp8266
带你飞、加群付费QQ
群,不喜的朋友勿喷勿加:434878850 - 个人邮箱:xuhongv@yeah.net 24小时在线,有回必回复!
- esp8266源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp8266
- esp32源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp32
- 关注下面微信公众号二维码,干货多多,第一时间推送!
![](https://img-blog.csdnimg.cn/20191010143449457.png)