简介

smartconfig 直译过来就是智能配置,它是一种可以是wifi快速连接到网络的技术。可以省去直接将wifi账号和密码写入到无线设备中的过程,通过手机将无限设备连接到网络中去。 smartconfig只是无线连接的一种,乐鑫还支持airkiss 方式将设备连接到网络。 具体原理我就不过多介绍了,只是简单介绍一下esp32 如何通过smartconfig技术接入到网络中。

  • esp32 进入smartconfig模式:将自己设置成wifiAP模式,以UDP的模式将此信息广播出去,等待有wifi接入。
  • 打开手机中的esptouch app(乐鑫提供的smartconfig软件),输入wifi密码后开始搜索wifi信号
  • 搜索到esp32的wifi信号,通过wifi协议连接,此时手机app软件将手机当前所连接的wifi的账号密码发送给esp32
  • esp32 接收到wifi账号和密码后开始连接路由器,连接成功后,esp32和手机app断开连接.

具体的原理,可以上网上搜索

eps32 smartconfig API

1.esp32 关于smartconfig的API都定义在“esp_smartconfig.h”中,而且应用起来也十分方便

#ifndef __ESP_SMARTCONFIG_H__
#define __ESP_SMARTCONFIG_H__

#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"

#ifdef __cplusplus
extern "C" {
#endif
/* 配置状态标志,在实际操作总根据函数的配置状态标志来判断当前smartconfig所执行的阶段*/
typedef enum {
    SC_STATUS_WAIT = 0,             /**< 等待开始连接 */
    SC_STATUS_FIND_CHANNEL,         /**< 发现目标通道 */
    SC_STATUS_GETTING_SSID_PSWD,    /**< 获取到app发送回来 wifi账号和密码*/
    SC_STATUS_LINK,                 /**< 连接路由器 */
    SC_STATUS_LINK_OVER,            /**< 连接路由器成功 */
} smartconfig_status_t;

/*smartconfig 类型 乐鑫支持epstouch 和airkiss 两种wifi快连方式 根据这个标志判断使用哪种方式*/
typedef enum {
    SC_TYPE_ESPTOUCH = 0,       /**< 支持 ESPTouch */
    SC_TYPE_AIRKISS,            /**< 支持 AirKiss */
    SC_TYPE_ESPTOUCH_AIRKISS,   /**< 两种协议都支持 ESPTouch and AirKiss */
} smartconfig_type_t;

/**
  * @brief  回调函数,用于在smartconfig status 改变时 调用
  *
  * @param  status  Status of SmartConfig
  * @param  不同的staus pdata的值也不同.
  *
  */
typedef void (*sc_callback_t)(smartconfig_status_t status, void *pdata);
/**
  * @brief  获取当前smartconfig的版本
  *
  * @return
  *     - 返回值是一个数组指针,返回当前版本字符串指针的首地址
  */
const char *esp_smartconfig_get_version(void);
/**
  * @brief     开始 SmartConfig,通过手机app设置,在配置过程中,通过c_callback_t cb 回调函数,实时的判断当前smartconfig的状态
  * @return
  *     - ESP_OK: succeed
  *     - others: fail
  */
esp_err_t esp_smartconfig_start(sc_callback_t cb, ...);
/**
  * @brief     停止 SmartConfig,无论smartconfig 配置是否成功都应该调用这个函数,这个函数主要是释放smartconfig start 中 申请的 内存,我们知道对于单片机来说内存是很宝贵的,所以必须执行这个函数。 
  *
  * @return
  *     - ESP_OK: succeed
  *     - others: fail
  */
esp_err_t esp_smartconfig_stop(void);

/**
  * @brief    设置SmartConfig进程超时,从获取到SC_STATUS_FIND_CHANNEL标志开始计时,如果超时了SmartConfig就会重新开始。
  * @param     超时范围 15s~255s, offset:45s.
  *
  * @return
  *     - ESP_OK: succeed
  *     - others: fail
  */
esp_err_t esp_esptouch_set_timeout(uint8_t time_s);

/**
  * @brief  设置smarconfig的协议类型,ESPTOUCH还是AIRKISS。
  */
esp_err_t esp_smartconfig_set_type(smartconfig_type_t type);

#ifdef __cplusplus
}
#endif

#endif

应用实例

  1. 在手机上安装esptouch APP, ESP-TOUCH 是乐鑫自主研发的协议。采用的是 Smart Config(智能配置)技术。简单在app上操作就可以使esp32 或者esp8266 快速连接到wifi中。

esp32的ota流程是怎么样的 esp32 coap_网络

下载地址:https://www.espressif.com/zh-hans/products/software/esp-touch/resources

我使用的是在谷歌的安卓市场中下载esptouch,因为我在github下载最新的esptouch apk 在实际配网过程中总是配置失败不知道是什么原因。

  1. 修改代码 官方提供smartconfg例程,位置在esp-idf/examples/wifi/smart_config 着重分析一下这个例程代码:
/*
 * app_main()是esp-idf应用程序的入口函数
 * 初始化flash。(nvs_flash_init())
 * 
 * 在实际的工程代码中应该在初始化flash之后      
 * 判断当前是否存在wifi的账号密码,如果存在应该使用原有的账号密码进行wifi连接,如果连接失败,有两种操作:1.不* 做任何处理,2.开始进行smartconfig,3.是否存在物理按键,检测按键是否被按下,如果按下就行smartconfig
 *
 * 初始化wifi(initialise_wifi();),一般smartconfig都是设备初始化阶段进行的。
 */
void app_main()
{
    ESP_ERROR_CHECK(nvs_flash_init());
    initialise_wifi();
}

/**
 * 初始化tcp/ip 协议栈,tcpip_adapter_init();esp-idf的网络协议栈使用的是lwip,有机会的话我会简单介绍一下 。
 *
 * esp_event_loop_init(event_handler, NULL)  初始化 事件回调函数,event_handler 函数中主要是实时判断当前wifi的执行状态,用户根据这个函数中的状态标志,对程序进行进一步处理
 */
static void initialise_wifi(void)
{
    tcpip_adapter_init();
    s_wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();

    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );//初始化wifi的各种配置
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );//设置当前wifi为station 模式
    ESP_ERROR_CHECK( esp_wifi_start() );//开始连接wifi
}

/* wifi 事件标志 回调函数 
 *
 * SYSTEM_EVENT_STA_START: 当wifi 在sta 模式下运行后, 这个标志被执行,在这个标志下 创建samartconfig任务。
 * SYSTEM_EVENT_STA_GOT_IP:直译过来就是获取到IP,在进入到这个标志时,表示esp32 已经成功连接到路由器中,并被分配了IP。
 * SYSTEM_EVENT_STA_DISCONNECTED:wifi连接断开,在这里面需要连接wifi,重新联网。
 */
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
    switch(event->event_id) {
    case SYSTEM_EVENT_STA_START://
        xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
        break;
    case SYSTEM_EVENT_STA_GOT_IP:
        xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        esp_wifi_connect();//
        xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
        break;
    default:
        break;
    }
    return ESP_OK;
}
/**
 *  1.设置配网类型为ESPTOUCH,esp_smartconfig_set_type(SC_TYPE_ESPTOUCH)  
 *  2. 设置回调函数,开始配网esp_smartconfig_start(sc_callback),根据sc_callback中标志去执行相应的操作。
 *  3. uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY); 根据sc_callback和 event_handler中的事件标志位,判断当前的wifi状态。当判断到CONNECTED_BIT标志设备已经成功连接到wifi,当判断ESPTOUCH_DONE_BIT标志时 应该停止智能配网
 *  4. 停止smartconfig esp_smartconfig_stop();

 */
void smartconfig_example_task(void * parm)
{
    EventBits_t uxBits;
    ESP_ERROR_CHECK( esp_smartconfig_set_type(SC_TYPE_ESPTOUCH) );
    ESP_ERROR_CHECK( esp_smartconfig_start(sc_callback) );
    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);
        }
    }
}

static void sc_callback(smartconfig_status_t status, void *pdata)
{
    switch (status) {
        case SC_STATUS_WAIT://等待开始连接
            ESP_LOGI(TAG, "SC_STATUS_WAIT");
            break;
        case SC_STATUS_FIND_CHANNEL://发现目标通道
            ESP_LOGI(TAG, "SC_STATUS_FINDING_CHANNEL");
            break;
        case SC_STATUS_GETTING_SSID_PSWD://获取账号和密码
            ESP_LOGI(TAG, "SC_STATUS_GETTING_SSID_PSWD");
            break;
        case SC_STATUS_LINK://开始连接路由器
            ESP_LOGI(TAG, "SC_STATUS_LINK");
            wifi_config_t *wifi_config = pdata;
            ESP_LOGI(TAG, "SSID:%s", wifi_config->sta.ssid);
            ESP_LOGI(TAG, "PASSWORD:%s", wifi_config->sta.password);
            ESP_ERROR_CHECK( esp_wifi_disconnect() );//断开连接
            ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, wifi_config) );//配置wifi
            ESP_ERROR_CHECK( esp_wifi_connect() );//连接wifi
            break;
        case SC_STATUS_LINK_OVER://连接路由器成功,发送ESPTOUCH_DONE_BIT 完成标志
            ESP_LOGI(TAG, "SC_STATUS_LINK_OVER");
            if (pdata != NULL) {
                uint8_t phone_ip[4] = { 0 };
                memcpy(phone_ip, (uint8_t* )pdata, 4);
                ESP_LOGI(TAG, "Phone ip: %d.%d.%d.%d\n", phone_ip[0], phone_ip[1], phone_ip[2], phone_ip[3]);
            }
            xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
            break;
        default:
            break;
    }
}

具体操作

  • 将代码下载到esp32中
$ cp -r esp-idf/examples/wifi/smart_config . 
$ cd smart_config 
$ make menuconfig # 将下载端口改成实际的端口
$ make -j8
$ make flash monitor

esp32的ota流程是怎么样的 esp32 coap_网络_02

  • 打开EspTouch app ESP32 不支持5G wifi。

esp32的ota流程是怎么样的 esp32 coap_回调函数_03

  • 软件输入wifi密码,点击确认.开始连接。

esp32的ota流程是怎么样的 esp32 coap_esp32的ota流程是怎么样的_04

  • esp32 接收到esptouch信号还是配置

esp32的ota流程是怎么样的 esp32 coap_初始化_05


  • 配置成功

esp32的ota流程是怎么样的 esp32 coap_网络_06

  • 通知手机APP连接完成

esp32的ota流程是怎么样的 esp32 coap_esp32的ota流程是怎么样的_07