0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用ESP32的一键配网

CHANBAEK 来源:编程圈子 作者:编程圈子 2023-03-26 17:15 次阅读

一、ESP32 配网简介

ESP32主要有以下配网方式:

1. SmartConfig

采用组播/广播方式,将WIFI信息编码到IEEE802.11底层通讯帧实现配网。

  • 优点:易于使用,用户只需要通过 APP 将配置信息发送给设备即可。
  • 缺点:需要额外的 APP,有一定的安全风险,不支持 WPA3 安全协议。

2. SoftAp 配网

配网时将ESP32置于AP热点模式,手机连接此热点建立通讯,把WIFI账号和密码发给模块。

3. AirKiss

微信提出的一种配网方式,支持通过微信小程序配网。

4. 蓝牙配网

通过低功耗蓝牙来传输WIFI账号与密码实现配网。

5. 其它配网方式

  • ESP32 Easy ConnectTM(DPP) 配网:支持NFC等辅助配网;
  • NFC辅助配网:需要增加支持NFC的芯片
  • 直接配网:通过SPI,UART,I2C,SDIO等接口传输配网信息;
  • WPS路由器配网;
  • 零配网:ZeroConfig,通过一台已配网设备给另一台设备配网;
  • 手机AP配网:手机启动AP热点,让模块连接此热点实现配网。

二、使用ESP32的一键配网

ESP32的example有完整的SmartConfig demo,可以直接创建项目使用。

1. 流程分析

配网主要执行以下流程:

(1)初始化网络接口并为应用程序创建事件组。

ESP_ERROR_CHECK(esp_netif_init());
    s_wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK(esp_event_loop_create_default());

(2)注册事件处理函数

为 WIFI_EVENT、IP_EVENT 和 SC_EVENT 注册事件处理函数。

ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );
    ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );
    ESP_ERROR_CHECK( esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );

(3)启动 WiFi 站点模式

设置站点模式的事件处理函数。

(4)创建 smartconfig 任务

当使用STA模式时,连接到WiFi网络时触发事件 WIFI_EVENT_STA_START ,这时创建一个名为“smartconfig_example_task”的新任务。

(5)查找到信道事件

当 SC_EVENT_FOUND_CHANNEL 事件被触发时,表示 smartconfig 已经找到一个信道。一键配网一般通过先找到信道、再通讯的方式以提高配网效率 。

(6)获取到SSID和密码事件

当 SC_EVENT_GOT_SSID_PSWD 事件被触发时,就可以从事件数据中获取 SSID 和密码,配置 WiFi 接口并连接到 AP。

这时要记录 SSID 和密码,如果 smartconfig 类型为 ESPTOUCH_V2,则获取 RVD_DATA 并记录它。

(7)记录WIFI已经连接

在“smartconfig_example_task”函数中,将 smartconfig 类型设置为 SC_TYPE_ESPTOUCH,启动 smartconfig,并等待事件组中的 CONNECTED_BIT 和 ESPTOUCH_DONE_BIT。

如果两个位都设置了,则记录一条消息,指示 WiFi 已连接并且 smartconfig 已结束。停止 smartconfig 并删除任务。

(8)调用

在 app_main 函数中初始化 NVS 闪存并调用 initialize_wifi 函数。

2. 源码

/* Esptouch example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include 
#include 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_wpa2.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_smartconfig.h"

/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t s_wifi_event_group;

/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
static const int CONNECTED_BIT = BIT0;
static const int ESPTOUCH_DONE_BIT = BIT1;
static const char *TAG = "smartconfig_example";

static void smartconfig_example_task(void * parm);

static void event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        esp_wifi_connect();
        xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {
        ESP_LOGI(TAG, "Scan done");
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
        ESP_LOGI(TAG, "Found channel");
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
        ESP_LOGI(TAG, "Got SSID and password");

        smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;
        wifi_config_t wifi_config;
        uint8_t ssid[33] = { 0 };
        uint8_t password[65] = { 0 };
        uint8_t rvd_data[33] = { 0 };

        bzero(&wifi_config, sizeof(wifi_config_t));
        memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));
        memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password));
        wifi_config.sta.bssid_set = evt->bssid_set;
        if (wifi_config.sta.bssid_set == true) {
            memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid));
        }

        memcpy(ssid, evt->ssid, sizeof(evt->ssid));
        memcpy(password, evt->password, sizeof(evt->password));
        ESP_LOGI(TAG, "SSID:%s", ssid);
        ESP_LOGI(TAG, "PASSWORD:%s", password);
        if (evt->type == SC_TYPE_ESPTOUCH_V2) {
            ESP_ERROR_CHECK( esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data)) );
            ESP_LOGI(TAG, "RVD_DATA:");
            for (int i=0; i<33; i++) {
                printf("%02x ", rvd_data[i]);
            }
            printf("\\n");
        }

        ESP_ERROR_CHECK( esp_wifi_disconnect() );
        ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
        esp_wifi_connect();
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
        xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
    }
}

static void initialise_wifi(void)
{
    ESP_ERROR_CHECK(esp_netif_init());
    s_wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );

    ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );
    ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );
    ESP_ERROR_CHECK( esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );

    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK( esp_wifi_start() );
}

static void smartconfig_example_task(void * parm)
{
    EventBits_t uxBits;
    ESP_ERROR_CHECK( esp_smartconfig_set_type(SC_TYPE_ESPTOUCH) );
    smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_smartconfig_start(&cfg) );
    while (1) {
        uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
        if(uxBits & CONNECTED_BIT) {
            ESP_LOGI(TAG, "WiFi Connected to ap");
        }
        if(uxBits & ESPTOUCH_DONE_BIT) {
            ESP_LOGI(TAG, "smartconfig over");
            esp_smartconfig_stop();
            vTaskDelete(NULL);
        }
    }
}

void app_main(void)
{
    ESP_ERROR_CHECK( nvs_flash_init() );
    initialise_wifi();
}

3. 执行效果

三、安卓端

1. ESP32提供的测试APP

2. 使用SDK

从官方找到下载地址:

https://www.espressif.com.cn/zh-hans/support/download/apps

下载 aar文件集成到自己项目中使用,主要是以下几步:

(1)添加Smart Config SDK库

设置build.gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

添加引用,esptouch:

implementation 'com.github.EspressifApp:lib-esptouch-android:1.1.1'

或 esptouch-v2

implementation 'com.github.EspressifApp:lib-esptouch-v2-android:2.2.1'

(2)添加权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

(3)API

EspTouch v1

// 创建任务实例
Context context; // Set Applicatioin context
byte[] apSsid = {}; // Set AP's SSID
byte[] apBssid = {}; // Set AP's BSSID
byte[] apPassword = {}; // Set AP's password

EsptouchTask task = new EsptouchTask(apSsid, apBssid, apPassword, context);
task.setPackageBroadcast(true); // if true send broadcast packets, else send multicast packets
// 设置回调
task.setEsptouchListener(new IEsptouchListener() {
    @Override
    public void onEsptouchResultAdded(IEsptouchResult result) {
        // Result callback
    }
});
// 执行任务
int expectResultCount = 1;
List

ESP touch v2

// 创建实例
Context context; // Set Application Context
EspProvisioner provisioner = new EspProvisioner(context);
// 设置监听 
EspSyncListener listener = new EspSyncListener() {
    @Override
    public void onStart() {
    }

    @Override
    public void onStop() {
    }

    @Override
    public void onError(Exception e) {
    }
};
// 发同步包
provisioner.startSync(listener); // listener is nullable

// 停止同步包
provisioner.stopSync();

// 开始
Context context; // Set Application Context
EspProvisioningRequest request = new EspProvisioningRequest.Builder(context)
                .setSSID(ssid) // AP's SSID, nullable
                .setBSSID(bssid) // AP's BSSID, nonnull
                .setPassword(password) // AP's password, nullable if the AP is open
                .setReservedData(customData) // User's custom data, nullable. If not null, the max length is 64
                .setAESKey(aesKey) // nullable, if not null, it must be 16 bytes. App developer should negotiate an AES key with Device developer first.
                .build();
EspProvisioningListener listener = new EspProvisioningListener() {
    @Override
    public void onStart() {
    }

    @Override
    public void onResponse(EspProvisionResult result) {
        // Result callback
    }

    @Override
    public void onStop() {
    }

    @Override
    public void onError(Exception e) {
    }
};
provisioner.startProvisioning(request, listener); // request is nonnull, listener is nullable

// 停止配网
provisioner.stopProvisioning();
// 关闭配网
provisioner.close()
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 蓝牙
    +关注

    关注

    114

    文章

    5765

    浏览量

    169796
  • nfc
    nfc
    +关注

    关注

    59

    文章

    1617

    浏览量

    180383
  • WIFI
    +关注

    关注

    81

    文章

    5286

    浏览量

    203265
  • 配网
    +关注

    关注

    0

    文章

    153

    浏览量

    9048
  • ESP32
    +关注

    关注

    17

    文章

    957

    浏览量

    17073
收藏 人收藏

    评论

    相关推荐

    STM32+ESP8266连接腾讯IOT微信小程序一键

    次我以智能锁为产品模型,在腾讯物联网平台创建个设备,使用STM32F103系统板+ESP8266+LED灯完成智能锁产品的模拟开发;用户设备端可以按下指定的按键进入模式,打开腾讯
    的头像 发表于 03-18 09:20 1.4w次阅读
    STM32+<b class='flag-5'>ESP</b>8266连接腾讯IOT微信小程序<b class='flag-5'>一键</b><b class='flag-5'>配</b><b class='flag-5'>网</b>

    ESP32C3 wifi失败的原因?

    1, 采用官方提供的at固件,固件版本V2.4.2; 2,发送AT+CWSTARTSMART进入WiFi,启动app; 问题:在2.4G和5G双频路由器下,部分路由器不能Wi
    发表于 06-26 06:00

    esp8266不能连接NETGEAR-WNDR3400v3路由器怎么解决?

    请问,esp8266不能使用一键 airkiss 连接NETGEAR-WNDR3400v3路由器,怎么解决?地点美国,已经试了5天,上百次了,
    发表于 07-09 06:33

    RT-Thread的助手小程序是否能用于esp32

    在论坛上看到rt-thread有个助手的小程序,最近产品要上esp32这个模块涉及到这个问题? 情况
    发表于 08-16 11:31

    请问ESP32-C3是否支持matter协议了? 可以通过softap方式吗?

    ESP32-C3是否支持matter协议了? 可以通过softap方式吗?
    发表于 02-10 06:22

    ESP32-C3是否支持matter协议? 可以通过softap方式吗?

    ESP32-C3是否支持matter协议了? 可以通过softap方式吗?
    发表于 03-03 08:12

    请问ESP32 wifi多频合找不到设备是何原因?

    请问ESP32 wifi多频合找不到设备是何原因?
    发表于 03-03 06:45

    请问ESP32-C3是否支持matter协议了? 可以通过softap方式吗?

    ESP32-C3是否支持matter协议了? 可以通过softap方式吗?
    发表于 03-08 08:18

    ESP8266一键烧写软件下载

    ESP8266一键烧写软件下载
    发表于 11-22 17:00 31次下载

    ESP32模组的主要特性

    WT-ESP32-DevKitC V4是款基于ESP32的小型开发板,集WIFI+蓝牙方案于体,板上模组绝大部分管脚均已引出,开发人员可根据实际需求,轻松通过跳线连接多种外围器件,
    发表于 11-04 14:54 3937次阅读

    ESP32音频开发板可实现Wi-Fi一键

    音频设备,成为率先爆发的智能平台入口。视频内容风口加速智能音频AI升级。 智能语音产品扩展了传统的使用场景,在会议、演讲、采访、直播场景中,这些功能的实现的核心,更需要颗专用MCU芯片。 ESP32具备卓越的性能和丰富的外设,集Wi-
    的头像 发表于 06-14 17:43 1720次阅读

    ESP32蓝牙用户指南

    电子发烧友网站提供《ESP32蓝牙用户指南.pdf》资料免费下载
    发表于 09-23 10:34 5次下载
    <b class='flag-5'>ESP32</b>蓝牙<b class='flag-5'>配</b><b class='flag-5'>网</b>用户指南

    鲲泓智能一键小程序正式上线 用户体验再升级

    为了满足用户的极致体验,提升产品的服务质量,鲲泓智能开发上线了一键微信小程序,并于近日发布运行。 小程序以其轻量化、便捷性等优势特点,成为智慧家居、智慧康养领域与用户交互的核心应用载体。作为
    发表于 02-22 10:53 275次阅读

    启明云端分享|ESP32-S3 Smartconfig一键教程

    启明云端作为乐鑫代理,直都尽最大可能做完善的教程能帮助更多的开发小伙伴快速上手各种应用;今天小明为大家带来ESP32-S3,Smartconfig一键
    的头像 发表于 09-16 10:57 6222次阅读
    启明云端分享|<b class='flag-5'>ESP32</b>-S3 Smartconfig<b class='flag-5'>一键</b><b class='flag-5'>配</b><b class='flag-5'>网</b>教程

    乐鑫ESP32_蓝牙用户指南

    乐鑫ESP32_蓝牙用户指南ESP32将天线开关、RFbalun、功率放大器、接收低噪声放大器、滤波器、电源管理模块等功能集于体。
    发表于 10-19 16:13 10次下载