- 
     前言
 
 前面的博文中,博主提供的实例源代码通常都是固定了WiFi热点的账号密码。但是,在实际产品开发中,这样的限制是行不通的。
 
 当你拿到一块WiFi模块,如果需要连上网络,则需要将SSID名称、密码设置到模块当中。一般有几种方式:
    一种就是通过串口接到输入设备,通过串口输入AT指令(SSID名称和密码),但是前提是该模块本身烧入了AT固件,很明显不符合Arduino core for ESP8266开发;
    
    一种就是设备提供一个AP热点,手机连上这个热点,然后通过手机把家里的WiFi的SSID和密码配置到设备上,最后手机再切换回家里的WiFi(这里就是博主后面会讲到的Web配网),这种配网成功率可以说是100%。
    
    通过SmartConfig技术配置,微信的AirKiss、ESP8266的esptouch(博主也把esptouch的代码抽取了一个module,供Android Studio开发app的同学直接引入),这是最智能的配网方式。但是缺点也很明显,那就是配网成功率未达到100%,同时SmartConfig还得另外安装一个app。SmartConfig最佳的应用场景就是你开发的产品需要搭配App来使用。
   
- 
     smartconfig
 
 8266核心库提供了SmartConfig技术,那么smartconfig到底是什么呢?
 
 2.1 smartconfig工作原理
 
 所谓SmartConfig就是手机App端发送包含WIFI用户名以及密码的UDP广播包,智能终端(开启了sniffer混杂模式)的WIFI芯片可以接收到该UDP包,只要知道UDP包的组织形式,就可以通过接收到的UDP包解密出WIFI用户名密码,然后智能硬件配置收到的用户名密码到指定的WIFI AP上。
 
 直接看一个概念图:
简单操作步骤如下:
    8266 端作为station,进入smartconfig, 等待手机端发出的用户名和密码。
    
    手机端把填写当前网络的密码通过UDP广播;
    
    8266 获取到信息之后推出smartconfig配置,连接网络;
   
    2.2 smartconfig支持库
    
    还记得,博主其实在 ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用 有稍微涉及到smartconfig。而且,请读者放心,smartconfig配置非常简单,方法就三个:
   
    beginSmartConfig
    
    stopSmartConfig
    
    smartConfigDone
   
    2.2.1 beginSmartConfig —— 启动配网模式
    
    函数说明:
    
    /**
   
- 启动配网模式
- 
     @return bool 是否启动配网模式成功
 
 
 /
 
 bool beginSmartConfig();
 
 复制代码看看 beginSmartConfig 源码:
 
 /
 
 *
- 
     启动 SmartConfig
 
 */
 
 bool ESP8266WiFiSTAClass::beginSmartConfig() {
 
 
 //SmartConfig已经开启了
 
 if(_smartConfigStarted) {
 
 
 return false;
 
 }
 
 //开启STA模式
 
 if(!WiFi.enableSTA(true)) {
 
 
 // enable STA failed
 
 return false;
 
 }
 
 //调用真正的smartconfig_start,并设置了_smartConfigCallback 回调函数
 
 if(smartconfig_start(reinterpret_cast<sc_callback_t>(&ESP8266WiFiSTAClass::_smartConfigCallback), 1)) {
 
 
 _smartConfigStarted = true;
 
 _smartConfigDone = false;
 
 return true;
 
 }
 
 return false;
 
 }
 
 复制代码注意点:
SmartConfig需要处于STA工作模式;
    我们看看 _smartConfigCallback 会做什么?源码:
    
    /**
   
- _smartConfigCallback
- @param st
- 
     @param result
 
 
 /
 
 void ESP8266WiFiSTAClass::_smartConfigCallback(uint32_t st, void
 
 result) {
 
 
 sc_status status = (sc_status) st;
 
 if(status == SC_STATUS_LINK) {
 
 
 //获取到配网信息(账号密码)
 
 station_config* sta_conf = reinterpret_cast<station_config*>(result);
 
 //把配置写到flash
 
 wifi_station_set_config(sta_conf);
 
 //断开连接
 
 wifi_station_disconnect();
 
 //重新连接
 
 wifi_station_connect();
 
 //标记配网完成
 
 _smartConfigDone = true;
 
 } else if(status == SC_STATUS_LINK_OVER) {
 
 
 //停止配网
 
 WiFi.stopSmartConfig();
 
 }
 
 }
 
 复制代码2.2.2 stopSmartConfig —— 停止Smartconfig
 
 函数说明:
 
 /**
- 停止Smartconfig
- 
     @return bool 是否停止配网模式成功
 
 
 /
 
 bool stopSmartConfig();
 
 复制代码源码:
 
 /
 
 *
- 
     Stop SmartConfig
 
 
 /
 
 bool ESP8266WiFiSTAClass::stopSmartConfig() {
 
 
 if(!_smartConfigStarted) {
 
 
 return true;
 
 }
 
 //调用停止函数
 
 if(smartconfig_stop()) {
 
 
 _smartConfigStarted = false;
 
 return true;
 
 }
 
 return false;
 
 }
 
 复制代码2.2.3 smartConfigDone —— 是否完成配网
 
 函数说明:
 
 /
 
 *
- 查找状态看是否配网完成
- 
     @return bool 是否启动配网模式成功
 
 
 /
 
 bool smartConfigDone();
 
 复制代码源码:
 
 /
 
 *
- Query SmartConfig status, to decide when stop config
- 
     @return smartConfig Done
 
 */
 
 bool ESP8266WiFiSTAClass::smartConfigDone() {
 
 
 if(!_smartConfigStarted) {
 
 
 return false;
 
 }
 
 //返回状态 _smartConfigCallback 会改变状态
 
 return _smartConfigDone;
 
 }
 
 复制代码3. 实例
请往8266WiFi模块先烧入以下代码:
#include <ESP8266WiFi.h>
    void smartConfig()
    
    {
    
    
    WiFi.mode(WIFI_STA);
    
    Serial.println(“\r\nWait for Smartconfig”);
    
    delay(2000);
    
    // 等待配网
    
    WiFi.beginSmartConfig();
   
    while (1)
    
    {
    
    
    Serial.print(“.”);
    
    delay(500);
    
    if (WiFi.smartConfigDone())
    
    {
    
    
    Serial.println(“SmartConfig Success”);
    
    Serial.printf(“SSID:%s\r\n”, WiFi.SSID().c_str());
    
    Serial.printf(“PSW:%s\r\n”, WiFi.psk().c_str());
    
    WiFi.setAutoConnect(true); // 设置自动连接
    
    break;
    
    }
    
    }
   
    Serial.println(“”);
    
    Serial.println(“WiFi connected”);
    
    Serial.println(“IP address: “);
    
    Serial.println(WiFi.localIP());
    
    }
   
    void setup()
    
    {
    
    
    Serial.begin(115200);
    
    smartConfig();
    
    }
   
    void loop()
    
    {
    
    
    delay(100);
    
    Serial.println(“loop”);
    
    }
    
    复制代码
    
    然后使用ESP8266提供的App ESPTouch 或者还是使用博主后面写的App SmartConfigAPP。
    
    当然,有兴趣的读者也可以获取到源码,请看 传输门,麻烦star。
    
    博主app配置如下:
   
注意点:
如果没有配置成功,一般都是没有进入到SmartConfig中,最好重启一下吧。
测试结果:
- 
     总结
 
 本篇非常简单,三个方法,简单步骤,一键配置网络,值得拥有。
    文章来源
    
    作者:单片机菜鸟博哥
   
 
