Bootstrap WiFi 凭据进入 ESP8266
Bootstrap WiFi credentials into ESP8266
我怀疑这是一个已经有 "stock" 解决方案的问题;我需要部署一个 ESP8266 设备,以便它能够连接到安全的本地 WiFi,但在软件嵌入到设备上时我不知道凭据。不知何故,我需要能够让最终用户使用普通计算机(即具有键盘和屏幕的计算机!)"push" 将此信息输入设备。作为偏好,我希望他们能够通过无线方式完成此操作,但如果必须以这种方式完成,则 USB/Serial 连接是可能的。
我想我可以 "bundle" 整个工具链和源代码,并让它们 运行 一个提示输入此信息的脚本,通过 USB 构建和上传软件。但是考虑到ESP作为AP的能力,我不禁想到有更好的方法,而且可能已经有人打包了!
(我想一个值得问的附带问题是是否可能有某种更可取的对等配置。我希望 ESP 与计算机主机(它并不真的需要互联网访问)。但我真的不想要任何可能危及该计算机安全的东西,所以坚持使用最终用户的常规 WiFi 似乎是最好的选择。)
我应该调查什么?或者有人有什么建议?或者什么关键字搜索会找到我的答案!?
TIA!
最简单的方法是使用第三方库,如 WiFiManager:
https://github.com/tzapu/WiFiManager
用法示例:http://www.instructables.com/id/Avoid-Hard-Coding-WiFi-Credentials-on-Your-ESP8266/
我使用以下解决方案。假设您正在使用 arduino API 对 ESP8266
进行编程
设置wifi模式为AP_STA
WiFi.mode(WIFI_AP_STA);
配置 softAP(您可以硬编码 SSID 和密码或使用具有默认值的配置文件)
IP 地址 apIP(192, 168, 1, 1);
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
WiFi.softAP(apname, 密码);
(可选)使用 DNSServer 库,您设置一个 DNS 服务器
使用 ESP8266WebServer 库,设置 HTTP 服务器
调用您的服务器对象的 onNotFound 方法,传递一个闭包来搜索请求的文件,无论是在 SPIFF 上还是在 SD 上(或者两者,如果您使用这两个接口)并流式传输它。
server->onNotFound
(
[&]()
{
if(!handleFileRead(server->uri()))
server->send(404, "text/plain", "FileNotFound");
}
);
- 调用 on 方法,以便它期望一个名为 networks.json 的文件(您可以提供其他名称)。此方法流式传输一个 json 字符串,其中包含所有可用的网络 SSID、信号级别和安全模式。要使用此代码,您应该包含 ArduinoJson 库
server->on("/networks.json", &
{
字符串 json;
int numNetworks, i, j, rssi;
StaticJsonBuffer<4096> json缓冲区;
JsonArray& networks = jsonBuffer.createArray();
对于(j = 0;j < 10;j++)
{
numNetworks = WiFi.scanNetworks();
Serial.print(numNetworks);
Serial.println("网络");
对于(j=0;j
if (WiFi.encryptionType(j) != 7)
network["auth"] = 0;
else
network["auth"] = 1;
rssi = WiFi.RSSI(j);
if (rssi < -90)
network["signal"] = 1;
else if (rssi < -80)
network["signal"] = 2;
else if (rssi < -70)
network["signal"] = 3;
else if (rssi < -67)
network["signal"] = 4;
else if (rssi < -30)
network["signal"] = 5;
}
}
networks.printTo(json);
server->send(200, "application/json", json);
Serial.println("handleFileRead: /networks.json");
}
);
再次调用on方法期待配置:
server->on("/配置", &
{ //处理程序
//添加一个新行
文件配置;
文件 file = SPIFFS.open("/resp.htm", "r");
SPIFFS.remove(配置文件);
StaticJsonBuffer<512> json缓冲区;
JsonObject&root = jsonBuffer.createObject();
配置=SPIFFS.open(配置文件,"w"); // 稍后添加一些备份逻辑
如果(!文件)
{
服务器->发送(404,"text/plain","File Not Found");
return;
}
for (int i = 0; i < server->args(); i++)
{
root[server->argName(i)] = server->arg(i);
如果(服务器->argName(i)。等于("ssid"))
{
root["wifissid"] = server->arg(i);
}
if(server->argName(i).equals("password"))
{
root["wifipassword"] = server->arg(i);
}
}
server->streamFile(file, "text/html");
root.printTo(配置);
file.close();
config.close();
}
- 创建一个网页,该网页读取名为 /networks.json 的文件以填充表单中的可用网络列表。当用户选择一个网络时,让页面要求输入密码(我不会为此提供代码,因为实际上有数百万种方法可以做到这一点)。您应该在此页面上使用 javascript。如果你想使用任何花哨的 javascript 插件,例如 jquery、bootstrap 或 angular,你可以使用它,但请记住 ESP8266HttpServer 库可能无法处理较大的文件(我设法将 jquery 压缩到 27kb,并且在这个大小上没有问题)。表单应该 GET 到“/config”。
您将获得一个带有 JSON 的简洁配置文件,您可以使用它来配置 STA SSID 和密码。
配置Wifi(){
文件配置;
int 文件长度;
内特塔伦;
整数结果;
无符号字符mac[6];
字符 * 缓冲区 = NULL;
StaticJsonBuffer<1024> json缓冲区;
wifiConnection = new WiFiClient();
WiFi.mode(WIFI_STA);
WiFi.macAddress(mac);
hex2str(this->clientid, (char *)mac, 6);
配置=SPIFFS.open(配置文件,"r");
如果(!配置)
{
config.close();
return;
}
如果 (config.size() < 10)
{
config.close();
return;
}
缓冲区 = (char *) calloc(config.size() + 1, 1);
config.readBytes(缓冲区, config.size());
config.close();
Serial.println(缓冲区);
JsonObject& root = jsonBuffer.parseObject(缓冲区);
如果 (!root.success())
{
config.close();
免费(缓冲区);
return;
}
strcpy(wifi_ssid, 根["wifissid"]);
strcpy(wifi_password, 根["wifipassword"]);
Serial.print("SSID = ");
Serial.print(wifi_ssid);
Serial.print("通过=");
Serial.println(wifi_password);
WiFi.begin(wifi_ssid, wifi_password);
免费(缓冲区);
Serial.println("initialized");
return;
}
就是这样。用户将获得一个强制页面来配置他的 wifi 连接。
我怀疑这是一个已经有 "stock" 解决方案的问题;我需要部署一个 ESP8266 设备,以便它能够连接到安全的本地 WiFi,但在软件嵌入到设备上时我不知道凭据。不知何故,我需要能够让最终用户使用普通计算机(即具有键盘和屏幕的计算机!)"push" 将此信息输入设备。作为偏好,我希望他们能够通过无线方式完成此操作,但如果必须以这种方式完成,则 USB/Serial 连接是可能的。
我想我可以 "bundle" 整个工具链和源代码,并让它们 运行 一个提示输入此信息的脚本,通过 USB 构建和上传软件。但是考虑到ESP作为AP的能力,我不禁想到有更好的方法,而且可能已经有人打包了!
(我想一个值得问的附带问题是是否可能有某种更可取的对等配置。我希望 ESP 与计算机主机(它并不真的需要互联网访问)。但我真的不想要任何可能危及该计算机安全的东西,所以坚持使用最终用户的常规 WiFi 似乎是最好的选择。)
我应该调查什么?或者有人有什么建议?或者什么关键字搜索会找到我的答案!?
TIA!
最简单的方法是使用第三方库,如 WiFiManager: https://github.com/tzapu/WiFiManager
用法示例:http://www.instructables.com/id/Avoid-Hard-Coding-WiFi-Credentials-on-Your-ESP8266/
我使用以下解决方案。假设您正在使用 arduino API 对 ESP8266
进行编程设置wifi模式为AP_STA
WiFi.mode(WIFI_AP_STA);
配置 softAP(您可以硬编码 SSID 和密码或使用具有默认值的配置文件)
IP 地址 apIP(192, 168, 1, 1); WiFi.mode(WIFI_AP); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); WiFi.softAP(apname, 密码);
(可选)使用 DNSServer 库,您设置一个 DNS 服务器
使用 ESP8266WebServer 库,设置 HTTP 服务器
调用您的服务器对象的 onNotFound 方法,传递一个闭包来搜索请求的文件,无论是在 SPIFF 上还是在 SD 上(或者两者,如果您使用这两个接口)并流式传输它。
server->onNotFound ( [&]() { if(!handleFileRead(server->uri())) server->send(404, "text/plain", "FileNotFound"); } );
- 调用 on 方法,以便它期望一个名为 networks.json 的文件(您可以提供其他名称)。此方法流式传输一个 json 字符串,其中包含所有可用的网络 SSID、信号级别和安全模式。要使用此代码,您应该包含 ArduinoJson 库
server->on("/networks.json", & { 字符串 json; int numNetworks, i, j, rssi; StaticJsonBuffer<4096> json缓冲区; JsonArray& networks = jsonBuffer.createArray(); 对于(j = 0;j < 10;j++) { numNetworks = WiFi.scanNetworks(); Serial.print(numNetworks); Serial.println("网络"); 对于(j=0;j
if (WiFi.encryptionType(j) != 7) network["auth"] = 0; else network["auth"] = 1; rssi = WiFi.RSSI(j); if (rssi < -90) network["signal"] = 1; else if (rssi < -80) network["signal"] = 2; else if (rssi < -70) network["signal"] = 3; else if (rssi < -67) network["signal"] = 4; else if (rssi < -30) network["signal"] = 5; } } networks.printTo(json); server->send(200, "application/json", json); Serial.println("handleFileRead: /networks.json"); }
);
再次调用on方法期待配置:
server->on("/配置", & { //处理程序 //添加一个新行 文件配置; 文件 file = SPIFFS.open("/resp.htm", "r"); SPIFFS.remove(配置文件); StaticJsonBuffer<512> json缓冲区; JsonObject&root = jsonBuffer.createObject(); 配置=SPIFFS.open(配置文件,"w"); // 稍后添加一些备份逻辑 如果(!文件) { 服务器->发送(404,"text/plain","File Not Found"); return; }
for (int i = 0; i < server->args(); i++) { root[server->argName(i)] = server->arg(i); 如果(服务器->argName(i)。等于("ssid")) { root["wifissid"] = server->arg(i); }
if(server->argName(i).equals("password")) { root["wifipassword"] = server->arg(i); }
}
server->streamFile(file, "text/html");
root.printTo(配置); file.close(); config.close(); }
- 创建一个网页,该网页读取名为 /networks.json 的文件以填充表单中的可用网络列表。当用户选择一个网络时,让页面要求输入密码(我不会为此提供代码,因为实际上有数百万种方法可以做到这一点)。您应该在此页面上使用 javascript。如果你想使用任何花哨的 javascript 插件,例如 jquery、bootstrap 或 angular,你可以使用它,但请记住 ESP8266HttpServer 库可能无法处理较大的文件(我设法将 jquery 压缩到 27kb,并且在这个大小上没有问题)。表单应该 GET 到“/config”。
您将获得一个带有 JSON 的简洁配置文件,您可以使用它来配置 STA SSID 和密码。
配置Wifi(){ 文件配置; int 文件长度; 内特塔伦; 整数结果; 无符号字符mac[6]; 字符 * 缓冲区 = NULL; StaticJsonBuffer<1024> json缓冲区; wifiConnection = new WiFiClient(); WiFi.mode(WIFI_STA); WiFi.macAddress(mac); hex2str(this->clientid, (char *)mac, 6); 配置=SPIFFS.open(配置文件,"r"); 如果(!配置) { config.close(); return; } 如果 (config.size() < 10) { config.close(); return; }
缓冲区 = (char *) calloc(config.size() + 1, 1); config.readBytes(缓冲区, config.size()); config.close(); Serial.println(缓冲区); JsonObject& root = jsonBuffer.parseObject(缓冲区); 如果 (!root.success()) { config.close(); 免费(缓冲区); return; } strcpy(wifi_ssid, 根["wifissid"]); strcpy(wifi_password, 根["wifipassword"]); Serial.print("SSID = "); Serial.print(wifi_ssid); Serial.print("通过="); Serial.println(wifi_password); WiFi.begin(wifi_ssid, wifi_password); 免费(缓冲区); Serial.println("initialized");
return; }
就是这样。用户将获得一个强制页面来配置他的 wifi 连接。