String lookup table and PROGMEM

Hi there,

I'm trying to figure a good way to use a string lookup table and PROGMEM, but my code does not seem to take less ram.

What am I doing wrong?

#ifndef StringTable_h
#define StringTable_h

#include <avr/pgmspace.h>

typedef enum
{
    STR_ID_00_EMPTY             = 0,
    STR_ID_01_MQTT_CONN_FAILED,
    STR_ID_02_MQTT_CONN_SUCCESS,



    STR_ID_MAX,
    STR_ID_NONE,
} StringTableIDTy;

PGM_P const StringTable[STR_ID_MAX] PROGMEM =
{
    "",                                                     // STR_ID_00_EMPTY
    "MQTT server connection failed...",                     // STR_ID_01_MQTT_CONN_FAILED
    "MQTT server connection success...",                    // STR_ID_02_MQTT_CONN_SUCCESS
};


class StringTableClass
{
public:
    static const char* GetString(StringTableIDTy id) {
        char buffer[strlen_P(StringTable[id])];
        strcpy_P(buffer, (PGM_P)pgm_read_word(&StringTable[id]));
        strcpy(thisBuffer, buffer);
        return thisBuffer;
    };

private:
    static char thisBuffer[STRING_MAX_LEN];
};

char StringTableClass::thisBuffer[STRING_MAX_LEN] = "";

#endif

Usage example

//...
Serial.println(StringTableClass::GetString(STR_ID_02_MQTT_CONN_SUCCESS));
//...
const char *errMsg = StringTableClass::GetString(STR_ID_01_MQTT_CONN_FAILED);
//...

The reference of PROGMEM explains it: https://www.arduino.cc/reference/en/language/variables/utilities/progmem/.

If you want the text itself in PROGMEM, then you have to declare them in PROGMEM.
If you also want a list of pointers, then you have to make another step and put those pointers in PROGMEM as well and fill it with pointers to the texts.

There are a few ways around that.
For example an array with a fixed size for every string. That is often acceptable when using a Arduino Mega board with more than enough Flash memory.
Or perhaps a very long string of data with separators. The sketch has to search for the right text.

A table of PROGMEM pointers initialized by the addresses of RAM string constants
does not make much sense to me, and it should not give the right results,
sometimes optimizations can hide that flaw.

Indeed, it does not give the right result. The value displayed is wrong. I get part from another string in the program.

So what would be the best practice to store a table of char arrays? RAM or FLASH?

If you have to change the strings at runtime, there is no way around RAM.
When possible (depending on the Arduino hardware), Flash is better.

If you don't know how to initialize your table properly,
you did not study the link provided by @Koepel.

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