Using NVS to save a configuration or settings

DylanWork
Posts: 32
Joined: Wed Jun 02, 2021 4:27 am

Using NVS to save a configuration or settings

Postby DylanWork » Tue Mar 28, 2023 12:52 am

Hi all,

I'm having some trouble implementing a way to save some settings that I want to be configurable.
These will rarely be changed (if ever), but having the option is very valuable.

It looks like blob storage is the most appropriate, but I haven't been able to find or adopt an example that works for my use-case.

I am trying to store the settings in a struct (is this the best method?) and saving the struct using blob storage, this part seems to work fine, but updating the table isn't occurring successfully.

The ability to save a configuration or settings to NVS seems like a common use-case, there must be examples out there that I haven't found yet? I require the settings to save across full power cycles.

Here is some code that I've attempted so far:


Save and load functions:

Code: Select all


esp_err_t save_struct(Settings_t Settings)
{
    nvs_handle_t my_handle;
    esp_err_t err;

    err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
    if (err != ESP_OK) return err;

    err = nvs_set_blob(my_handle, "Settings", &Settings, sizeof(Settings));
    if (err != ESP_OK) return err;

    err = nvs_commit(my_handle);
    if (err != ESP_OK) return err;

    nvs_close(my_handle);
    return ESP_OK;
}

esp_err_t load_struct(Settings_t *Settings)
{
    nvs_handle_t my_handle;
    esp_err_t err;

    err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
    if (err != ESP_OK) return err;

    size_t required_size = sizeof(Settings_t);
    err = nvs_get_blob(my_handle, "Settings", Settings, &required_size);
    if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;

    nvs_close(my_handle);
    return ESP_OK;
}
Code that gets initiated on a downlink (or any form of comms, could be serial)

Code: Select all


void save_settings(void)
{
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK( err );
    printf("In Saving \n");

    Settings_t Settings = {0};
    err = load_struct(&Settings);
    if (err == ESP_ERR_NVS_NOT_FOUND) {
        Settings.var1= 15;
        Settings.var2= 5;
    } else if (err != ESP_OK) {
        // Handle error
    }

    // vTaskDelay(pdMS_TO_TICKS(2000));


    printf("var1 = %d\n", Settings.var1);
    printf("var2 = %d\n", Settings.var2);
    err = save_struct(Settings);
    if (err != ESP_OK) {
        // Handle error
    }
}
The downlink receive code

Code: Select all

void messageReceived(const uint8_t* message, size_t length, ttn_port_t port)
{
    printf("Message of %d bytes received on port %d:", length, port);
        Settings.var1= message[1];
        printf("var1%d\n", Settings.var1);
        Settings.var2= message[2];
        save_settings();
        printf("After Saving \n");
}

The struct from main.h

Code: Select all

typedef struct {
    int var1;
    int var2;
} Settings_t;

extern Settings_t Settings;
This seems to update the var1/2 in the struct but doesn't appear to update the NVS, this is evident as the values are correctly updated when in normal operation (they receive the downlink and update accordingly), but then on full power reset they return to this values:
var1 = 1073478214
var2 = 1073478204

Which I believe are memory addresses? I just quickly tried a few things relating to this question with no change in outcome so I'll just post here for now.

Has anyone tried to save a configuration to blob NVS or similar? Am I taking the right approach?

Cheers,
Dylan

User avatar
corz.org
Posts: 80
Joined: Fri Feb 03, 2023 10:44 pm
Location: Aberdeen
Contact:

Re: Using NVS to save a configuration or settings

Postby corz.org » Tue Mar 28, 2023 3:18 am

Why not use the built-in preferences library? It makes saving data to NVS extremely easy.

DylanWork
Posts: 32
Joined: Wed Jun 02, 2021 4:27 am

Re: Using NVS to save a configuration or settings

Postby DylanWork » Tue Mar 28, 2023 4:56 am

That sounds perfect, but I can't see that in the ESP-IDF. I can see it in this tutorial, looks like it's installed when adding boards on the Arduino platform?
https://randomnerdtutorials.com/esp32-s ... eferences/
I'm using ESP-IDF V4.4, do you know of any examples that are would work using C, I'll still check out the preferences.h library, cheers for sharing.

User avatar
corz.org
Posts: 80
Joined: Fri Feb 03, 2023 10:44 pm
Location: Aberdeen
Contact:

Re: Using NVS to save a configuration or settings

Postby corz.org » Tue Mar 28, 2023 5:07 am

Ah sorry! It hadn't crossed my mind that it wasn't included (my Eclipse install refuses to play ball so I use Arduino IDE, which is pretty handy and anyway suits my everyman style of working. Now that I know such thing are not included, I'll likely never bother!).

When I started using NVS for storage (for this: https://corz.org/public/scripts/ESP32/SignalGenerator/) I Googled my way to a heap of apparent issues but when I actually used the library, it was super-easy and reliable (so long as you don't try to store more than 4000 bytes - SPIFFS sounds like a better solution there).

As for saving a scruct; that sounds like unnecessary complication. Why not just save two variables?

Also, what IDE are you using?

martins
Posts: 51
Joined: Tue Aug 24, 2021 8:58 am

Re: Using NVS to save a configuration or settings

Postby martins » Tue Mar 28, 2023 8:03 am

DylanWork wrote:
Tue Mar 28, 2023 4:56 am
That sounds perfect, but I can't see that in the ESP-IDF. I can see it in this tutorial, looks like it's installed when adding boards on the Arduino platform?
https://randomnerdtutorials.com/esp32-s ... eferences/
I'm using ESP-IDF V4.4, do you know of any examples that are would work using C, I'll still check out the preferences.h library, cheers for sharing.
NVS is great for storing the settings, ideally in key-value pairs where it is the most effective. There should be plenty information including links to examples in the docs: https://docs.espressif.com/projects/esp ... on-example

Who is online

Users browsing this forum: Google [Bot] and 68 guests