SD and Filename Format

Hi

I would like to dynamically format the filename that is used to store in my SD card. However, it looks like the library doesn't allow to use a formatted String. If you check my example you will see that I get an error:

no matching function for call to 'SDClass::open(String&, int)'

Any ideas how to fix this?

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

const int chipSelect = 4;

File dataFile;

String filename = "";

void setup() {
  Serial.begin(9600);
  pinMode(SS, OUTPUT);
  if (!SD.begin(chipSelect)) {
    while (1) ;
  }

  filename += "file";
  filename += "_";
  filename += "One";
  filename += ".txt";
  Serial.println(filename);  

  //********** This works using the "datalog.txt" as filename **********
  //dataFile = SD.open("datalog.txt", FILE_WRITE);

  //********** But not when I put string filename (that has valus of "file_One.txt") **********
  dataFile = SD.open(filename, FILE_WRITE);
  if (! dataFile) {
    while (1) ;
  }
}

void loop() {
  String dataString = "";
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ","; 
    }
  }
  dataFile.println(dataString);
  dataFile.flush();
  delay(5000);
}

However, it looks like the library doesn't allow to use a formatted String

No, it doesn't. And, rightly so. So, don't use String. Use a string (NULL terminated array of char) instead. sprintf() works great.

So I guess the following is the best way to do this...
I get the RTC values of year and month, and format a char using the sprintf

#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>

//Setup the SD card
const int chipSelect = 4;
File dataFile;

//Setup the RTC
RTC_Millis rtc;
int yearNow;
int monthNow;

void setup () {
  Serial.begin(9600);
  ////////////////////////////////////////////////
  //Setup the RTC, get only year and month
  ////////////////////////////////////////////////  
  rtc.begin(DateTime(__DATE__, __TIME__));
  DateTime now = rtc.now();
  ////////////////////////////////////////////////
  
  
  ////////////////////////////////////////////////
  //Setup the SD card
  //Format the name of the file to a generic one,
  //based on the current year and month
  ////////////////////////////////////////////////  
  pinMode(SS, OUTPUT);
  if (!SD.begin(chipSelect)) {
    while (1) ;
  }
  char buffer[8];
  sprintf(buffer, "%d_%d.csv", now.year(), now.month());
  Serial.println(buffer);

  dataFile = SD.open(buffer, FILE_WRITE);
  if (!dataFile) {
    while (1) ;
  }
  ////////////////////////////////////////////////
}

void loop() {
  ////////////////////////////////////////////////
  //Add some data to the SD card
  ////////////////////////////////////////////////
  String dataString = "";
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ","; 
    }
  }
  dataFile.println(dataString);
  dataFile.flush();
  delay(5000);
}

Your buffer needs to be bigger. It should be large enough to hold a fullsized filename (8.3) plus the null at the end. Make it 16 chars just to leave a little leeway. You should also specify the field width for the year and month so that you don't get any surprises. If the year is the last two digits use "%02d_%02d.csv" - the zero will make sprintf put in a leading zero if required. e.g. September will be 09 rather than 9. If the year is 4 digitits use "%4d_%02d.csv".

Pete