ESP8266 Wifi Configuration Part 1

So far with the ESP8266 modules we've been using the same network name and password, these values have been hard coded into the program for ease of use. Now imagine that we had a dozen devices all running at the same time, all trying to set up the same wifi network (and yes I realise by using the mac address as part of our SSID we have avoided this problem). The solution, that we're going to talk about today, is to allow the user to configure the network name and password. This is simply good practice as anyone who has logged into a device using 'admin' and 'password' should realise.

The first step is to find a way to store the new values in a way that they will be remembered while the device is turned off, and then be able to load that information when the device turns back on again. On a standard Arduino we'd use the EEPROM which would allow us to write data to a specific type of memory that requires special electrical conditions to be programmed and that retains the information between boots. On the ESP8266 we use exactly the same EEPROM library but it only emulates EEPROM and it actually writes to the flash memory instead (the same place we store the program data to).

The EEPROM libraries do all the hard work of writing to the correct registers within the device but older versions of the library would only read/write single bytes of data to/from the EEPROM. This led someone to create the EEPROMWriteAnything library, this library allows you to define a single data structure that contains all the information you want to store and write it in a single operation. That seems like a lot of preamble but hopefully it'll start to make sense once we put it all together.

The first thing to do is declare a data structure to hold our information we also create an instance of the structure at the same time called 'config'. The structure has two strings of data, one to hold the name of the network and the other to hold the password. Both the password and name can be up to 16 characters long but each string needs to have a null ('0') character at the end so we make byte arrays that are 17 bytes long. We can also give this information default values at the point of decleration.

This now gives us a way to store our information in volatile ram, meaning it will be forgotten at reboot. When the program starts, we want to load this information from the EEPROM overwriting the default values but this puts us in a bit of a catch 22 situation. At some point we need to write this information to the EEPROM before we read it. My solution also doubles up as a firmware reset should you ever forget the wifi password.

As part of the setup function we can initialise one of the input pins to be a reset indicator ('D1'). By pulling the GPIO pin low we can rewrite the password and network name upon program start, this should be done the first time the device is started but it can also be done any time the user requires it. This is akin to holding down a reset button on any electronic gadget while it boots. If the device detects the reset pin it writes the default values to the EEPROM, in both cases the device then reads the values back from the EEPROM before creating a new wifi network. The values are output to the serial port which is not particularly secure but if you already have a physical USB connection there are worse things you could do with the device.

My test setup just has a wire link connecting between D1 and GND, and D1 is configured to use the pullup resistor to provide the high voltage 'on' signal. I spent quite some time on a detour trying to use the built in reset button on the wemos board to provide the same function. It is possible to distinguish between a 'button push' reset and a 'power on' reset but the USB->Serial device (CH340C) is tied into the reset pin to enable the arduino bootloader to reprogram the ESP device so pushing the reset button makes it appear like a power on reset. My detour only identified the problem and I haven't found a solution for it yet.

So that's part 1 of wifi config, we initialise some memory and store some default values to non volatile memory, recalling them at program start and a method for restoring the default values should the password be forgotten. The next part will be to provide a method for a user to actually change the values in eeprom.