【问题标题】:Bootstrap WiFi credentials into ESP8266将 WiFi 凭据引导到 ESP8266
【发布时间】:2017-06-26 13:18:38
【问题描述】:

我怀疑这是一个已经有“库存”解决方案的问题;我需要部署一个 ESP8266 设备,以便它能够连接到安全的本地 WiFi,但在将软件嵌入设备时我不知道凭据。不知何故,我需要能够让最终用户使用普通计算机(即具有键盘和屏幕的计算机!)将这些信息“推送”到设备中。出于偏好,我希望他们能够通过无线方式执行此操作,但如果必须这样做,则可以使用 USB/串行连接。

我想我可以“捆绑”整个工具链和源代码,让他们运行一个脚本,提示输入此信息,通过 USB 构建和上传软件。但是考虑到 ESP 充当 AP 的能力,我不禁想到还有更好的方法,而且可能已经有人打包了这个!

(我想一个值得问的附带问题是是否可能存在某种更可取的对等配置。我希望 ESP 与计算机主机进行双向、可靠(即类似 TCP 套接字)的通信(它并不真的需要互联网访问)。但我真的不想要任何可能危及该计算机安全性的东西,因此坚持使用最终用户的常规 WiFi 似乎是最好的选择。)

我应该调查什么?或者有人有什么建议?或者什么关键字搜索会找到我的答案!?

TIA!

【问题讨论】:

    标签: wifi esp8266 arduino-esp8266


    【解决方案1】:

    【讨论】:

    • 完美,很明显这将是一个反复出现的问题,并且已经有人解决了。这正是我所需要的。非常感谢!
    【解决方案2】:

    我使用以下解决方案。假设您使用 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, password);

    • (可选)使用 DNSServer 库,您可以设置 DNS 服务器

    • 使用 ESP8266WebServer 库,您可以设置 HTTP 服务器

    • 调用服务器对象的 onNotFound 方法,传递一个在 SPIFF 或 SD(或两者,如果您同时使用这两个接口)上搜索所请求文件的闭包并将其流式传输。

      server->onNotFound
        (
          [&]()
          {
            if(!handleFileRead(server->uri()))
              server->send(404, "text/plain", "FileNotFound");
          }
        ); 
      
      • 调用 on 方法,以便它需要一个名为 networks.json 的文件(您可以指定另一个名称)。此方法流式传输具有所有可用网络 SSID、信号级别和安全模式的 json 字符串。要使用此代码,您应该包含 ArduinoJson 库

      server->on("/networks.json", & { 字符串 json; int numNetworks,我,j,rssi; 静态JsonBuffer jsonBuffer; JsonArray& 网络 = jsonBuffer.createArray(); 对于(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("/configure", & { //处理程序 //添加一个新行 文件配置; 文件 file = SPIFFS.open("/resp.htm", "r"); SPIFFS.remove(configFile); 静态JsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.createObject(); 配置 = SPIFFS.open(configFile, "w"); // 稍后添加一些备份逻辑 如果(!文件) { server->send(404, "text/plain", "File Not Found"); 返回; }

      for (int i = 0; i args(); i++) { 根[服务器->argName(i)] = 服务器->arg(i); if(服务器->argName(i).equals("ssid")) { root["wifissid"] = 服务器->arg(i); }

      if(server->argName(i).equals("password"))
      {
        root["wifipassword"] = server->arg(i);
      }
      

      }

      server->streamFile(file, "text/html");

      root.printTo(config); 文件.close(); config.close(); }

      • 创建一个网页,该网页读取名为 /networks.json 的文件以填充表单中的可用网络列表。当用户选择一个网络时,让页面要求输入密码(我不会为此提供代码,因为实际上有数百万种方法可以做到这一点)。您应该在此页面上使用 javascript。如果您想使用任何花哨的 javascript 插件,例如 jquery、bootstrap 或 angular,您可以使用它,但请记住 ESP8266HttpServer 库可能对较大的文件表现不佳(我设法将 jquery 压缩到 27kb 并且在这个大小上没有问题) .表单应该 GET 到“/config”。
    • 您将获得一个包含 JSON 的简洁配置文件,可用于配置 STA SSID 和密码。

      configWifi(){ 文件配置; int 文件长度; 诠释标记; 整数结果; 无符号字符 mac[6]; 字符 * 缓冲区 = NULL; 静态JsonBuffer jsonBuffer; wifiConnection = new WiFiClient(); WiFi.mode(WIFI_STA); WiFi.mac地址(mac); hex2str(this->clientid, (char *)mac, 6); 配置 = SPIFFS.open(configFile, "r"); 如果(!配置) { config.close(); 返回; } 如果 (config.size() 缓冲区 = (char *) calloc(config.size() + 1, 1); config.readBytes(缓冲区,config.size()); config.close(); Serial.println(缓冲区); JsonObject& root = jsonBuffer.parseObject(buffer); 如果 (!root.success()) { config.close(); 免费(缓冲区); 返回; } strcpy(wifi_ssid, root["wifissid"]); strcpy(wifi_password, root["wifipassword"]); Serial.print("SSID = "); 串行打印(wifi_ssid); Serial.print("Pass = "); Serial.println(wifi_password); WiFi.begin(wifi_ssid, wifi_password); 免费(缓冲区); Serial.println("初始化");
      返回; }

    就是这样。用户将获得一个强制页面来配置他的 wifi 连接。

    【讨论】:

    • 天哪,这非常彻底和详细。谢谢。我会花些时间看看我能从中学到什么。希望它也能为其他可能看到这个问题的人服务。
    猜你喜欢
    • 1970-01-01
    • 2023-02-11
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 2016-09-10
    相关资源
    最近更新 更多