Reputation: 11
I am trying to create and set up a Wi-Fi Manager with the ESPAsyncWebServer library that can be modified and used with any web server project or with any project that needs a connection to a Wi-Fi network.
I followed various projects I found around but this one has, I think, has some advantages so I have decided to make it work (https://randomnerdtutorials.com/esp32-wi-fi-manager-asyncwebserver/#comment-913501).
I use the VS Code, PlatformIO IDE and SPIFFS library. So far I have failed, to make it work, by that I mean, I can't bring up the wifimanager.html screen, after I have connected to esp32 as AP.
I have placed a couple of lines after the initSPIFFS(); when you load values saved in SPIFFS.
wifimanagerhtml = readFile (SPIFFS, wifimanagerPath);
Serial.println(wifimanagerhtml);
the result that I receive is:
Reading file: /wifimanager.html
– failed to open file for reading
I can’t figure out why. It must be something elemental that I am missing. The wifimanager.html is placed in the data directory, as suggested. I have also placed other files in there as well. For example I placed a config.txt for testing and I can read it.
configFile = readFile (SPIFFS, configPath);
Serial.println(configFile);
These two lines brings out:
Reading file: /config.txt
{“topic”:”home/news”,”parameter_1″:108}
The main.cpp is as in the web page I mentioned above:
#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();
}
}
The serial terminal output:
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
The data directory has the following files: config.txt, index.html, style.css and wifimanager.html
Here is the wifimanager.html file:
<!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>
Also here is the partitions that I read from the 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,
Any ideas as to where to look? Thanks a lot!!
Upvotes: 0
Views: 337
Reputation: 11
After some trial and error and trying to understand the Vs code environment better, I noticed that the Vs-code editor was not recognizing the wifimanager.html
file as an HTML file. It is not clear why because I could read the HTML markup language inside and I could also open it in Firefox. Also the file was built and uploaded to SPIFFS, but could not be opened. Apart from the above behavior I was not receiving any errors during compile or build.
I recreated a file in Vs code and named it wifimanager.html
again.
I placed some elemental HTML inside, saved it , built and uploaded. Now I could open the file from SPIFFS. I opened the original wifimanager.html
and copied the Firefox/source code to the file editor in vs code, and it worked.
Upvotes: 0