乐鑫Esp32学习之旅 21 esp32蓝牙配网blufi的高度封装,集成简单、使用简单、容易上手,提高开发效率!(附带demo)


  • 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。

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配网,上几个月用官网的蓝牙配网例子,感觉太强大、太臃肿了,今天再做一个蓝牙配网的组件轮子,大大节省开发时间,提高开发效率;

      “造轮子”是什么意思?我可以从中获取什么?

  1. 接口太复杂,不知道怎么用,搞明白太难!
  2. 需要在老轮子上添加新功能,然而老轮子代码难读无人可问,不知道何时能弄明白,看不到结果,容易放弃 眼界有限,不知道已有这样的轮子
  3. 就想锻炼自己,因为造轮子对自己的设计、编码能力有很大好处,对理解业务也有很大好处。
  4. 自己造轮子,有“控制感”,看得见摸的着,可以一步一步来,一个一个小目标迭代出大目标,不断成功的小激励,会带给自己前行编程的动力;

二、封装过程;

       配网的目的就是让模块连接路由器,而少不了监听系统的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
  • 个人邮箱:[email protected] 24小时在线,有回必回复!
  • esp8266源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp8266
  • esp32源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp32
  • 关注下面微信公众号二维码,干货多多,第一时间推送!
发布了152 篇原创文章 · 获赞 785 · 访问量 79万+

猜你喜欢

转载自blog.csdn.net/xh870189248/article/details/103469473