Optimizing code by shortening array - Help please

Hi there everyone,

sorry if this is already covered in some topics, but I couldn't find it. I will go straight to the point:

I have a project where I load texts from .txt files that are stored on SD card and display them on my TFT.
The point is that I've organised files in different folders on SD card depending on what screen needs to be drawn.

So, the way I load files is that, based on an IF condition, I call a specific file address:

example: MFile = "tx/a/1_1.txt"

*where MFile is word type variable (later on I use MFile in another function to call a file)

As you can, see I've already shortened all the names of files and folders so it wouldn't take too much dynamic memory. But as I have more and more files, many of them share the same folder, so I thought how I could save my dynamic memory even more if I "pre-store" part of file location in an array and just add the remaining part.

So I thought about something like this:

char MFile[30];

if (base condition){ //condition that many files share so I can write base address

MFile[0] = "tx/a/";
//I'm not sure what should I write to fill first few places of MFile with that written address?

if(second condition) MFile[4] = "1_1.txt"//to fulfill my address
else if(second condition) MFile[4] = "1_2.txt"

and so on...

}

I hope you understand what I would like to achieve and that someone could help me make it work.

Thanks in advance :slight_smile:

You don't need to do that. When you need to construct the filename just test the value of what you are calling the base address and and append the appropriate text. Something like

char fileName[20];

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  makeFilename(0, "wibble.txt");
  Serial.println(fileName);
  makeFilename(1, "wibble.txt");
  Serial.println(fileName);
  makeFilename(0, "wobble.txt");
  Serial.println(fileName);
  makeFilename(2, "wobble.txt");
  Serial.println(fileName);
}

void loop()
{
}

void makeFilename(byte fileRange, char * name)
{
  char * paths[] = {"tx/a/", "tx/b/", "tx/c/"};
  strcpy(fileName, paths[fileRange]);
  strcat(fileName, name);
}

Thank you very very much. I'll try it later and I'll came back with my results.

Once more, thank you👍

Unfortunately the SD card library does not support storing filenames in program memory , but you can save a considerable amount of dynamic memory by storing the filenames in program (flash) memory then copying to a buffer.

char fileName[20];

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  makeFilename_P(0, PSTR("wibble.txt")); //PSTR() tells compiler to store text in program (flash) memory
  Serial.println(fileName);
  makeFilename_P(1, PSTR("wibble.txt"));
  Serial.println(fileName);
  makeFilename_P(0, PSTR("wobble.txt"));
  Serial.println(fileName);
  makeFilename_P(2, PSTR("wobble.txt"));
  Serial.println(fileName);
}

void loop()
{
}

void makeFilename_P(byte fileRange, const char* name)
{
  static const char textA[] PROGMEM = "tx/a/"; //"static" needed inside a function when storing to progmem
  static const char textB[] PROGMEM = "tx/b/";
  static const char textC[] PROGMEM = "tx/c/";
  const char* paths[] = {textA, textB, textC};
  strcpy_P(fileName, paths[fileRange]);
  strcat_P(fileName, name);
}

A bit less efficient, but you can do away with the complication of using the function and just do a straight copy with the full filename if you have the room in program memory.

  strcpy_P(fileName, PSTR("tx/d/wibble.txt"));
  Serial.println(fileName);

Thank you very much, I made it like you suggested. Helped a lot, my dynamic memory usage dropped from 57% to 48%, and I have to shorten some more file names so it will be even more optimized.

Thanks again :smiley: