很多时候ESP8266都是直接将WIFI的信道和密码写入Arduino内部的,这样做虽然对于个人项目并没有什么影响,但是如果涉及到项目商业化则明显不行。所以波波也一直在探索如何让用户更加便捷的配置开发板上网。功夫不负有心人,在简书上看到乐鑫提供了一个SmartConfig的方案感觉很不错,所以分享一下。
所谓的smartconfig就是手机APP端发送包含WIFI 用户名 WIFI密码的 UDP 广播包或者组播包,智能终端的WIFI芯片可以接收到该UDP包,只要知道UDP的组织形式,就可以通过接收到的UDP包解密 出WIFI 用户名 密码,然后智能硬件 配置受到的WIFI 用户名 密码到指定的WIFI AP 上。
这种方式尤其适合对没有屏幕的外设进行相关配置。
配置步骤:
1、ESP8266 端调用 WiFi.beginSmartConfig() 等待手机端发出的用户名与密码。
2、手机端填写当前网络的密码发送到UDP端口。
3、ESP8266 自动收到连接信息并调用 WiFi.smartConfigDone() 退出等待。
是不是很简单呢?
附:ESP8266固件代码(APP及代码下载)
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include "FS.h"
#define LED 2
struct Config {
String SSID;
String Passwd;
String Server = "esaylinker";
String Token = "0000";
};
Config _config;
bool LoadConfig() {
File configFile = SPIFFS.open("/config.json", "r");
if (!configFile) {
Serial.println("Failed to open config file");
return false;
}
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, configFile);
if (error) {
Serial.println("Failed to read file, using default configuration");
return false;
}
_config.SSID = doc["SSID"] | "fail";
_config.Passwd = doc["Passwd"] | "fail";
if (_config.SSID == "fail" || _config.Passwd == "fail") {
return false;
}
else {
Serial.println("Load wifi config from spiffs successful.");
Serial.print("Loaded ssid: ");
Serial.println(_config.SSID);
Serial.print("Loaded passwd: ");
Serial.println(_config.Passwd);
return true;
}
}
bool SaveConfig() {
DynamicJsonDocument doc(1024);
JsonObject root = doc.to<JsonObject>();
root["SSID"] = _config.SSID;
root["Passwd"] = _config.Passwd;
root["Server"] = _config.Server;
root["Token"] = _config.Token;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("Failed to open config file for writing");
return false;
}
if (serializeJson(doc, configFile) == 0) {
Serial.println("Failed to write to file");
return false;
}
return true;
}
void setup() {
Serial.begin(115200);
//Set LED
pinMode(LED, OUTPUT);
//Mount FS
Serial.println("Mounting FS...");
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
//Connect WIFI
ConnectServer();
}
void loop() {
//Wifi watch dog,if wifi not connect, it will auto reconnect.
WiFiWatchDog();
Serial.print("Looks like working. now:");
Serial.println(millis() / 1000);
delay(1000);
}
void ConnectServer() {
if (LoadConfig()) {
BaseConfig();
} else {
SmartConfig();
}
digitalWrite(LED, LOW);
}
bool WiFiWatchDog(){
if(WiFi.status() != WL_CONNECTED){
BaseConfig();
}
return true;
}
void BaseConfig() {
Serial.println("Use base config to connect wifi.");
WiFi.mode(WIFI_STA);
WiFi.begin(_config.SSID, _config.Passwd);
//连接超时时间,30s后没有连接将会转入SmartConfig
int timeout = 30000;
while (WiFi.status() != WL_CONNECTED) {
Serial.println("Wait to connect wifi...");
digitalWrite(LED, LOW);
delay(150);
digitalWrite(LED, HIGH);
delay(150);
timeout = timeout - 300;
if (timeout <= 0) {
Serial.println("Wifi connect timeout, use smart config to connect...");
SmartConfig();
return;
}
}
Serial.println("WiFi connected by base config.");
Serial.print("SSID:");
Serial.println(WiFi.SSID());
Serial.print("IP Address:");
Serial.println(WiFi.localIP());
}
void SmartConfig()
{
Serial.println("Use smart config to connect wifi.");
WiFi.mode(WIFI_STA);
WiFi.beginSmartConfig();
while (1)
{
Serial.println("Wait to connect wifi...");
digitalWrite(LED, LOW);
delay(1000);
digitalWrite(LED, HIGH);
delay(1000);
if (WiFi.smartConfigDone())
{
Serial.println("WiFi connected by smart config.");
Serial.print("SSID:");
Serial.println(WiFi.SSID());
Serial.print("IP Address:");
Serial.println(WiFi.localIP());
_config.SSID = WiFi.SSID();
_config.Passwd = WiFi.psk();
if (!SaveConfig()) {
Serial.println("Failed to save config");
} else {
Serial.println("Config saved");
}
break;
}
}
}
如果使用NodeMCU Lua 的话代码会更简单一些:
wifi.setmode(wifi.STATION)
wifi.startsmart(0,function(ssid, password)
print(string.format("Success. SSID:%s ; PASSWORD:%s", ssid, password))
end )
参考文档:https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_cn#wifistartsmart
手机端
上述固件烧录完毕后,在手机上只需启动乐鑫提供的ESP-Touch应用输入WIFI信道和密码即可配置让开发板联网了。
文章评论