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);
}
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".