ESP32 WiFi Manager | Dynamic SSID and Password

ESP32 WiFi Manager

If you've been following my tutorials on ESP32, then you'll notice that the WiFi SSID and password are always hardcoded. This tutorial will show you a way to change the WiFi credentials without needing to edit and re-upload your sketch. Our aim is to create a simple ESP32 WiFi manager.

Overview

There are two scenarios where you would need a WiFi SSID and password. The first is when your ESP32 or ESP8266 is in station mode and another is when those microcontrollers are in access point mode.

Station Mode - device connects to another WiFi router

Access Point Mode - device acts as the WiFi router

In station mode:

WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);

In access point mode:

WiFi.mode(WIFI_AP);
WiFi.softAp(ssid, password);

Both begin() and softAp() functions accept char array pointers and are normally prefixed as constants.

const char * ssid = "my-wifi-ssid"
const char * password = "my-wifi-password"

So our aim is to have these WiFi credentials not be hardcoded but instead come from user input. If so, then ideally, the device should be in access point mode first then shifts to station mode once it gets the WiFi credentials from the user.

Step 1: Create a Form

Once the user connects to the device which is in access point mode, there should be a page to which the WiFi credentials can be registered or updated. For that, we'll create a simple HTML form:

<!DOCTYPE HTML>
<html>
 <head>
  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
  <meta name = "viewport" content = "width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=0">
  <title>WiFi Creds Form</title>
  <style>
   body { background-color: #808080; font-family: Arial, Helvetica, Sans-Serif; Color: #000000; text-align:center; }
  </style>
 </head>
 <body>
  <h3>Enter your WiFi credentials</h3>
  <form action="/" method="post">
  <p>
   <label>SSID:&nbsp;</label>
   <input maxlength="30" name="ssid"><br>
   <label>Key:&nbsp;&nbsp;&nbsp;&nbsp;</label><input maxlength="30" name="password"><br><br>
   <input type="submit" value="Save"> 
  </p>
  </form>
 </body>
</html>

This form has two fields, ssid and password which would contain the WiFi creds from the user. These creds will be readable once the Save button is clicked.

Assuming this form is the root page of the web server hosted by the device, then we can just use the arg() function to retrieve the credentials:

server.on("/", handleRoot);
...
}

void handleRoot() {
  if (server.hasArg("ssid")&& server.hasArg("password")) {
    String ssid = server.arg("ssid");
    String password = server.arg("password");
    // Do next steps here
   ...
   ... 
  }
  else {
    // If one of the creds is missing, go back to form page
    server.send(200, "text/html", INDEX_HTML);
  }
}

Step 2: Store Data to EEPROM

It is logical to store the WiFi creds so that we don't have to ask for them again if the device restarts. For this, we use ESP32's EEPROM.

We initialize two char arrays with a fixed size, preferably equal to the maxlength attribute of our text fields in the form. Then we use the toCharArray() function to convert the Strings ssid and password to char arrays, before finally writing to EEPROM using the writeString() function.

...
char buff1[30];
char buff2[30];
ssid.toCharArray(buff1,30);
password.toCharArray(buff2,30); 
EEPROM.writeString(100,buff1);
EEPROM.writeString(200,buff2);
...

This will now save the WiFi credentials to memory and will stay there regardless if the device is powered or not.

Step 3: Read Data from EEPROM and Fire Away

Now that we are able to acquire the creds from the user and store it in memory, the next thing is to be able to retrieve them from EEPROM. This should be done at the start of the sketch/code so that you wouldn't need to load the form again (unless explicitly).

String s = EEPROM.readString(100);
String p = EEPROM.readString(200);

Here we read the data from EEPROM. Note that the numbers are the specific memory location for the SSID and passwords. If there's nothing there then we load the form. Otherwise, we skip the form and continue. To check if there are WiFi creds on EEPROM, just do:

if(s.length() <= 0 && p.length() <= 0){
   // Load form since no SSID and password found
  ...
}

The full sketch for this tutorial is on this repository.

The code pointed above, on initial commit, will not work on ESP8266 boards yet. We will remove this notice once it's been updated or you can check the repo regularly

Using the Application

After uploading the code in the repo pointed, the ESP32 will broadcast an access point:

ESP32 access point name for WiFi Manager

The password for this access point is 12345678.

Once connected to the AP, go to 192.168.4.1. This is the default access point IP. You can specify this on the code by using:

IPAddress IP = {10, 10, 1, 1};
IPAddress NMask = (255, 255, 255, 0);
...
WiFi.softAPConfig(IP, IP, NMask);

This form should be visible on the IP address:

Form for entering WiFi creds

Enter your router's SSID and password and click Save. The device will restart and store the credentials to EEPROM.

Success message

The access point will be gone and the ESP32's LED will blink every second. To change the WiFi credentials, just short pin 15 to VCC.

For any questions, clarifications or suggestions, kindly drop a comment below!

Leave a Reply

Your email address will not be published. Required fields are marked *