How to name a file using a variable?

Hello all! I am fiddling around with my SD module, trying to figure out how to use it for a data logger project. I've ran into the problem of trying to name a file after a variable, such as the date. I don't have a RTC module (yet) so I set a static variable (dt) for my birthdate (19910401) in YYYYMMDD format (was DDMMYYYY but the leading 0 caused a octal constant error). However when trying to just plug it in as dt.txt or dt".txt" I ran into errors. I had a feeling I would, but tried just in case. Here is the code so far:

#include <SPI.h>
#include <SD.h>


int dt = 19910401;

File myFile;

void setup() {
  
  Serial.begin(9600);
  while (!Serial){}
  Serial.print("Initializing SD Card...");

  if (!SD.begin(10, 11, 12, 13)){
    Serial.println("initialization failed");
    return;
  }
  Serial.println("initilization done.");

  myFile = SD.open(dt.txt, FILE_WRITE);
  myFile.println("will this work?");
  myFile.close();
  }

void loop() {
  // put your main code here, to run repeatedly:

}

any suggestions would be appreciated.

During my google searching I came across sprintf() mentioned in similar posts, but cannot find documentation on it and I do not understand how it works.

ShadowfireOmega:
was DDMMYYYY but the leading 0 caused a octal constant error).

Should not, because the trick is you want it to be text :wink: But yyyymmdd is wayyyyyyy more logical anyway :slight_smile:

ShadowfireOmega:
However when trying to just plug it in as dt.txt or dt".txt" I ran into errors.

Like I said, it should be text :wink: And then concat it with the ".txt"

Two options, just do it on compiler time

const char FileName[] = "19910401.txt";  ///dt is just a terrible name ;)

Or at runtime

unsigned long date = 19910401; //does not fit in an (unsigned) int ;)

char fileName[13]; //8 char for the date + 4 (".txt") + 1 for null termination

sprintf(fileName, "%08lu.txt", date);

ShadowfireOmega:
but cannot find documentation on it and I do not understand how it works.

Then you're terrible at searching :wink:

This number won't fit in a 16 bit int:

int dt = 19910401;

For some ideas:

//create a new file and open for write. return true if successful, else false.
bool openFile(void)
{
    char filename[] = "LOGnnn.TXT";

    for (int i = 1; i < 1000; i++) {
        filename[3] = i / 100 + '0';
        filename[4] = ( i / 10 ) % 10 + '0';
        filename[5] = i % 10 + '0';
        if (logFile.open(filename, O_CREAT | O_EXCL | O_WRITE)) break;
    }
    return logFile.isOpen();

Two options, just do it on compiler time
const char FileName[] = "19910401.txt";  ///dt is just a terrible name ;)

Will this work with a dynamic variable, or is it just for the specific example of 19910401? (dt wasn't supposed to be the name, just the variable to be called, dt was short for date/time when I had a time latched on the end)

Or at runtime

unsigned long date = 19910401; //does not fit in an (unsigned) int ;)

char fileName[13]; //8 char for the date + 4 (".txt") + 1 for null termination

sprintf(fileName, "%08lu.txt", date);

I follow this up until the "%08lu" portion, how does this work?

Then you're terrible at searching :wink:

Ah, I had been restricting my searches to this site, I'll keep in mind to search the base language itself in the future.

Ok, I think I understand the %08lu portion now, after checking the printf() function referenced in the sprintf() function page. It specifies 8 characters minimum as an unsigned long int, then calls upon the date variable to fill it, yes?

So how to I call this variable with the SD.open function?

Nevermind, I feel stupid now. plugged fileName in and it worked. Thanks for your help y'all!

sprintf() fills fileName with the text :slight_smile: So now you just use that :slight_smile:

Yea, just figured that out and edited my post xD Thank you very much Septillion!

Remember sprintf adds lots of code to the sketch.

For the %08lu
8 specifies the minimum width
0 indicates leading zeroes, else it will be leading spaces.

Personally I find it highly preferable to use yyyyMmdd. Makes sorting files sooooooooo much easier.

larryd:
Remember sprintf adds lots of code to the sketch.

How much does it add, exactly?

odometer:
How much does it add, exactly?

Exactly, you will have to test yourself.

I compared it once and believe it was around 1500 bytes more flash for the sketch I was working on.

larryd:
Exactly, you will have to test yourself.

I compared it once and believe it was around 1500 bytes more flash for the sketch I was working on.

The way I see it, if you can afford to spare the 1500 bytes, then it is worth it to use sprintf because it makes life easier for you, the programmer, as well as for anyone trying to make sense of your code (such as yourself a few months from now).

Whatever makes you feel good then :wink:

Yes, sprintf adds quite a bit indeed. Writing a specific function for it will take a lot less. Although not extremely hard it is more complex to do right including leading zero's and handling a long. That's why I opted for sprintf() in this case.

But if you want to spend the extra time on making that function you will save quite a bit of space.

Isn't there a problem here with SD and the length of the file name being greater than 8 characters or have things moved on?

G

The earlier suggested sprintf solution adheres to the 8 dot 3 notation as long as the number is limited to 8 digits.

And is that still an issue? I can see where it comes from but I do think it's a stupid this isn't on the reference page (or am I blind...).

Under File Naming.

G

Link edited. Fat fingers.

Okay, I'm blind :smiley: But I must say, it's buried pretty deep for something so important...

PS You mangled your link :wink: