During the wifi configuration tutorial I described a method to provide a firmware reset in the case that you forget the user name and password using an additional button (or wire loop). I also lamented the problems of the Wemos D1 board not being able to distinguish between a power cycle and a button reset. Today I'm going to discuss another way to achieve a firmware reset of the device without the requirement for any additional hardware. The method itself is quite simple and we have already used all required parts for the wifi configuration program.
The first thing the device should do when it starts up, is set a flag in the non volatile memory and after a given period of time it should clear this flag again. Now if the device is reset before it has the chance to clear the flag we can tell that the reset button has been pushed twice in quick succession and use that as an indicator that we want to perform a firmware reset.
There are a few items to declare at the start of the program, we'll be using the EEPROM library to write the flag to a memory location that is remembered between boots. The flag is stored as a 4 byte value and should have two different states, these should not be zero because that is the default value for EEPROM, I have chosen 0x55 and 0xAA as they are alternating bit patterns but the actual values are fairly arbitrary. Finally we should declare a memory location to store the value and a length of time to check the value.
There are two helper functions used to access the EEPROM. CheckFlag looks at the memory location for the flag and returns true if the flag is set. WriteFlag puts a new value in the memory location, don't forget to call EEPROM.commit() which is specific to the ESP devices, this is the function that actually writes the data to the memory locations.
In this example we're going to be using the Serial port and built in LED to indicate the state of the device so those should both be set up immediately. For the EEPROM library to work you need to tell it how many bytes of data it is going to be using. This EEPROM.begin step is something I miss all the time with infuriating results. Next comes the actual checking of the flag, if the flag is still set from the previous boot cycle then we know that we need to perform a firmware reset, in this example we note the state by turning on the LED. If we perform a firmware reset we should clear the flag now so as to avoid a double reset situation. If the flag is not set then we should turn it on now.
Finally there is a little delay loop which waits the given time before clearing the flag, I've added this as a blocking delay at the end of setup because I don't like the idea of my main loop performing a redundant check for the rest of it's execution. It could easily be implemented as a non blocking check in the main loop though.
Now when you download and run the program, if you click the reset button twice within a 3 second period you should see the LED turn on indicating a firmware reset state. As usual the full code is at the bottom.