ESP32cam - preferences not persisting on reboot

This is my platformio.ini:

[env:esp32cam]
platform = espressif32
board = esp32cam
framework = arduino

I have checked my code with several tutorials and it seems okay, but reading the preference after rebooting gives the default value.

Preferences prefs;
prefs.begin("store", true);
int value = prefs.getInt("key", 4);
prefs.end();

I save using:

prefs.begin("store", false);
prefs.putInt("key", 3);
prefs.end();

I have done a bit more digging and it transpires that the saving of the changed value isn’t working. So, it isn’t the re-boot that is causing the problem, for now anyway.

Does the example work for you?

Hi, thank you for your reply. Yes, it does work on the ESP32CAM. I didn’t think my dependencies would be relevant, so didn’t include them. They are:

knolleary/PubSubClient
bblanchon/ArduinoJson@^7.1.0
 adafruit/Adafruit BME680 Library@^2.0.4

And included headers are:

#include "Arduino.h"
#include "ArduinoJson.h"
#include <esp_camera.h>
#include <esp_http_server.h>
#include <HTTPClient.h>
#include <soc/rtc_cntl_reg.h>
#include <Preferences.h>
#include <PubSubClient.h>
#include <time.h>
#include <WiFi.h>
#include <Adafruit_BME680.h>

My project uses the RNT project as a basis and I have only half a dozen additional int variables.

If the example works, it proves that it is not due to the ESP32 Cam module. The error is probably in your code which you have not shown completely.

Please show a complete minimal example (including the platformio.ini) which makes the error reproducible.

What strikes me: You open Preferences first as read-only and later again as writable. I have never seen this before and have never used it that way myself.

Simply call prefs.begin("store"); once in setup() and don’t call prefs.end() (except you know the ESP32 will restart soon).

The complete platformio.ini is already posted. The code is essentially complete, in that the attempt to read is in setup() and I write after receiving the new value in an MQTT message.

I’ve tried:

  1. Opening the preferences read-write at the outset and leaving it open afterwards.
  2. Using this instance to write the changed value.
  3. I call preferences.end() immediately after writing, as in the example.

I initiate the re-start (using ESP.restart() and it still fails to load the new value.

Add a delay before calling ESP.restart() as it is done in the example.

I tried that but no difference - or putting a delay between the putInt() and close().

Replacing my setup() completely with just the minimal code to write/read the preference revealed an error message saying my key was too long! It was originally 18 characters. Reducing it to three means my original code works!

Armed with this info, I found that there is a limit of 15 characters, but it is documented under NVS rather than Preferences.

Thank you for your help.

I’m glad you found the reason.

What’s strange about this is that it implies that the code in your first post must have worked because the key name is just “key” (3 letters)!?

It didn’t because I replaced the real key name in my post. I should have redacted it with 'xxxxxx_xxx_xxxxxx" instead!

1 Like