I'm creating a weather station / environmental datalogger and am saving my data to a SD card Breakout. The SD card works fine but I would like to name the files I am saving on it after the date when the readings were taken.I've tryed multiple things but I can't work out how to combine the date from my RTC and put them in a file name. I've tryed this:

dataFile = SD.open(String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv",FILE_WRITE);

But this gives me an error -

char dateName[13] = {String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv"};
dataFile = SD.open(dateName,FILE_WRITE);

But this gives me this error:

 cannot convert 'StringSumHelper' to 'char' in initialization

Help! How do I do this?

  • How many problems can you detect here: "char dateName[13] = {String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv"};"? – user31481 Feb 10 at 19:13
up vote 5 down vote accepted

EDIT: As noted by Klaus Warzecha, the SD library may only support 8.3 format filenames (i.e. 8 characters for the name, 3 characters for the extension). The solution may in fact be to ensure that the years is only 2 digits, resulting in names like: 20-12-14.csv


From what I can see in the SD library code, the open() method isn't designed to accept a String object as a parameter. It only wants a plain old C-style string (which means a char array). That explains why your first example doesn't work -- it's trying to pass a String object.

The second example unfortunately is invalid C++. You simply can't initialise an array like that. What you want to do instead is to build the String object, then extract the characters out using String::toCharArray().

Something like this should work:

String filename = String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv";
char str[16] = {0};
filename.toCharArray(str, 16);
dataFile = SD.open(str, FILE_WRITE);

I'm not sure what your now.year() returns; i.e. if that's a 2 digit or 4 digit year. I've assumed 4 digits, so I've made the char array big enough for 15 characters in total, plus an extra null terminator (which is essential for C-style strings).

  • The SD card doesn't get files saved onto it when using this. – SquarePie Feb 27 '14 at 18:17
  • Can you check if it works when you write the filename manually? E.g.: dataFile = SD.open("test.csv", FILE_WRITE); – Peter Bloomfield Feb 27 '14 at 18:23
  • @SquarePie I tested the filename code just now, and it works as expected. I suspect the problem must be somewhere else in your code (or possibly the hardware). – Peter Bloomfield Feb 27 '14 at 18:51
  • @SquarePie I suggest you create a new question for this more specific SD write issue; it seems to me (but it's you to decide) that the current question has been correctly answered. – jfpoilpret Feb 27 '14 at 21:02

In your second case, you need to break the initialization into two lines and use toCharArray() as shown:

char dateName[13];
String(String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv").toCharArray(dateName, 13);

Then, you can move ahead with opening the file.

The problem you are seeing is quite literally what the error message says. An initialization of a character array requires a character array. It cannot be initialised with a string object.

  • The SD card doesn't get files saved onto it when using this. – SquarePie Feb 27 '14 at 18:16
  • @SquarePie That's odd. Maybe there is something wrong elsewhere, in the code, or in the hardware? – asheeshr Feb 28 '14 at 1:48

Is this based on the SDFat library?

Then you have to live with short 8.3 filenames for the moment.

  • It looks like this applies to the core SD library too. I hadn't noticed that. Well spotted. – Peter Bloomfield Feb 28 '14 at 8:19

//////////////////////////////////////////////////////////////

String filename = String(now.month()) + "-" + String(now.year()) + ".csv";

char str[16] = {0};

filename.toCharArray(str, 16);

File dataFile = SD.open(str, FILE_WRITE);

//////////////////////////////////////////////////////////////

  • Add some explanation to your code only solution. – gre_gor Feb 10 at 16:47

Well:

  char buffer[15];
  snprintf(buffer, sizeof(buffer), "%02d-%02d-%04d.csv", now.day(), now.month(), now.year());

After snprintf call, buffer contains the name of the file.

This solution use constant fixed space in RAM (just 15 bytes for buffer), while all others solutions demands tons of RAM for creating multiple String objects.

And it's faster, because it only do the format part, minus all creations, conversions, and deletion using String.

Finally, generated names are always the same length, from 1-1-2018 thru 31-12-2018.

Don't use String with Arduino.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.