Arduino

Sketch

#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager

void setup() {
    // put your setup code here, to run once:
    Serial.begin(115200);

    //WiFiManager
    //Local intialization. Once its business is done, there is no need to keep it around
    WiFiManager wifiManager;
    //reset saved settings
    //wifiManager.resetSettings();
    
    //filter low signal quality networks, you can tell WiFiManager to not show networks below an arbitrary quality %
    wifiManager.setMinimumSignalQuality(20);
    
    //set custom ip for portal
    wifiManager.setAPStaticIPConfig(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...yeey :)");
}

void loop() {
    // put your main code here, to run repeatedly:
    
}

Store any struct in flash

Hi there I have been writing some code to store any struct that you can create.

so here is the functional code.

void storeStruct(void *data_source, size_t size)
{
  EEPROM.begin(size * 2);
  for(size_t i = 0; i < size; i++)
  {
    char data = ((char *)data_source)[i];
    EEPROM.write(i, data);
  }
  EEPROM.commit();
}

void loadStruct(void *data_dest, size_t size)
{
    EEPROM.begin(size * 2);
    for(size_t i = 0; i < size; i++)
    {
        char data = EEPROM.read(i);
        ((char *)data_dest)[i] = data;
    }
}

it is verry simple every struct is passed by reference, say you have this code:

typedef struct {
  char board_name[64];
  char ssid[64];
  char pass[64];
} settings_t __attribute__ ((packed));

settings_t settings
{
    "test_host",
    "ssid",
    "pass"
};

and you want to store that struct in eeprom/flash! you'd do:

storeStruct(&settings, sizeof(settings));

and to load it:

loadStruct(&settings, sizeof(settings));

here is my test code and that passes:

settings_t settings_original;
void printCmpSettings(settings_t s1, settings_t s2)
{
    Serial.printf("board_name: %s | %s \n"
                  "ssid: %s | %s \n"
                  "pass: %s | %s \n",
                  s1.board_name, s2.board_name,
                  s1.ssid, s2.ssid,
                  s1.pass, s2.pass
                  );
}

memcpy(&settings_original, &settings, sizeof(settings));
storeStruct(&settings, sizeof(settings));
loadStruct(&settings, sizeof(settings));
if(!memcmp(&settings_original, &settings, sizeof(settings)))
{
    Serial.println("settings are the same!");
    printCmpSettings(settings_original, settings);
}
else
{
    Serial.println("settings are not the same!");
    printCmpSettings(settings_original, settings);
}

memcpy(&settings_original, &settings, sizeof(settings));
strcpy(settings.board_name, "test_host");
storeStruct(&settings, sizeof(settings));
loadStruct(&settings, sizeof(settings));
if(!memcmp(&settings_original, &settings, sizeof(settings)))
{
    Serial.println("settings are the same!");
    printCmpSettings(settings_original, settings);
}
else
{
    Serial.println("settings are not the same!");
    printCmpSettings(settings_original, settings);
}

it is really nice because you can make those structs as complicated or simple as you want. a few notes. your struct needs to be packed! and it needs to be alligned with flash! also if you want to put structs in a struct you want to do it like this:

struct Employee
{
   char ename[20];
   int ssn;
   float salary;
   struct date
       {
       int date;
       int month;
       int year; 
       }doj;
}emp1;