ESP8266学习笔记(1)——Smartconfig接口使用

一、优缺点分析

  1. 一键配网比起传统AP配网技术,简化了连接操作与连接步骤,操作更加简单和加快了连接速度。
  2. 很多路由器不支持UDP广播功能,例如wifi放大器、或者一些默认关闭UDP广播的路由器,会导致发广播包失败,导致WIFI设备无法获取到广播包。
  3. 当5G和2.4G同频的时候,如果当前手机连接的是5G频段,那发出来的广播包是5G的,而目前所有WIFI设备都只支持2.4G,导致无法获取广播包。
  4. 就算经历千辛万险获取到路由器名字和密码,很多路由器由于不支持局域网通讯(例如路由器的访客网络)
  5. 当前环境下面有几个路由器名字都是一样的,导致手机和WIFI设备不是连接在同一个路由器下面,都会导致wifi设备广播的MAC地址无法被手机APP获取到,进而导致绑定失败

二、代码分析

Smartconfig 接口位于 ESP8266_NONOS_SDK/include/smartconfig.h

Step 1) 包含头文件

#include "wb_protocol.h"
#include "ip_addr.h"
#include "smartconfig.h"
#include "user_smartconfig.h"
#include "user_esp_platform.h"
#include "mscp_wifi.h"

Step 2) 相关定义

static os_timer_t s_smartConfigCheckIpTimer;
static os_timer_t s_tcpPingTimer;
static os_timer_t s_tcpLongTimeTimer;

const uint16 SMART_CONFIG_CHEAK_IP_TIMER = 15000; 
const uint16 SMART_PLATFORM_PING_PERIOD = 30000;  	
const uint16 SMART_PLATFORM_LONG_TIME_PERIOD = 60000;

Step 3) 初始化函数

void ICACHE_FLASH_ATTR
SmartConfig(void)
{
    
    
	//获取WIFI默认SSID和密码
	wifi_station_get_config_default(&s_softap);

	//WIFI配置
	wifi_station_set_config(&s_softap);
	wifi_station_disconnect();
	wifi_station_connect();

	//进入自动识别是否接入网络
	startSmartConfigCheckIpTimer();
}

Step 4) 相关回调函数

/**
 @brief 开始进入自动识别是否接入网络
 @param 无
 @return 无
*/
static void ICACHE_FLASH_ATTR
startSmartConfigCheckIpTimer(void)
{
    
    
    os_timer_disarm(&s_smartConfigCheckIpTimer);
    os_timer_setfn(&s_smartConfigCheckIpTimer, (os_timer_func_t *) SmartConfigCheckIpTimerCallback, NULL);
    os_timer_arm(&s_smartConfigCheckIpTimer, SMART_CONFIG_CHEAK_IP_TIMER, true);
}

/**
 @brief 停止进入自动识别是否接入网络
 @param 无
 @return 无
*/
static void ICACHE_FLASH_ATTR
stopSmartConfigCheckIpTimer(void)
{
    
    
	os_timer_disarm(&s_smartConfigCheckIpTimer);
}

/**
 @brief 进入自动识别是否接入网络
 @param resetFlag -[in] 重启标志
 @return 无
*/
static void ICACHE_FLASH_ATTR
SmartConfigCheckIpTimerCallback(void)
{
    
    
	static uint8 connect_status = 0;
	if(wifi_station_get_connect_status() == STATION_GOT_IP)
	{
    
    
		//连接上次路由器成功
		connect_status = 0;
		wifi_set_opmode_current(STATIONAP_MODE);// 设置为 STA+AP模式
	}
	else
	{
    
    
		//连接上次路由器失败
		if(connect_status == 0)
		{
    
    
			connect_status = 1;
			//进入Smartconfig
			user_smartConfig_start();
			os_printf("\n ========================================================== \n ");
			os_printf(" Err : Reason, unable to connect to router ! \n \n");
			os_printf(" wifi ssid : %s \n", s_softap.ssid);
			os_printf(" wifi password : %s \n", s_softap.password);
			os_printf(" ========================================================== \n ");
		}
	}
}

Step 5) Smartconfig函数

/**
 @brief 一键配网切换到AP配网的定时器的回调函数
 @param resetFlag -[in] 重启标志
 @return 无
*/
static void ICACHE_FLASH_ATTR
user_smartConfig_start(void)
{
    
    
	smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS);
	wifi_set_opmode(STATION_MODE);
	smartconfig_start(smartconfig_done);
	os_printf("\n smartconfig_start(smartconfig_done); \n");
}

void ICACHE_FLASH_ATTR 
smartconfig_done(sc_status status, void *pdata) 
{
    
    

	switch (status) {
    
    

	//连接未开始,请勿在此阶段开始连接
	case SC_STATUS_WAIT:
		os_printf("SC_STATUS_WAIT\n");
		break;

	//发现信道
	case SC_STATUS_FIND_CHANNEL:
		os_printf("SC_STATUS_FIND_CHANNEL\n");
		//开启长时间未连接重新进入Smartconfig
		startSendLongTimeTimer();
		break;

	//得到wifi名字和密码
	case SC_STATUS_GETTING_SSID_PSWD:
		os_printf("SC_STATUS_GETTING_SSID_PSWD\n");
		sc_type *type = pdata;
		if (*type == SC_TYPE_ESPTOUCH) {
    
    
			os_printf("SC_TYPE:SC_TYPE_ESPTOUCH\n");
		} else {
    
    
			os_printf("SC_TYPE:SC_TYPE_AIRKISS\n");
		}
		//关闭长时间未连接重新进入Smartconfig
		stopSendLongTimeTimer();
		break;

	case SC_STATUS_LINK:
		os_printf("SC_STATUS_LINK\n");
		struct station_config *sta_conf = pdata;
		s_softap = *sta_conf;
		wifi_station_set_config(sta_conf);
		wifi_station_disconnect();
		wifi_station_connect();
		//开启超时定时器
		startSendPingTimer();
		break;

	//成功获取到IP,连接路由完成。
	case SC_STATUS_LINK_OVER:
		os_printf("SC_STATUS_LINK_OVER \n\n");
		if (pdata != NULL) {
    
    
			uint8 phone_ip[4] = {
    
     0 };
			os_memcpy(phone_ip, (uint8*) pdata, 4);
			os_printf("Phone ip: %d.%d.%d.%d\n", phone_ip[0], phone_ip[1],	phone_ip[2], phone_ip[3]);
		}
		//停止超时定时器
		stopSendPingTimer();
		//停止配置
		smartconfig_stop();
		//切换WIFI模式
		wifi_set_opmode(STATIONAP_MODE);
		break;

	default:
		os_printf("\n ========================================================== \n ");
		os_printf("\n Err: Smartconfig mode failed !! \n");
		os_printf("\n ========================================================== \n ");
		startSendPingTimer();
		break;
	}
}

Step 6) 连接超时回调函数

/**
 @brief 开始发送PING的定时器
 @param 无
 @return 无
*/
static void ICACHE_FLASH_ATTR
startSendPingTimer(void)
{
    
    
	os_timer_disarm(&s_tcpPingTimer);
	os_timer_setfn(&s_tcpPingTimer, (os_timer_func_t *) sendPingTimerCallback, NULL);
    os_timer_arm(&s_tcpPingTimer, SMART_PLATFORM_PING_PERIOD, false);
}

/**
 @brief 停止发送PING的定时器
 @param 无
 @return 无
*/
static void ICACHE_FLASH_ATTR
stopSendPingTimer(void)
{
    
    
	os_timer_disarm(&s_tcpPingTimer);
}

/**
 @brief 发送PING定时器的回调函数
 @param 无
 @return 无
*/
static void ICACHE_FLASH_ATTR
sendPingTimerCallback(void)
{
    
    
	//停止配置
	smartconfig_stop();
	user_smartConfig_start();
	os_printf("\n ========================================================== \n ");
	os_printf("\n Err: Smartconfig Connect Timeout !! ");
	os_printf("\n ========================================================== \n ");
}


• 由 ChiKong_Tam 写于 2020 年 7 月 23 日
• 参考:【ESP8266】NONOS_第2篇:一键配网smartconfig原理及应用
• 参考:设备配网技术之AirKiss微信配网_fengfeng0328的博客-CS…_CSDN博客

猜你喜欢

转载自blog.csdn.net/qq_42209354/article/details/107536935