Write string multi value to NVS

s.sirapol
Posts: 2
Joined: Tue Nov 22, 2022 3:57 am

Write string multi value to NVS

Postby s.sirapol » Wed Nov 23, 2022 11:03 am

Hello everyone. I newby for IDF.

I need to using NVS like a arduino EEPROM.
I have many string ( MQTT config ).
I can write some value not at all.
please help me.

Code: Select all

#define nvsPartition "storage"
#define nvsMaxLen_String 100
#define nvsKey_MQTT_HOST "mqttHOST"
#define nvsKey_MQTT_PORT "mqttPORT"
#define nvsKey_MQTT_USER "mqttUSER"
#define nvsKey_MQTT_PASS "mqttPASS"
#define nvsKey_MQTT_Topic_PUB "mqttTopicPub"
#define nvsKey_MQTT_Topic_SUB "mqttTopicSub"
#define nvsKey_Device_SerialNumber "deviceSN"
#define nvsKey_MQTT_INTERVAL "mqttInterval"

Code: Select all

// write function
    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);
    nvs_handle_t my_handle;
    err = nvs_open(nvsPartition, NVS_READWRITE, &my_handle);
    char nvsChar[nvsMaxLen_String];
    memset(nvsChar, 0x00, nvsMaxLen_String);

    if (err != ESP_OK)
    {
        printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
    }
    else
    {
        nvs_set_str(my_handle, nvsKey_MQTT_HOST, c->mqttHOST);
        nvs_set_i16(my_handle, nvsKey_MQTT_PORT, c->mqttPORT);
        nvs_set_str(my_handle, nvsKey_MQTT_USER, c->mqttUSER);
        nvs_set_str(my_handle, nvsKey_MQTT_PASS, c->mqttPASS);
        nvs_set_str(my_handle, nvsKey_MQTT_Topic_PUB, c->mqttTopPub);
        nvs_set_str(my_handle, nvsKey_MQTT_Topic_SUB, c->mqttTopSub);
        nvs_set_str(my_handle, nvsKey_Device_SerialNumber, c->deviceSN);
        nvs_set_i16(my_handle, nvsKey_MQTT_INTERVAL, c->mqttInterval);
        nvs_commit(my_handle);
        printf("Commit pass\r\n");
        nvs_close(my_handle);
    }

Code: Select all

// read function
void readNVS()
{
    printf("----------readNVS----------\r\n");
    nvs_handle_t my_handle;
    esp_err_t err = nvs_open(nvsPartition, NVS_READWRITE, &my_handle);
    char nvsChar[nvsMaxLen_String];
    memset(nvsChar, 0x00, nvsMaxLen_String);
    size_t buf_len = sizeof(nvsChar);
    if (nvs_get_str(my_handle, nvsKey_MQTT_HOST, nvsChar, &buf_len) != ESP_OK)
    {
        printf("nvs_get_str error\r\n");
    }
    else
    {
        printf("MQTT_HOST=|%s|\r\n", nvsChar);
        memset(nvsChar, 0x00, nvsMaxLen_String);
    }
    int16_t mqttPort = 0;
    if (nvs_get_i16(my_handle, nvsKey_MQTT_PORT, &mqttPort) != ESP_OK)
    {
        printf("nvs_get_str error\r\n");
    }
    else
    {
        printf("MQTT_PORT=|%d|\r\n", mqttPort);
    }
    if (nvs_get_str(my_handle, nvsKey_MQTT_USER, nvsChar, &buf_len) != ESP_OK)
    {
        printf("nvs_get_str error\r\n");
    }
    else
    {
        printf("MQTT_USER=|%s|\r\n", nvsChar);
        memset(nvsChar, 0x00, nvsMaxLen_String);
    }
    if (nvs_get_str(my_handle, nvsKey_MQTT_PASS, nvsChar, &buf_len) != ESP_OK)
    {
        printf("nvs_get_str error\r\n");
    }
    else
    {
        printf("MQTT_PASS=|%s|\r\n", nvsChar);
        memset(nvsChar, 0x00, nvsMaxLen_String);
    }
    if (nvs_get_str(my_handle, nvsKey_MQTT_Topic_PUB, nvsChar, &buf_len) != ESP_OK)
    {
        printf("nvs_get_str error\r\n");
    }
    else
    {
        printf("MQTT_TOP_PUB=|%s|\r\n", nvsChar);
        memset(nvsChar, 0x00, nvsMaxLen_String);
    }
    if (nvs_get_str(my_handle, nvsKey_MQTT_Topic_SUB, nvsChar, &buf_len) != ESP_OK)
    {
        printf("nvs_get_str error\r\n");
    }
    else
    {
        printf("MQTT_TOP_SUB=|%s|\r\n", nvsChar);
        memset(nvsChar, 0x00, nvsMaxLen_String);
    }
    int16_t mqttInterval = 0;
    if (nvs_get_i16(my_handle, nvsKey_MQTT_PORT, &mqttInterval) != ESP_OK)
    {
        printf("nvs_get_str error\r\n");
    }
    else
    {
        printf("MQTT_INTERVAL=|%d|\r\n", mqttInterval);
    }
    if (nvs_get_str(my_handle, nvsKey_Device_SerialNumber, nvsChar, &buf_len) != ESP_OK)
    {
        printf("nvs_get_str error\r\n");
    }
    else
    {
        printf("deviceSN=|%s|\r\n", nvsChar);
        memset(nvsChar, 0x00, nvsMaxLen_String);
    }
    nvs_close(my_handle);
}
After i send value for set to nvs. this is result.

Code: Select all

----------readNVS----------
MQTT_HOST=|www.google.com|
MQTT_PORT=|1883|
MQTT_USER=|txst|
nvs_get_str error
nvs_get_str error
nvs_get_str error
MQTT_INTERVAL=|1883|
deviceSN=|SNxxxxx|
The 3 value of middle is not set to nvs and interval is not correct ( i send interval 15sec).
I do check the struct before write to nvs one by one that correct.

Please help me.

ESP_Sprite
Posts: 9749
Joined: Thu Nov 26, 2015 4:08 am

Re: Write string multi value to NVS

Postby ESP_Sprite » Wed Nov 23, 2022 1:45 pm

You're re-using buf_len. When you enter nvs_get_str, it should contain the length of the buffer, but when that function exits, it overwrites the value there with the amount of bytes actually read. So when reading the user (which is 4 characters), this value is presumably set to 4. I imagine your password is longer than that, but the call to get that enters with buf_len set to 4 (the result from the previous call) and the call fails. Solution is to re-set 'buf_len = sizeof(nvsChar);' after every nvs_get_str call.

s.sirapol
Posts: 2
Joined: Tue Nov 22, 2022 3:57 am

Re: Write string multi value to NVS

Postby s.sirapol » Wed Nov 23, 2022 1:59 pm

Oho thank you very much.

Who is online

Users browsing this forum: No registered users and 120 guests