Using preferences.h on ESP32 - Variable stored correctly but then overwritten

Hi all,

Reative programming beginner tinkering with a "SparkFun Thing Plus" ESP32 board in the Arduino IDE. I've been using tutorials online to create a basic sketch which fires up a web server on the board and allows me to control the onboard LED on pin 13 from a web browser. So far so good.

I then decided to use the preferences library to store the Wi-Fi credentials (and potentially later allow them to be overwritten from the browser). I've managed to implement this in a very basic first try kind of way, but I'm finding that despite storing both the SSID and Wi-Fi password with unique keys, the code was replacing the SSID value with the password value at some point, and I can't work out why or where.

I then changed the SSID and password values to allow me to copy and paste the output here, and now no longer populates the SSID variable at all, but also is not trying to use the password value.
I have erased the NVS and tried again but can now not get the SSID variable to hold a value from preferences. Any advice would be greatly appreciated.

My understanding of the behaviour I'm expecting for the code I'm using to define the variables is:

  • Create const char * variable called SSID
  • Create the preferences string with a key of SSID and if no value stored (currently clearing the stored values on every boot) define the value of WIFINAME then use .c_str() to allow me to store it in my const char * variable
  • So in theory const char * SSID now holds the value of WIFINAME
  • Output this value to the serial
  • Repeat steps 1-4 for password
  const char * ssid = preferences.getString ("ssid", "WIFINAME").c_str();
  Serial.println(ssid);
  const char * password = preferences.getString ("password", "PASSWORD123").c_str();
  Serial.println(password);

I'm using:

Arduino IDE 1.8.13 (Standalone, not from Windows Store)
ESP32 board manager by Espressif Systems 1.0.6
Windows 10 64bit
SparkFun Thing Plus - ESP32 WROOM

Full code:

// Load Wi-Fi library
#include <WiFi.h>
// Load Preferences library
#include <Preferences.h>

// Define name for Preferences
Preferences preferences;

// 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 output13State = "off";

// Assign output variables to GPIO pins
const int output13 = 13;

// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0; 
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;

void setup() {
  Serial.begin(115200);
  
  // Open Preferences with my-app namespace. Each application module, library, etc
  // has to use a namespace name to prevent key name collisions. We will open storage in
  // RW-mode (second parameter has to be false).
  // Note: Namespace name is limited to 15 chars.
  preferences.begin("vanLife", false);
  
  preferences.clear();
  
  // Replace with your network credentials
  const char * ssid = preferences.getString ("ssid", "WIFINAME").c_str();
  Serial.println(ssid);
  const char * password = preferences.getString ("password", "PASSWORD123").c_str();
  Serial.println(password);

  // Initialize the output variables as outputs
  pinMode(output13, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output13, LOW);
  
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  Serial.print("Using password ");
  Serial.println(password);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();

  // Close the Preferences
  preferences.end();
}

Output was doing this:

WIFI NAME
PASSWORD123
Connecting to PASSWORD123
Using password PASSWORD123
...........................

Now it does this:

PASSWORD123
Connecting to 
Using password PASSWORD123
...........................

+Karma for having read forum instructions. Well done.

Move the declarations for ssid and password out of setup(), make them global. You also have to have used putString() before you can use getString(). You never mentioned if you had done that.

If you don’t quite understand why the variables should be outside of setup(), Google “C variable scope”.

1 Like

Thanks very much for taking the time to respond and providing the information and links.

I've done some reading about the scope of the variables and that makes perfect sense. Glad I learnt that now or I foresee I would have had some hideous problems later trying to work out why variables weren't working! I also managed to create a working version of a sketch for my needs using the Random Nerd Tutorials page you linked, so again thanks so much.

I did have another question, which relates to my not using putString() in my code. I was originally trying to hack my solution in the original post together using this sketch: arduino-esp32/StartCounter.ino at master · espressif/arduino-esp32 · GitHub

This stores a number and increments it by one every time the ESP32 resets. But it does this using unsigned int counter = preferences.getUInt("counter", 0); before using a putUint() .

Is it simply that this sketch is a lot more simplistic in function or was my issue that I was trying to read the value FROM the preferences before I'd putString() it rather than this code increasing it locally then storing TO the preferences?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.