WiFiManager with ESP8266 – Autoconnect, Custom Parameter and Manage your SSID and Password

In this guide you’ll learn how to use WiFiManager with the ESP8266 board. WiFiManager allows you to connect your ESP8266 to different Access Points (AP) without having to hard-code and upload new code to your board. Additionally, you can also add custom parameters (variables) and manage multiple SSID connections with the WiFiManager library.

How WiFiManager Works with ESP8266

The WiFiManager is a great library do add to your ESP8266 projects, because using this library you no longer have to hard-code your network credentials (SSID and password). Your ESP will automatically join a known network or set up an Access Point that you can use to configure the network credentials. Here’s how this process works:

  • When your ESP8266 boots, it is set up in Station mode, and tries to connect to a previously saved Access Point (a known SSID and password combination);
  • If this process fails, it sets the ESP into Access Point mode;
  • Using any Wi-Fi enabled device with a browser, connect to the newly created Access Point (default name AutoConnectAP);
  • After establishing a connection with the AutoConnectAP, you can go to the default IP address 192.168.4.1 to open a web page that allows you to configure your SSID and password;
  • Once a new SSID and password is set, the ESP reboots and tries to connect;
  • If it establishes a connection, the process is completed successfully. Otherwise, it will be set up as an Access Point.

This blog post illustrates two different use cases for the WiFiManager library:

  • Example #1 – Autoconnect: Web Server Example
  • Example #2 – Adding Custom Parameters

Prerequisites

Before proceeding with this tutorial we recommend reading the following resources:

Installing WiFiManager and ArduinoJSON

You also need to install the WiFiManager Library and ArduinoJSON Library. Follow these next instructions.

Installing the WiFiManager Library

  1. Click here to download the WiFiManager library. You should have a .zip folder in your Downloads
  2. Unzip the .zip folder and you should get WiFiManager-master folder
  3. Rename your folder from WiFiManager-master to WiFiManager
  4. Move the WiFiManager folder to your Arduino IDE installation libraries folder
  5. Finally, re-open your Arduino IDE

Installing the ArduinoJSON Library

  1. Click here to download the ArduinoJSON library. You should have a .zip folder in your Downloads
  2. Unzip the .zip folder and you should get ArduinoJSON-master folder
  3. Rename your folder from ArduinoJSON-master to ArduinoJSON
  4. Move the ArduinoJSON folder to your Arduino IDE installation libraries folder
  5. Finally, re-open your Arduino IDE

Learn more how to Decode and Encode JSON with Arduino or ESP8266 using the Arduino JSON Library.


Example #1 – WiFiManager with ESP8266: Autoconnect Example

This first example is based on the ESP8266 Web Server post, where you build a web server with an ESP8266 to control two outputs (watch the video tutorial below).

For Example #1 we’ll use the previous project, but instead of hard-coding the SSID and password, you’ll be able to configure it with the WiFiManager library.

Code

Having the ESP8266 add-on for the Arduino IDE installed (How to Install the ESP8266 Board in Arduino IDE), go to Tools and select “ESP-12E” (or choose the development board that you’re using). Here’s the code that you need to upload to your ESP8266:

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         // https://github.com/tzapu/WiFiManager

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
String output5State = "off";
String output4State = "off";

// Assign output variables to GPIO pins
const int output5 = 5;
const int output4 = 4;

void setup() {
  Serial.begin(115200);
  
  // Initialize the output variables as outputs
  pinMode(output5, OUTPUT);
  pinMode(output4, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output5, LOW);
  digitalWrite(output4, LOW);

  // WiFiManager
  // Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  
  // Uncomment and run it once, if you want to erase all the stored information
  //wifiManager.resetSettings();
  
  // set custom ip for portal
  //wifiManager.setAPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

  // fetches ssid and pass from eeprom and tries to connect
  // if it does not connect it starts an access point with the specified name
  // here  "AutoConnectAP"
  // and goes into a blocking loop awaiting configuration
  wifiManager.autoConnect("AutoConnectAP");
  // or use this for auto generated name ESP + ChipID
  //wifiManager.autoConnect();
  
  // if you get here you have connected to the WiFi
  Serial.println("Connected.");
  
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            
            // turns the GPIOs on and off
            if (header.indexOf("GET /5/on") >= 0) {
              Serial.println("GPIO 5 on");
              output5State = "on";
              digitalWrite(output5, HIGH);
            } else if (header.indexOf("GET /5/off") >= 0) {
              Serial.println("GPIO 5 off");
              output5State = "off";
              digitalWrite(output5, LOW);
            } else if (header.indexOf("GET /4/on") >= 0) {
              Serial.println("GPIO 4 on");
              output4State = "on";
              digitalWrite(output4, HIGH);
            } else if (header.indexOf("GET /4/off") >= 0) {
              Serial.println("GPIO 4 off");
              output4State = "off";
              digitalWrite(output4, LOW);
            }
            
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons 
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #77878A;}</style></head>");
            
            // Web Page Heading
            client.println("<body><h1>ESP8266 Web Server</h1>");
            
            // Display current state, and ON/OFF buttons for GPIO 5  
            client.println("<p>GPIO 5 - State " + output5State + "</p>");
            // If the output5State is off, it displays the ON button       
            if (output5State=="off") {
              client.println("<p><a href=\"/5/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/5/off\"><button class=\"button button2\">OFF</button></a></p>");
            } 
               
            // Display current state, and ON/OFF buttons for GPIO 4  
            client.println("<p>GPIO 4 - State " + output4State + "</p>");
            // If the output4State is off, it displays the ON button       
            if (output4State=="off") {
              client.println("<p><a href=\"/4/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/4/off\"><button class=\"button button2\">OFF</button></a></p>");
            }
            client.println("</body></html>");
            
            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

View raw code

This code needs to include the following libraries for the WiFiManager:

#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>

You also need to create a WiFiManager object:

WiFiManager wifiManager;

And run the autoConnect() method:

wifiManager.autoConnect("AutoConnectAP");

That’s it! By adding these new lines of code to your ESP8266 projects, you’re able to configure Wi-Fi credentials using the WiFiManager.

Accessing the WiFiManager AP

If it’s your first time running the WiFiManager code with your ESP8266 board, you’ll see the next messages being printed in your Arduino IDE Serial Monitor.

You can either use your computer/laptop to connect to the AutoConnectAP Access point:

Then, open your browser and type the following IP address: 192.168.4.1. This loads the next web page, where you can set your Wi-Fi credentials:

Alternatively, you can use your smartphone, activate Wi-Fi and connect to AutoConnectAP as follows:

You should see a a window similar to the one shown in the figure below. Then, press the “SIGN IN” button:

Configuring the WiFi page

You’ll be redirected to a web page at 192.168.4.1 that allows you to configure your ESP’s WiFi credentials. Press the “Configure WiFi” button:

Choose your desired network by tapping its name and the SSID should be filled instantly (in my case “MEO-620B4B”):

After that, type your password and press “save“:

You’ll see a similar message saying “Credentials Saved“:

In the meanwhile, the Serial Monitor displays the scan results of the available Access Points and message stating that Wi-Fi credentials were saved.

Accessing your web server

Now, if you RESET your ESP board, it will print the IP address in the Serial Monitor (in my case it’s 192.168.1.132):

Open your browser and type the IP address. You should see the web server shown below, that allows you to control two GPIOs on and off:

Parts required and schematic

If you want to make this project work, here’s the parts that you need:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Follow this schematic:


How to Erase Credentials From Your ESP8266

This next line is commented by default, otherwise you would need to configure your ESP8266 every time it boots up.

// Uncomment and run it once, if you want to erase all the stored information
//wifiManager.resetSettings();

If for some reason you want to erase all the saved credentials:

  1. Uncomment the preceding line;
  2. Upload the code to the ESP8266;
  3. Let it run once (reset your board);
  4. Comment that line again;
  5. Upload the code to the ESP8266 with the line commented.

Example #2 – WiFiManager with ESP8266 and Custom Parameters

The WiFiManager has a useful feature that allows you to add custom parameters to the “Configure WiFi” web page. This is extremely useful, because in some applications you might want to add a different API Key, an MQTT broker IP Address, assign a different GPIO, activate a sensor, etc..

In Example #2, you’ll make a web server to control an ESP8266 GPIO pin that is defined with a custom parameter set through the WiFiManager.

Code

Having the ESP8266 add-on for the Arduino IDE installed (How to Install the ESP8266 Board in Arduino IDE), go to Tools and select “ESP-12E” (or choose the development board that you’re using). Here’s the code that you need to upload to your ESP8266:

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#include <FS.h> //this needs to be first, or it all crashes and burns...
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          // https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>          // https://github.com/bblanchon/ArduinoJson

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
String outputState = "off";

// Assign output variables to GPIO pins
char output[2] = "5";

//flag for saving data
bool shouldSaveConfig = false;

//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}

void setup() {
  Serial.begin(115200);
  
  //clean FS, for testing
  //SPIFFS.format();

  //read configuration from FS json
  Serial.println("mounting FS...");

  if (SPIFFS.begin()) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");
          strcpy(output, json["output"]);
        } else {
          Serial.println("failed to load json config");
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");
  }
  //end read
  
  WiFiManagerParameter custom_output("output", "output", output, 2);

  // WiFiManager
  // Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);
  
  // set custom ip for portal
  //wifiManager.setAPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

  //add all your parameters here
  wifiManager.addParameter(&custom_output);
  
  // Uncomment and run it once, if you want to erase all the stored information
  //wifiManager.resetSettings();

  //set minimu quality of signal so it ignores AP's under that quality
  //defaults to 8%
  //wifiManager.setMinimumSignalQuality();
  
  //sets timeout until configuration portal gets turned off
  //useful to make it all retry or go to sleep
  //in seconds
  //wifiManager.setTimeout(120);

  // fetches ssid and pass from eeprom and tries to connect
  // if it does not connect it starts an access point with the specified name
  // here  "AutoConnectAP"
  // and goes into a blocking loop awaiting configuration
  wifiManager.autoConnect("AutoConnectAP");
  // or use this for auto generated name ESP + ChipID
  //wifiManager.autoConnect();
  
  // if you get here you have connected to the WiFi
  Serial.println("Connected.");
  
  strcpy(output, custom_output.getValue());

  //save the custom parameters to FS
  if (shouldSaveConfig) {
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    json["output"] = output;

    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }

    json.printTo(Serial);
    json.printTo(configFile);
    configFile.close();
    //end save
  }

  // Initialize the output variables as outputs
  pinMode(atoi(output), OUTPUT);
  // Set outputs to LOW
  digitalWrite(atoi(output), LOW);;
  
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            
            // turns the GPIOs on and off
            if (header.indexOf("GET /output/on") >= 0) {
              Serial.println("Output on");
              outputState = "on";
              digitalWrite(atoi(output), HIGH);
            } else if (header.indexOf("GET /output/off") >= 0) {
              Serial.println("Output off");
              outputState = "off";
              digitalWrite(atoi(output), LOW);
            }
            
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons 
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #77878A;}</style></head>");
            
            // Web Page Heading
            client.println("<body><h1>ESP8266 Web Server</h1>");
            
            // Display current state, and ON/OFF buttons for the defined GPIO  
            client.println("<p>Output - State " + outputState + "</p>");
            // If the outputState is off, it displays the ON button       
            if (outputState=="off") {
              client.println("<p><a href=\"/output/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/output/off\"><button class=\"button button2\">OFF</button></a></p>");
            }                  
            client.println("</body></html>");
            
            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

View raw code

Adding custom parameters

To add a custom parameter, you need to add a bunch of code (see the preceding sketch) that allows you to manipulate the /config.json file stored in the ESP. For this tutorial we won’t explain how the custom parameters feature works, but basically if you wanted to create another custom parameter follow these next steps.

In this example, we’ll create a variable to store an MQTT broker server IP address. First, create a char variable:

char output[2];
char mqtt_server[40];

Then, if it’s already saved in the /config.json, you can copy it:

strcpy(output, json["output"]);
strcpy(mqtt_server, json["mqtt_server"]);

Create a WiFiManagerParameter (so, the parameter is displayed in the “Configure WiFi” web page:

WiFiManagerParameter custom_output("output", "output", output, 2);
WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);

Add the variable as a parameter:

wifiManager.addParameter(&custom_output);
wifiManager.addParameter(&custom_mqtt_server);

Check and update the char variables with the latest value:

strcpy(output, custom_output.getValue());
strcpy(mqtt_server, custom_mqtt_server.getValue());

Finally, if the user submits a new value to one of the parameters, this line updates the /config.json file:

json["output"] = output;
json["mqtt_server"] = mqtt_server;

You could repeat this process to add more custom parameters.

Accessing the WiFiManager AP

Use your smartphone, computer or tablet and connect to the AutoConnectAP Access Point:

You should see a a window similar to the one shown in the figure below. Then, press the “SIGN IN” button:

Configuring the WiFi page

You’ll be redirected to a web page at 192.168.4.1 that allows you to configure your ESP’s WiFi credentials. Press the “Configure WiFi” button:

Choose your desired network by tapping its name and the SSID should be filled instantly (in my case “MEO-620B4B”):

After that, type your password, your desired GPIO number (in my case it’s GPIO 5, so I’ve entered 5) and press “save“:

In the meanwhile, the Serial Monitor displays:

  • Scan results of the available Access Points;
  • Message stating that Wi-Fi credentials were saved;
  • Confirmation that the output parameter (that refers to the GPIO) was set to 5: {“output”:”5″}.

Accessing your web server

Now, if you RESET your ESP board, it will print the IP address in the Serial Monitor (in my case it’s 192.168.1.132):

Open your browser and type the IP address. You should see the web server shown below, that allows you to control the GPIO you’ve defined on and off:

Parts required and schematic

If you want to make this project work, here’s the parts that you need:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Note: if you’ve defined a GPIO number different than GPIO 5 (which is D1 with the NodeMCU board), you need to make a different circuit.

Wrapping Up

That’s it for now, I hope you found this project useful and you can use the WiFiManager library in your projects!

If you like the ESP8266, you may also like:

Do you have any questions? Leave a comment down below!

Thanks for reading. If you like this post probably you might like my next ones, so please support me by subscribing my blog.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

121 thoughts on “WiFiManager with ESP8266 – Autoconnect, Custom Parameter and Manage your SSID and Password”

  1. I know you get out of your way to help us understand whatever topic you are dealing with. For that I really appreciate your excellent tutorials and courses.
    In this one you “touched” on the role of the WiFi manger AND the config file INSIDE THE ESP8266. This is a very important part of ESP8288, and I will appreciate if you dedicate a tutorial JUST on this important topic of ESP8266 config file. and the wifi manager.

    Maybe you did talk about it somewhere in your site, if this is the case, my apology; and I hope you direct me to the links that address this important topic ( IMHO)

    Reply
    • Hi Samir,
      Thanks for sharing your interest about that topic, however at the moment I don’t have any tutorial about the config file at the moment…
      I might write a tutorial about that subject in the future.

      Thanks for your feedback.
      Regards,
      Rui

      Reply
    • I’m not sure why it didn’t work… That’s the official method to clear the access points. In fact, to test this project, I’ve deleted more than 10 times using that function and it worked every time.
      Make sure you restart your ESP8266 at least one or two times after uploading the sketch with the reset line uncommented:

      wifiManager.resetSettings();

      Reply
  2. The example wont compile. here is the error for the arduino console.

    “/tmp/arduino_build_335203/sketch/WiFiManager.ino.cpp” -o “/tmp/arduino_build_335203/sketch/WiFiManager.ino.cpp.o”
    /home/jake/Arduino/programs/WiFiManager/WiFiManager.ino: In function ‘void setup()’:
    WiFiManager:81: error: ‘class WiFiManager’ has no member named ‘setAPConfig’
    wifiManager.setAPConfig(IPAddress(192,168,200,1), IPAddress(192,168,200,1), IPAddress(255,255,255,0));
    ^
    Using library ESP8266WiFi at version 1.0 in folder: /home/jake/.arduino15/packages/esp8266/hardware/esp8266/2.4.0/libraries/ESP8266WiFi
    Using library DNSServer at version 1.1.0 in folder: /home/jake/.arduino15/packages/esp8266/hardware/esp8266/2.4.0/libraries/DNSServer
    Using library ESP8266WebServer at version 1.0 in folder: /home/jake/.arduino15/packages/esp8266/hardware/esp8266/2.4.0/libraries/ESP8266WebServer
    Using library WiFiManager at version 0.12 in folder: /home/jake/Arduino/libraries/WiFiManager
    Using library ArduinoJson at version 5.13.1 in folder: /home/jake/Arduino/libraries/ArduinoJson
    exit status 1
    ‘class WiFiManager’ has no member named ‘setAPConfig’

    Reply
    • It looks like you might be running an older version of the WiFiManager library or an older version of the ESP8266 add-on for the Arduino IDE.
      Make sure you double-check and you have everything updated.
      Let me know if that solves your problem.

      Regards,
      Rui

      Reply
  3. When compiling example 1 i get a error msg: “error compiling to board WeMos D1 R2 & mini”. This error appears also on the WiFiManager examples. Any idea?

    Reply
      • Hi Sara,
        i already did all the things in your suggestions, without success, also i uninstalled all ESP plugins from my arduino IDE and reinstalled it. Did also not work …
        But then, i uninstalled all ESP plugins, then deleted all ESP files in the “c:/users/MyAccount/AppData/local/arduino15/” folder and after that, reinstalled everything from scratch.
        Now ist works fine ! Maybe important for other users with te sam problem …

        Anyway, thanks for your help and your great homepage. It’s a very good starting point to get familar with the ESP8266 !
        Manfred

        Reply
        • It looks like you have a library missing in your Arduino IDE.
          Did you install the WiFi Manager library or the ArduinoJSON? Make sure you have all the libraries installed that your sketch needs.

          Reply
  4. Hi,
    I tried this project using an ESP01 :
    – compiling = ok
    – upload = ok
    – reboot = ok
    I got the correct message on the serial monitor up to the line :”*WM: HTTP server started” then nothing
    _ when I check the wifi list, I can see : AutoConnectAP (but it appears and disappears erratically)
    – when it appears, if I try to connect, I get after about 5 seconds “cannot connect to the network”

    please advise
    (I cannot check with another ESP, I have got only one at the moment)
    regards

    Reply
    • Hi Yodrack.
      I’ve never experienced that error before, please try to search for your exact problem and someone on GitHub might be able to help you.
      Make sure you’re using the latest stable libraries for the ESP8266 and WiFi Manager dependencies…
      Regards,
      Rui

      Reply
      • Thank you for your answer. I tried several sketches dealing with wifi on my ESP01. I got always the same problem, the PC or smartphone cannot connect to ESP in server mode, and ESP cannot connect to Wifi in client mode.
        I tried AT commands , same problem
        I thing my ESP is out of order regarding the Wifi section, but other sketches (with no realation to Wifi) run without any problem.

        I order other ESP (01, 03, 07, 12) and I will try again when I received them.
        regards

        Reply
        • Hi Ruy Santos
          I received new ESP’s and I tried again with ESP01
          Every things works with this new device.
          I can get the list of AP (I did’n check further at the moment).

          It is very strange that my previous ESP does’nt work on the Wifi side,
          the rest works without any problem (I can activate GPIO’s)

          I checked the antenna if there were a microcut in the wire, I even changed the capacitor between ESP8266ex and antenna, nothing change !

          Anyway, it does not matter, I can pursue the work..
          Regards

          Reply
  5. Hi,
    I try example number 1 and it was uploaded successfully to my esp8266 board I saw the “autoconnect” network and connect to it.
    I try to open the IP 192.168.4.1 and it just returns an empty page! do I missed something ??

    Reply
  6. I was very interested in WiFiManager and I would like to use it with BLYNK, but I do not know how to load ssid and pass from eeprom into variables so I can use them in Blynk.begin (auth, ssid, pass);

    Thanks

    Reply
    • I don’t have any examples on that subject, but please read the “Example #2 – Adding Custom Parameters” section.
      You should be able to create a pass for your example…

      Reply
  7. The interesting thing about Raspberry Pi 3 is that it has a bit of everything: wired and wireless connectivity, USB, GPIO, camera, display, processing, video and graphics. So, unlike the transition from Raspberry Pi 2 to Raspberry Pi 3, where we added wireless, I don”t think that the next Raspberry Pi be qualitatively different: it will be more of the same, and as always how much more will depend on what we can squeeze into that $35 price point.

    Reply
  8. i have a weird problem when i compile it. The arduino IDE soft stop with “error compiling” causing by Manager library. Do you have an idea why?

    Reply
  9. I am using NodeMcu 0.9 ESP-12 board and getting an error on example2 ‘stray \342’ in program at line
    client.println(“”);

    I have the latest libs – Arduino 1.8.6 please advise

    Reply
    • Paul, i hope you already found the answher, but for other people: this error is usually seen when you copy non-pure ASCII from a formatted website. The error that is the most frequent is that you copy so called elegant quotes instead of regular double quotes. Make sure you copy so called Raw code

      Reply
    • Thanks for asking, but I don’t write custom code due to time constraints. If you have an exact problem with my project please let me know which error you are encountering…
      Regards,
      Rui

      Reply
  10. Sir,
    Your tutorials are awesome, and they are working very nicely.
    Can you please help me in making a esp8266 webserver in AP mode in which there is a download button that can download a file from the sd card to the client

    Reply
  11. Very nice tutorial. I was not a aware of the WiFiManager capability to add custom parameters.

    It worked great when I added a single custom parameter. However, I ran into a problem when I wanted to add a second custom parameter. Even though I (*think*) I’m doing it exactly the same way, it crashes every time. I think it’s in the second call to addParameter(). Is that something that should be expected to work? Is there anything special about having more than one paramter? Thanks!

    Reply
    • Hi Peter, please take a look at the official example “AutoConnectWithFSParameters.ino” to see how to add more than 1 parameter: github.com/tzapu/WiFiManager/blob/master/examples/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino

      Reply
  12. How to open WifiManager again, where a device is connected to network?
    I can’t find it on list available acces points.

    Reply
    • You need to add this to the setup to run it again. In essence, you clear all data in memory.

      wifiManager.resetSettings();

      I would use a button to do that. If the button is pushed during reset then this line will be running to clear all settings in memory.

      Reply
  13. I am currently trying to use WifiManager’s custom parameters to store an Adafruit username/key, so that I can send information to Adafruit without hardcoding login information.

    I have no problems when I hardcode all values. When I declare an empty “adafruit_key” char array and enter my key on the interface, I still have no problems. However, I get an error on my Adafruit Monitor when I try to enter my Adafruit username on the interface instead of hardcoding it.

    With each attempt to log data, instead of recording the correct data, my Adafruit Monitor displays “mqtt subscription error on /f/alli_test_temp/csv: you are not authorized.”

    It seems that Adafruit does not want to accept my username when it is entered through WifiManager. I have not been able to find much information on this error – I don’t know if the issue is the WifiManager’s custom parameters, or Adafruit itself.

    Does anyone have experience using WifiManager with Adafruit who could help? Even just pointing me to a place I could find more information would be greatly appreciated. Thank you!

    Reply
    • Hello Alli,
      Sorry to hear that you can’t make it work! I’ve never integrated with the Adafruit services. In my opinion, it must be something missing in your code to make it work, but I don’t have have tutorials on that exact subject.

      Regards,
      Rui

      Reply
  14. Hi Rui, thanks a lot for your code!!!

    I am testing it and it works great!!!

    I am only experiencing some problems when I´m using my smartphone with chrome because sometime it doesn’t disconnect the client, so, if I switch to my browser in my PC I got stucked in the PC browser, I can only send commands in the phone, because the client is still connected in the phone.

    Here you can see how the client is still connected using the phone, it disconnects properly but inmediately it connects again:

    GET /4/off HTTP/1.1
    01:36:26.620 -> Host: 192.168.2.184
    01:36:26.620 -> Connection: keep-alive
    01:36:26.620 -> Upgrade-Insecure-Requests: 1
    01:36:26.620 -> User-Agent: Mozilla/5.0 (Linux; Android 8.0.0; Mi MIX 2S Build/OPR1.170623.032) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36
    01:36:26.655 -> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    01:36:26.655 -> Referer: http://192.168.2.184/4/on
    01:36:26.655 -> Accept-Encoding: gzip, deflate
    01:36:26.655 -> Accept-Language: es-ES,es;q=0.9,en;q=0.8
    01:36:26.655 ->
    01:36:26.655 -> GPIO 4 off
    01:36:26.655 -> Client disconnected.
    01:36:26.655 ->
    01:36:26.655 -> New Client.

    Do you know why is this happenning?

    Reply
  15. hello i use wifimanger and it works great and saves the cridentials so i dont have to reenter them, but i need to access it from an android as well so i changed my wifimanger to ken taylors version. that works great to access with the androit and it prints out the ip address to access and everything but IT DONT SAVE the cridentials and so i have to reenter everytime i turn on my device. i read in kens notes he did that for a reason but does anyone have a fix for it so that i can get the best of both worlds? please help!

    Reply
  16. The wifi manager is very slic but would be much better if it added the ability to read back I.P address through the access point after connecting with the router as a station, rather than needing to read the Station I.P. back on a serial monitor. Does this capability exist? Thanks.

    Reply
  17. Hi again. I recently asked if there was a way to get the Station IP read back when in AP mode via wifimanager. I found that it is available with the OnDemandConfigPortal example. Also the wifiManager.setAPConfig you have commented out in your above code should be changed to wifiManager.setSTAStaticIPConfig if it is to be used.
    Your tutorials are very useful for filling in most gaps, ofcourse there are always going to be more gaps.

    Reply
    • Hi Chris.
      I’m sorry I missed your latest comment.
      I’m glad you’ve found the solution for what you were looking for. Also, thank you for sharing this solution, it may be useful for other users.
      Thank You.
      Happy new year.

      Reply
    • Hi Chris. We are thinking same thing. Where did you found OnDemandConfigPortal example? Thanks.

      By the way, thank you Sara and Rui for this tutorial.

      Reply
  18. Hi,
    Thanks for the tutorial. I did this project, it works perfectly as expected. I would like to add a manual override button to switch off and on. Could you suggest me what all the changes in code has to be done? Hardware part connecting I can do but I don’t have coding knowledge.

    Reply
  19. Thanks for your quick reply. I am using this for controlling the pump in my apartment.
    Purpose of the button is to allow other people without app manually switch on or off whenever required.

    Reply
    • Hi.
      You need to create a global variable to hold the state of the button.
      Add an if statement to check the button state, and change its value accordingly.
      Alternatively, you can set the button as an interrupt, that when activated runs a function that changes the previous button state.
      Regards,
      Sara

      Reply
  20. Hi,
    Pretty interesting project, this was working fine. But i need to limit the number of attempt for wifi connection in wifimanager. If wifimanger not connected then come out of autoconnect loop and execute the rest of codes.
    or if its possible to assign some connection time, lets say 2 min when esp started. if wifi is not connected then execute the rest of codes offline.
    Help me

    Reply
    • Hi Paras, you can use the following statement to check if the ESP is connected to WiFi or not:
      (WiFi.status() != WL_CONNECTED)

      You can use that in a while, for or if statement with a counter to decide what to do in case the counter reaches a certain number, or in case the ESP connects to WiFi.

      Regards,
      Sara

      Reply
  21. Hi Sara, hi Rui, as usual really interesting tutorial.
    I would point out the json library classes in the code are referred to the json library version 5.xx.x, if you use them with actual library (version 6.12) the compiler is giving out some error.
    I solved removing the 6.12 library and installing an older version.

    Ciao

    Reply
    • Hi.
      You’re right.
      We need to update this tutorial to use the latest library.
      Thanks for pointing that out.
      Regards,
      Sara

      Reply
  22. Hi, again here!!!

    What should I change in order to store a number in a variable instead of GPIO controlling from webserver ?

    Reply
  23. Hi, so today I’m having time to test this the web server, all seems fine but I’m having some difficult to get connected from Smartphone.

    In fact if I try to connect to the AP, as shown in the network list “AutoconnectAP”, very often I receive access denied error. Once connected, when connected, the pages are very slow and when I clik on the wifi setting button (192.168.4.1/wifi) the page get timeout error.

    Please help to solve this seems that the scope of the tutorial is hard-code avoiding so it comes really comfortable to have the chance of setting by smartphone.

    By laptop all is going fine!

    Reply
  24. Great project, thanks for sharing.

    You might want to update the second example to ArdinoJson 6.x otherwise some people not use to json will have problems with the syntax changes…

    Reply
  25. I have successfully used wifimanager to setup the webpage to input the wifi parameters to connect to wifi without putting those parameters directly into the sketch.

    I have also tried Example #2 in your note

    https://randomnerdtutorials.com/wifimanager-with-esp8266-autoconnect-custom-parameter-and-manage-your-ssid-and-password/

    I want to be able to input not only the wifi username and password, but also the username and password to connect to an mqtt broker.

    I followed the suggested directions to add parameters in that note, and it compiles, but when it comes up it still only shows the ON/OFF button, but not the mqtt_server box.

    In addition to get your original sketch to work, I had to upgrade the json calls, as per a note seen when I compile.

    The ON/OFF button is in the HTML file that is generated in the sketch. It uses a “button” call. How do I get it to request the strings that are the mqtt username and password?

    Do you have a complete sketch in which you have added parameters, which are initially requested throough the web then stored in SPIFF for subsequent use? Your example #2 only suggests adding variables for mqtt_server but doesn’t seem to include the code to add that new parameter to the html page.

    Thanks

    Reply
  26. Hi nice example can you please add an erase credential button (hardware or gui or both) like the
    // Uncomment and run it once, if you want to erase all the stored information
    //wifiManager.resetSettings();
    does but without re flashing only a reboot …..

    thanks

    Reply
    • You have all the information you need to implement this. You may have to look at a couple different examples if you need more information. Just call the resetSettings procedure in response to an input .

      Reply
  27. Can I use Arduino Json 6? I have a project code I’m working on, it works only with arduinojson 6, I want to also include the code from this tutorial but I found out that this code only work with arduinojson 5. Is there a way for me to use Arduinojson 6 ?
    Thank you

    Reply
  28. Will this code work on ESP32 ? I tried uploading it to an ESP32 but it fails. It seems like i’m using the wrong libraries to work with the esp32. Need help please. Thank you

    Reply
  29. Again very good examples
    A question for a standalone application (without Router)
    Woud it be possible to configured the ESP using WiFi manager in a way that the ESP create an access point ?

    Reply
  30. Great stuff. Just what I was looking for to build a large number of D1 Mini Sensors and configuring WiFi and MQTT without reflashing each single unit.
    However, the ArduinoJSON Library used in this Tutorial is outdated. Current Version is 6.x.x and has completely different functions e.g. instead of DynamicJsonBuffer the new (and suppposedly better) DynamicJsonDocument is used – unfortunately with a differen syntax. Downgrading to Version 5.x.x helps to make the sketch run but that’s not the way it should be.
    Also the compiler keeps nagging that SPIFFS is deprecated.
    It would be great, if you could provide an update. My skills aren’t sufficient enough to do it.

    Reply
  31. Nice tutorial,
    but I want to ask you if there is a source tha I can use with default SSID and password
    I mean… if I allready compile with default SSID and pass is connect
    or else if I not inserted defalt SSID and pass will start a webpage manager.

    Reply
  32. I love the stuff that you guys produce and as I wanted to use this sketch but I noticed that you hadn’t got around to updating the code for ArduinoJson v6.x, I figured I’d give it a shot. The following code compiles with the v6 library:


    #include <FS.h> //this needs to be first, or it all crashes and burns...
    #include <ESP8266WiFi.h>
    #include <DNSServer.h>
    #include <ESP8266WebServer.h>
    #include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
    #include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson

    // Set web server port number to 80
    WiFiServer server(80);

    // Variable to store the HTTP request
    String header;

    // Auxiliar variables to store the current output state
    String outputState = "off";

    // Assign output variables to GPIO pins
    char output[2] = "5";

    //flag for saving data
    bool shouldSaveConfig = false;

    //callback notifying us of the need to save config
    void saveConfigCallback () {
    Serial.println("Should save config");
    shouldSaveConfig = true;
    }

    void setup() {
    Serial.begin(115200);

    //clean FS, for testing
    //SPIFFS.format();

    //read configuration from FS json
    Serial.println("mounting FS...");

    if (SPIFFS.begin()) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
    //file exists, reading and loading
    Serial.println("reading config file");
    File configFile = SPIFFS.open("/config.json", "r");
    if (configFile) {
    Serial.println("opened config file");
    size_t size = configFile.size();
    // Allocate a buffer to store contents of the file.
    std::unique_ptr<char[]> buf(new char[size]);

    configFile.readBytes(buf.get(), size);
    DynamicJsonDocument doc(1024);
    DeserializationError error = deserializeJson(doc, buf.get());
    serializeJson(doc, Serial);
    if (error) {
    Serial.println("\nparsed json");
    strcpy(output, doc["output"]);
    } else {
    Serial.println("failed to load json config");
    }
    }
    }

    } else {
    Serial.println("failed to mount FS");
    }
    //end read

    WiFiManagerParameter custom_output("output", "output", output, 2);

    // WiFiManager
    // Local intialization. Once its business is done, there is no need to keep it around
    WiFiManager wifiManager;

    //set config save notify callback
    wifiManager.setSaveConfigCallback(saveConfigCallback);

    // set custom ip for portal
    //wifiManager.setAPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

    //add all your parameters here
    wifiManager.addParameter(&custom_output);

    // Uncomment and run it once, if you want to erase all the stored information
    //wifiManager.resetSettings();

    //set minimu quality of signal so it ignores AP's under that quality
    //defaults to 8%
    //wifiManager.setMinimumSignalQuality();

    //sets timeout until configuration portal gets turned off
    //useful to make it all retry or go to sleep
    //in seconds
    //wifiManager.setTimeout(120);

    // fetches ssid and pass from eeprom and tries to connect
    // if it does not connect it starts an access point with the specified name
    // here "AutoConnectAP"
    // and goes into a blocking loop awaiting configuration
    wifiManager.autoConnect("AutoConnectAP");
    // or use this for auto generated name ESP + ChipID
    //wifiManager.autoConnect();

    // if you get here you have connected to the WiFi
    Serial.println("Connected.");

    strcpy(output, custom_output.getValue());

    //save the custom parameters to FS
    if (shouldSaveConfig) {
    Serial.println("saving config");
    DynamicJsonDocument doc(1024);
    // JsonObject& json = jsonBuffer.createObject();
    doc["output"] = output;

    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
    Serial.println("failed to open config file for writing");
    }

    serializeJson(doc, Serial);
    serializeJson(doc, configFile);
    configFile.close();
    //end save

    }

    // Initialize the output variables as outputs
    pinMode(atoi(output), OUTPUT);
    // Set outputs to LOW
    digitalWrite(atoi(output), LOW);;

    server.begin();
    }

    void loop(){
    WiFiClient client = server.available(); // Listen for incoming clients

    if (client) { // If a new client connects,
    Serial.println("New Client."); // print a message out in the serial port
    String currentLine = ""; // make a String to hold incoming data from the client
    while (client.connected()) { // loop while the client's connected
    if (client.available()) { // if there's bytes to read from the client,
    char c = client.read(); // read a byte, then
    Serial.write(c); // print it out the serial monitor
    header += c;
    if (c == '\n') { // if the byte is a newline character
    // if the current line is blank, you got two newline characters in a row.
    // that's the end of the client HTTP request, so send a response:
    if (currentLine.length() == 0) {
    // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
    // and a content-type so the client knows what's coming, then a blank line:
    client.println("HTTP/1.1 200 OK");
    client.println("Content-type:text/html");
    client.println("Connection: close");
    client.println();

    // turns the GPIOs on and off
    if (header.indexOf("GET /output/on") >= 0) {
    Serial.println("Output on");
    outputState = "on";
    digitalWrite(atoi(output), HIGH);
    } else if (header.indexOf("GET /output/off") >= 0) {
    Serial.println("Output off");
    outputState = "off";
    digitalWrite(atoi(output), LOW);
    }

    // Display the HTML web page
    client.println("<!DOCTYPE html><html>");
    client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
    client.println("<link rel=\"icon\" href=\"data:,\">");
    // CSS to style the on/off buttons
    // Feel free to change the background-color and font-size attributes to fit your preferences
    client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
    client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
    client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
    client.println(".button2 {background-color: #77878A;}</style></head>");

    // Web Page Heading
    client.println("<body><h1>ESP8266 Web Server</h1>");

    // Display current state, and ON/OFF buttons for the defined GPIO
    client.println("<p>Output - State " + outputState + "</p>");
    // If the outputState is off, it displays the ON button
    if (outputState=="off") {
    client.println("<p><a href=\"/output/on\"><button class=\"button\">ON</button></a></p>");
    } else {
    client.println("<p><a href=\"/output/off\"><button class=\"button button2\">OFF</button></a></p>");
    }
    client.println("</body></html>");

    // The HTTP response ends with another blank line
    client.println();
    // Break out of the while loop
    break;
    } else { // if you got a newline, then clear currentLine
    currentLine = "";
    }
    } else if (c != '\r') { // if you got anything else but a carriage return character,
    currentLine += c; // add it to the end of the currentLine
    }
    }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");

    }
    }

    Hope this helps someone.

    Reply
  33. Dear Rui,
    Happy new year.
    How are you?
    How to recovery the ssid and psw saved in the Wifimanager STA mode?
    i have tried many things, but the only think that it save is SSID and PSW from AP mode.
    I appreciate your help!

    Reply
  34. Thank you Rui very appreciated with your work!, can you point me to the right direction on how to implement UPNP with this method?
    Im working on product that requires the End user to set up WIFI and automatically be able to access remotely.
    Thank you so much

    Reply
  35. Hi. I am really enjoying your tutorials. Learning a lot!

    I am building a Node-RED console and a ESP-01 digital thermometer to teach physical computing, IoT and AI to kids. A defining element of my project is that I need to be able to quickly set up in random workshop locations. So I need an easy way to enter wifi credentials into the ESP-01.

    I have managed to merge the code from the following tutorials:
    esp8266-and-node-red-with-mqtt
    esp8266-dht11dht22-temperature-and-humidity-web-server-with-arduino-ide
    esp8266-ota-updates-with-arduino-ide-over-the-air

    However, I cannot integrate wifimanager-with-esp8266-autoconnect-custom-parameter-and-manage-your-ssid-and-password/ because the wifimanager code doesn’t create values for ssid and password and the other code requires these.

    Can you give me any pointers on how to go about this? I need the merged code from the 3 tutorials, plus the wifimanager for entering the SSID, password and MQTT ip.

    Thanks

    Reply
  36. Hello,

    It was great and worked perfectly, thank you very much.

    I have tried to add LED to blink while connecting then keep ON when connecting to the WIF after entering the SSID credential. Would you please help with this?

    Thank you

    Reply
    • I would like to do the exact same thing, but I have not gotten it to work yet… In previous projects, I would use the ESP8266WiFi library and use various WiFi.status() responses to blink an LED at different speeds to indicate whether the device was connecting, connected, or in error. I’ve tried to recreate this with WiFiManager with no success. I’ve used both blocking and non-blocking varieties, and also tried blinking the LED using delay() and millis(). Any combination of these results in the device either crashing or some other part not working properly. Can anyone help please?

      Reply
      • Add me to the list of folks wanting to do the same thing! Blink an LED while until the WiFiManager connects or reaches its time out.

        Reply
  37. Excellent tutorial and what a simplistic way you have to teach Rui. Thanks for your service to budding electronic hobbyists. I do have one question. I have to give a temperature Humidity monitor to a friend and for some reason after initial wifi configuration, its hard to find how what IP ( 192.168.1.xx) it will configure the page. Is there a way to setup static IP, I tried but seems it does not work.

    Reply
  38. Hi, followed your instructions to the letter but get the following error code when compiling:
    error: ‘wifi_country_t’ does not name a type
    const wifi_country_t WM_COUNTRY_US{“US”,1,11,WIFI_COUNTRY_POLICY_AUTO};

    Regards Don….

    Reply
  39. I make some changes to work with ESP32 and ArduinoJson library version 6 (updating the previous comment)

    /*********
    Rui Santos
    Complete project details at https://randomnerdtutorials.com
    *********/

    #include <FS.h> //this needs to be first, or it all crashes and burns…
    #include <WiFi.h>
    #include <DNSServer.h>
    #include <WebServer.h>
    #include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
    #include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson
    #include “SPIFFS.h”

    // Set web server port number to 80
    WiFiServer server(80);

    // Variable to store the HTTP request
    String header;

    // Auxiliar variables to store the current output state
    String outputState = “off”;

    // Assign output variables to GPIO pins
    char output[2] = “5”;

    //flag for saving data
    bool shouldSaveConfig = false;

    //callback notifying us of the need to save config
    void saveConfigCallback () {
    Serial.println(“Should save config”);
    shouldSaveConfig = true;
    }

    void setup() {
    Serial.begin(115200);

    //clean FS, for testing
    //SPIFFS.format();

    //read configuration from FS json
    Serial.println(“mounting FS…”);

    if (SPIFFS.begin()) {
    Serial.println(“mounted file system”);
    if (SPIFFS.exists(“/config.json”)) {
    //file exists, reading and loading
    Serial.println(“reading config file”);
    File configFile = SPIFFS.open(“/config.json”, “r”);
    if (configFile) {
    Serial.println(“opened config file”);
    size_t size = configFile.size();
    // Allocate a buffer to store contents of the file.
    std::unique_ptr<char[]> buf(new char[size]);

    configFile.readBytes(buf.get(), size);

    // DynamicJsonBuffer jsonBuffer;
    StaticJsonDocument json;
    // JsonObject& json = jsonBuffer.parseObject(buf.get());
    // json.printTo(Serial);
    serializeJsonPretty(json, Serial);
    // if (json.success()) {
    JsonObject object = json.as();

    if (!object.isNull()) {
    Serial.println("\nparsed json");
    strcpy(output, json["output"]);
    } else {
    Serial.println("failed to load json config");
    }
    }
    }

    } else {
    Serial.println(“failed to mount FS”);
    }
    //end read

    WiFiManagerParameter custom_output(“output”, “output”, output, 2);

    // WiFiManager
    // Local intialization. Once its business is done, there is no need to keep it around
    WiFiManager wifiManager;

    //set config save notify callback
    wifiManager.setSaveConfigCallback(saveConfigCallback);

    // set custom ip for portal
    //wifiManager.setAPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

    //add all your parameters here
    wifiManager.addParameter(&custom_output);

    // Uncomment and run it once, if you want to erase all the stored information
    //wifiManager.resetSettings();

    //set minimu quality of signal so it ignores AP’s under that quality
    //defaults to 8%
    //wifiManager.setMinimumSignalQuality();

    //sets timeout until configuration portal gets turned off
    //useful to make it all retry or go to sleep
    //in seconds
    //wifiManager.setTimeout(120);

    // fetches ssid and pass from eeprom and tries to connect
    // if it does not connect it starts an access point with the specified name
    // here “AutoConnectAP”
    // and goes into a blocking loop awaiting configuration
    wifiManager.autoConnect(“AutoConnectAP”);
    // or use this for auto generated name ESP + ChipID
    //wifiManager.autoConnect();

    // if you get here you have connected to the WiFi
    Serial.println(“Connected.”);

    strcpy(output, custom_output.getValue());

    //save the custom parameters to FS
    if (shouldSaveConfig) {
    Serial.println(“saving config”);
    // DynamicJsonBuffer jsonBuffer;
    StaticJsonDocument json;
    // JsonObject& json = jsonBuffer.createObject();
    json[“output”] = output;

    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
    Serial.println("failed to open config file for writing");
    }

    // json.printTo(Serial);
    // json.printTo(configFile);
    serializeJsonPretty(json, Serial);
    serializeJsonPretty(json, configFile);
    configFile.close();
    //end save
    }

    // Initialize the output variables as outputs
    pinMode(atoi(output), OUTPUT);
    // Set outputs to LOW
    digitalWrite(atoi(output), LOW);;

    server.begin();
    }

    void loop(){
    WiFiClient client = server.available(); // Listen for incoming clients

    if (client) { // If a new client connects,
    Serial.println(“New Client.”); // print a message out in the serial port
    String currentLine = “”; // make a String to hold incoming data from the client
    while (client.connected()) { // loop while the client’s connected
    if (client.available()) { // if there’s bytes to read from the client,
    char c = client.read(); // read a byte, then
    Serial.write(c); // print it out the serial monitor
    header += c;
    if (c == ‘\n’) { // if the byte is a newline character
    // if the current line is blank, you got two newline characters in a row.
    // that’s the end of the client HTTP request, so send a response:
    if (currentLine.length() == 0) {
    // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
    // and a content-type so the client knows what’s coming, then a blank line:
    client.println(“HTTP/1.1 200 OK”);
    client.println(“Content-type:text/html”);
    client.println(“Connection: close”);
    client.println();

    // turns the GPIOs on and off
    if (header.indexOf("GET /output/on") >= 0) {
    Serial.println("Output on");
    outputState = "on";
    digitalWrite(atoi(output), HIGH);
    } else if (header.indexOf("GET /output/off") >= 0) {
    Serial.println("Output off");
    outputState = "off";
    digitalWrite(atoi(output), LOW);
    }

    // Display the HTML web page
    client.println("<!DOCTYPE html><html>");
    client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
    client.println("<link rel=\"icon\" href=\"data:,\">");
    // CSS to style the on/off buttons
    // Feel free to change the background-color and font-size attributes to fit your preferences
    client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
    client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
    client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
    client.println(".button2 {background-color: #77878A;}</style></head>");

    // Web Page Heading
    client.println("<body><h1>ESP8266 Web Server</h1>");

    // Display current state, and ON/OFF buttons for the defined GPIO
    client.println("<p>Output - State " + outputState + "</p>");
    // If the outputState is off, it displays the ON button
    if (outputState=="off") {
    client.println("<p><a href=\"/output/on\"><button class=\"button\">ON</button></a></p>");
    } else {
    client.println("<p><a href=\"/output/off\"><button class=\"button button2\">OFF</button></a></p>");
    }
    client.println("</body></html>");

    // The HTTP response ends with another blank line
    client.println();
    // Break out of the while loop
    break;
    } else { // if you got a newline, then clear currentLine
    currentLine = "";
    }
    } else if (c != '\r') { // if you got anything else but a carriage return character,
    currentLine += c; // add it to the end of the currentLine
    }
    }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");

    }
    }

    Reply
  40. Perhaps adding a push button with a pull up resistor can be used to reset the config file. Just add a routine to execute the wifiManager.resetSettings(); if the button is pressed within 2 seconds of booting up the board. After 2 seconds nothing will happen. This would be easier then compiling and uploading code just to reset.

    if (millis() < 2000) {
    resetPin=digitalRead(pin);
    if (resetPin == HIGH) { wifiManager.resetSettings(); }
    }

    Reply
  41. Hi Sara and Rui,

    If the board is not connected to the serial monitor, i.e. only powered by using batteries at the first time, I cannot know the local IP address (after setting at screen of ‘WiFiManager’).

    On the other hand, I also try your another tutorial , topic of which is “ESP32 Neopixel Status Indicator and Sensor” . The local IP address is allowed to set ; however, if a user doesn’t have any knowledge of IP address, he/she should not be able to type 192.168.0.xxx or 192.168.1.xxx .

    Both above come to one question :
    Is there any convenient way for user to only enter a name which is then auto-match to that local IP address ? Then by only typing the name the browser, the web page comes out .
    Looking forward to you any idea to do so.
    Thanks.

    Reply
  42. Hi,
    You mention that you can use the custom parameters to : “.. to add a different API Key, etc.. Is there an example of changing an API key posted? It would be awesome if I could use the output field you have listed in one of the examples to update this API key. Many API keys have expiration dates and the code will stop if they are not periodically updated. Any links or examples appreciated. Thx!

    Reply
  43. hi, this is pretty good web page and thank you for that.
    well let me ask…this wifi manager is perfect thing but in my project i would need to input 5 parameters in first run of 8266 (wifi creditential, thingspeak api key and channel, and time interval for deepsleep). how could i solve it? is this solution somewhere in your ebook here? then i am gonna buy. thank you.
    denis

    Reply
  44. Help. it Goes Back AP mode every time there is a power outage. Using ESP-01 for ESPALEXA and want wifimanager to have an option to change wifi network if needed.

    CODE:

    #include <Espalexa.h>
    #include<WiFiManager.h>

    // define the GPIO connected with Relays
    #define RelayPin1 0 //D1
    #define RelayPin2 2 //D2

    //direct callback functions
    void device1Changed(uint8_t brightness);
    void device2Changed(uint8_t brightness);

    // device names
    String Device_1_Name = “Red light”;
    String Device_2_Name = “Green light”;

    Espalexa espalexa;

    void setup()
    {
    WiFi.mode(WIFI_STA);
    Serial.begin(115200);

    pinMode(RelayPin1, OUTPUT);
    pinMode(RelayPin2, OUTPUT);

    WiFiManager wm;
    bool res;
    res = wm.autoConnect(“AutoConnectAP”,”password”); // password protected ap
    if(!res) {
    Serial.println(“Failed to connect”);
    // ESP.restart();
    }
    else {
    //if you get here you have connected to the WiFi
    Serial.println(“connected…yeey :)”);
    }

    {
    // Define your devices here.
    espalexa.addDevice(Device_1_Name, device1Changed);
    espalexa.addDevice(Device_2_Name, device2Changed);

    espalexa.begin();

    }
    }

    void loop()
    {
    espalexa.loop();
    delay(1);
    }

    //our callback functions
    void device1Changed(uint8_t brightness){
    0;
    //Control the device
    if (brightness == 255)
    {
    digitalWrite(RelayPin1, LOW);
    Serial.println(“Device1 ON”);
    }
    else if (brightness == 0)
    {
    digitalWrite(RelayPin1, HIGH);
    Serial.println(“Device1 OFF”);
    }
    else
    {
    int brigh_perc = (brightness/255.)*100;
    analogWrite(RelayPin1, brightness);
    Serial.print(“Device1 Brightness: “);
    Serial.print(brigh_perc);
    Serial.println(“%”);

    }
    }

    void device2Changed(uint8_t brightness)
    {
    //Control the device
    if (brightness == 255)
    {
    digitalWrite(RelayPin2, LOW);
    Serial.println(“Device2 ON”);
    }
    else
    {
    digitalWrite(RelayPin2, HIGH);
    Serial.println(“Device2 OFF”);
    }
    }

    Reply
  45. hey the code works well when I add 1 custom parameter but it gives some Guru error when I add 3-4 custom parameters. What could be the reason?
    Need help!!

    Reply
  46. Great software. I love it.
    I want to set an fix IP within a network. So I need a possibility to input 3 fields: IP, GW, SN in addition to the list of available SSIDs and Password. Is there an easy way to do so?
    Thanks for your response.
    Klaus

    Reply
      • Hi Sara, Yes I checked this tutorial. I installed the LittleFS and can compile the code. I connect the computer with the network ESP-Wifi-Manager and try to get a page on 192.168.4.1 but the response is:
        This 192.168.4.1 page can’t be found
        No webpage was found for the web address: http://192.168.4.1/
        so less success as with the other wifi-manager.

        Reply
        • Yeah, it works as described. I didn’t upload the Files in LittleFS before. So my fault – sorry. Nevertheless I prefer this WiFiManager because of the network list. I modified the ON/OFF page to a reset page, where I can go back to the AccessPoint again. Now I try to get the IP/GW/SN fields into the page of this WiFiManager. If there is any recommendation I would appreciate it.
          Best regards
          Klaus

          Reply
  47. I have set-up a wifimanager with extra parameters. It is working very well.
    The next step would be to use time in my application.
    Until now I have not been able to sync time via NTP.
    I tried several different solutions.
    Some way or another the WiFi manager prevents that time is synchronised.

    Has somebody any clue what might be the solution?

    Reply
  48. Hi Rui & Sarah,
    First,
    You guys are truly awesome! Thank you for this all all tutorials you guys share with us. I am new to arduino and must say that your tutorials have been instrumental for aging beginners, like myself. Proof that one is never too old to learn new things.. You guys have a perfect way on explaining how things work in simple, plain english. Again, Thank you both for all your hard work.
    Second ,
    I am using the above sweb server sketch to control the GPIO of an esp-o1 relay module. It works flawlessly, but is the a way I can add browser authentication so that individuals with the correct user name and passwords can access the GPIO’S on/off web page/

    I found a tutorial published by you guys (ESP32/ESP8266 Web Server HTTP Authentication (Username and Password Protected) which is exactly what I am looking to do but I have been unable to get it to work or correctly with this skecth. When you have a moment can you please let me know if there is a way I can add authentication to this sketch so it can perform the same function as your esp32/esp8266 web serverHTTP Auth. sketch. Thank you..

    Reply
  49. Hello,

    Firstly thank you for the amazing tutorial. Works like a charm!!

    I am making a voice controlled magic wand with MIT app project and I have two queries which you may help me with: ( Maybe it is already addressed in Q/A. If so let me know )

    1) Is there a way to setup custom IP address for NodeMCU since I may not have access to serial monitor and I may not know the IP address my app should connect to.

    2) Is there a way to send data from NodeMCU to MIT app inventor? I want the app to record the voice when a button ( sensor ) is pressed on NodeMCU.

    Thank you for reading this.

    Reply
  50. Hello everyone
    I would need to know how I recover the value of ssid and password that I have entered to activate the connection on the network.
    Currently I receive the confirmation of the connection with the local IP but I would like to have those values entered because I am testing the tutorial “Reconnect ESP8266 NodeMCU to Wi-Fi Network After Lost Connection” and the values of “ssid” and “password” must be entered as parameters in:
    WiFi.begin(ssid, password)
    with the values obtained after using the wifimanager library.
    Any help for this case?

    Reply
  51. Does reset button press only restarts ESP8266.

    How can I override the behavior on press of reset button that it shows my wifi and parameter reconfiguration page. I mean how to show wifi configuration screen on press of reset button?

    Reply
  52. Thanks for the excellent guide. I have used it and it works normally. but there is a little annoying problem. when the power goes out and the wifi is not ready, the esp will switch to the “AutoConnectAp” hotspot and when the wifi is ready the esp still doesn’t connect to the wifi that is ready.
    Is there a way to set the wifi scan time delay longer so that there is more time for wifi ready esp to be able to reconnect after the power goes out. so we no longer need to connect manually. because it will be troublesome if our condition is out of town

    Reply
  53. Thank you for the excellent tutorial! I would like to know if you have addressed where the SSID and password are stored in flash. It is useful to know and have a control over it. I can’t find something relevant in the documentation. Many thanks!

    Reply
  54. Hi..Thank you for your sharing. I have a problem to migrate Arduino Json5 instruction to Json7 due to my library update. May I know ho to resolve the problem. Thank you

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.