带有 SPIFFS 和 AsyncWebServer 库的 ESP32 WiFiManager

问题描述 投票:0回答:1

我正在尝试使用 ESPAsyncWebServer 库创建和设置一个 Wi-Fi 管理器,该库可以修改并与任何 Web 服务器项目或任何需要连接到 Wi-Fi 网络的项目一起使用。

我跟踪了我发现的各种项目,但我认为这个项目有一些优点,所以我决定让它发挥作用(https://randomnerdtutorials.com/esp32-wi-fi-manager-asyncwebserver/#comment- 913501).

我使用 VS Code、PlatformIO IDE 和 SPIFFS 库。到目前为止,我未能使其正常工作,我的意思是,在我作为 AP 连接到 esp32 后,我无法调出 wifimanager.html 屏幕。

我在 initSPIFFS(); 之后放置了几行;当您加载 SPIFFS 中保存的值时。

wifimanagerhtml = readFile (SPIFFS, wifimanagerPath);
Serial.println(wifimanagerhtml);

我收到的结果是:

Reading file: /wifimanager.html
– failed to open file for reading

我不明白为什么。这一定是我缺少的一些基本的东西。 按照建议,wifimanager.html 放置在数据目录中。 我也将其他文件放在那里。例如,我放置了一个 config.txt 进行测试,我可以读取它。

configFile = readFile (SPIFFS, configPath);
Serial.println(configFile);

这两行带出:

Reading file: /config.txt
{“topic”:”home/news”,”parameter_1″:108}

main.cpp如我上面提到的网页:

#include <Arduino.h>
#include <WiFi.h> 
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include "SPIFFS.h"
//Variables to save values from HTML form
String ssid;
String pass;
String ip;
String gateway;
String wifimanagerhtml;
String configFile;
const int ledPin = 2;
// Stores LED state
String ledState;
boolean restart = false;
// File paths to save input values permanently
const char* ssidPath = "/ssid.txt";
const char* passPath = "/pass.txt";
const char* ipPath = "/ip.txt";
const char* gatewayPath = "/gateway.txt";
const char* wifimanagerPath = "/wifimanager.html";
const char* configPath = "/config.txt";
IPAddress localIP;
IPAddress localGateway;
IPAddress subnet(255, 255, 255, 0);
// Initialize SPIFFS
void initSPIFFS() {
  if (!SPIFFS.begin(true)) {
    Serial.println("An error has occurred while mounting SPIFFS");
  }
  Serial.println("SPIFFS mounted successfully");
}

// Read File from SPIFFS
String readFile(fs::FS &fs, const char * path){
  Serial.printf("Reading file: %s\r\n", path);

  File file = fs.open(path);
  if(!file || file.isDirectory()){
    Serial.println("- failed to open file for reading");
    return String();
  }
  
  String fileContent;
  while(file.available()){
    fileContent = file.readStringUntil('\n');
    break;     
  }
  return fileContent;
}

// Write file to SPIFFS
void writeFile(fs::FS &fs, const char * path, const char * message){
  Serial.printf("Writing file: %s\r\n", path);

  File file = fs.open(path, FILE_WRITE);
  if(!file){
    Serial.println("- failed to open file for writing");
    return;
  }
  if(file.print(message)){
    Serial.println("- file written");
  } else {
    Serial.println("- write failed");
  }
}


// Initialize WiFi
bool initWiFi() {
  if(ssid=="" || ip==""){
    Serial.println("Undefined SSID or IP address.");
    return false;
  }

  WiFi.mode(WIFI_STA);
  localIP.fromString(ip.c_str());
  localGateway.fromString(gateway.c_str());

  if (!WiFi.config(localIP, localGateway, subnet)){
    Serial.println("STA Failed to configure");
    return false;
  }
  WiFi.begin(ssid.c_str(), pass.c_str());

  Serial.println("Connecting to WiFi...");
  delay(20000);
  if(WiFi.status() != WL_CONNECTED) {
    Serial.println("Failed to connect.");
    return false;
  }

  Serial.println(WiFi.localIP());
  return true;
}

// Replaces placeholder with LED state value
String processor(const String& var) {
  if(var == "STATE") {
    if(!digitalRead(ledPin)) {
      ledState = "ON";
    }
    else {
      ledState = "OFF";
    }
    return ledState;
  }
  return String();
}

void setup() {
  Serial.begin(9600);
  delay(500);
  Serial.println("Starting ...");

initSPIFFS();

// Load values saved in SPIFFS
  ssid = readFile(SPIFFS, ssidPath);
  pass = readFile(SPIFFS, passPath);
  ip = readFile(SPIFFS, ipPath);
  gateway = readFile (SPIFFS, gatewayPath);
  Serial.println(ssid);
  Serial.println(pass);
  Serial.println(ip);
  Serial.println(gateway);

  Serial.println("********************");
  wifimanagerhtml = readFile (SPIFFS, wifimanagerPath);
  Serial.println(wifimanagerhtml);
  configFile = readFile (SPIFFS, configPath);
  Serial.println(configFile);

  if(initWiFi()) {
    // Route for root / web page
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
      request->send(SPIFFS, "/index.html", "text/html", false, processor);
    });
    
    server.serveStatic("/", SPIFFS, "/");
    
    // Route to set GPIO state to HIGH
    server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request) {
      digitalWrite(ledPin, LOW);
      request->send(SPIFFS, "/index.html", "text/html", false, processor);
    });

    // Route to set GPIO state to LOW
    server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request) {
      digitalWrite(ledPin, HIGH);
      request->send(SPIFFS, "/index.html", "text/html", false, processor);
    });
    server.begin();
  }
  else {
    // Connect to Wi-Fi network with SSID and password
    Serial.println("Setting AP (Access Point)");
    // NULL sets an open Access Point
    WiFi.softAP("matrix_panel_esp32", "password");
    bool softAPsetHostname(const char * hostname);
    IPAddress IP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(IP); 

    // Web Server Root URL
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      request->send(SPIFFS, "/wifimanager.html", "text/html");
    });
    
    server.serveStatic("/", SPIFFS, "/");
    
    server.on("/", HTTP_POST, [](AsyncWebServerRequest *request) {
      int params = request->params();
      for(int i=0;i<params;i++){
        AsyncWebParameter* p = request->getParam(i);
        if(p->isPost()){
          // HTTP POST ssid value
          if (p->name() == PARAM_INPUT_1) {
            ssid = p->value().c_str();
            Serial.print("SSID set to: ");
            Serial.println(ssid);
            // Write file to save value
            writeFile(SPIFFS, ssidPath, ssid.c_str());
          }
          // HTTP POST pass value
          if (p->name() == PARAM_INPUT_2) {
            pass = p->value().c_str();
            Serial.print("Password set to: ");
            Serial.println(pass);
            // Write file to save value
            writeFile(SPIFFS, passPath, pass.c_str());
          }
          // HTTP POST ip value
          if (p->name() == PARAM_INPUT_3) {
            ip = p->value().c_str();
            Serial.print("IP Address set to: ");
            Serial.println(ip);
            // Write file to save value
            writeFile(SPIFFS, ipPath, ip.c_str());
          }
          // HTTP POST gateway value
          if (p->name() == PARAM_INPUT_4) {
            gateway = p->value().c_str();
            Serial.print("Gateway set to: ");
            Serial.println(gateway);
            // Write file to save value
            writeFile(SPIFFS, gatewayPath, gateway.c_str());
          }
          //Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
        }
      }
      restart = true;
      request->send(200, "text/plain", "Done. matrix_panel_esp32 will restart, connect to your router and go to IP address: " + ip);
      delay(3000);
      ESP.restart();
    });
    server.onNotFound([](AsyncWebServerRequest *request){request->send(405);});
    //server.serveStatic("/", SPIFFS, "/");
    server.begin();
  }
}

void loop() {
  if (restart){
    delay(5000);
    ESP.restart();
  }
}

串口终端输出:

Starting ...
SPIFFS mounted successfully
Reading file: /ssid.txt
- failed to open file for reading
Reading file: /pass.txt
- failed to open file for reading
Reading file: /ip.txt
- failed to open file for reading
Reading file: /gateway.txt
- failed to open file for reading




********************
Reading file: /wifimanager.html
- failed to open file for reading

Reading file: /config.txt
{"topic":"home/news","param1":108}
Undefined SSID or IP address.
Setting AP (Access Point)
AP IP address: 192.168.4.1

数据目录有以下文件: config.txt、index.html、style.css 和 wifimanager.html

这是 wifimanager.html 文件:

<!DOCTYPE html>
<html>
<head>
  <title>ESP Wi-Fi Manager</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
  <div class="topnav">
    <h1>ESP Wi-Fi Manager</h1>
  </div>
  <div class="content">
    <div class="card-grid">
      <div class="card">
        <form action="/" method="POST">
          <p>
            <label for="ssid">SSID</label>
            <input type="text" id ="ssid" name="ssid"><br>
            <label for="pass">Password</label>
            <input type="text" id ="pass" name="pass"><br>
            <label for="ip">IP Address</label>
            <input type="text" id ="ip" name="ip" value="192.168.1.200">
            <input type ="submit" value ="Submit">
          </p>
        </form>
      </div>
    </div>
  </div>
</body>
</html>

这也是我从 esp32 flash 读取的分区:

# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x9000,20K,
otadata,data,ota,0xe000,8K,
app0,app,ota_0,0x10000,1280K,
app1,app,ota_1,0x150000,1280K,
spiffs,data,spiffs,0x290000,1472K,

关于去哪里看有什么想法吗?非常感谢!!

esp32 wifimanager spiffs
1个回答
0
投票

经过一番尝试和错误并试图更好地了解 Vs code 环境后,我注意到 Vs-code 编辑器无法将

wifimanager.html
文件识别为 HTML 文件。不清楚为什么,因为我可以阅读里面的 HTML 标记语言,也可以在 Firefox 中打开它。文件也已构建并上传到 SPIFFS,但无法打开。除了上述行为之外,我在编译或构建期间没有收到任何错误。

我在Vs code中重新创建了一个文件,并再次命名为

wifimanager.html

我在里面放置了一些基本的 HTML,保存、构建并上传。现在我可以从 SPIFFS 打开该文件。我运行原始的

wifimanager.html
并将 Firefox/源代码复制到 VS Code 中的文件编辑器中,它起作用了。

© www.soinside.com 2019 - 2024. All rights reserved.