Naming Files Sequentially?

For the past few weeks I’ve been creating a data logger for my motorcycle. It (most of the time) records throttle, clutch, and brake position using two rotary potentiometers, and a flexiforce sensor. Some times it stops after 6 or so cycles, and sometimes it stops when the first input changes, but most of the time, it works fine. Up until now though, I’ve just been using the same file name over and over, which of course puts all the logged data in the same place. While this wasn’t a problem while debugging and wiring it all up, it has become one now that we’re ready-ish to break the tether to the computer.

The arduino will turn on when the key is turned to on, and off when the key is off. Now as a result, should I perhaps go to the store and come home, both of those logging sessions will be combined as one. Now I could probably deal with this by adding a few blank lines to the file in ‘setup’ but that’s just not elegant at all. I’d like to create a new file with each session, something like “LOG001.txt”, “LOG002.txt” and so on. So I would need the sketch to check the SD card and find the file with the highest value, and then create a new file with a name one value higher. This could of course be passed as a parameter through the rest of the sketch to keep things simple. My problem is, I have no idea where to start XD My programming experience is scheme (LISP, first and last time they taught that in an intro CSE class at my university), some C++, a little matlab, and some Arduino/Processing experience prior to this undertaking. Really all I’m looking for is for someone to point me in the right direction, so I can give it a go myself :slight_smile:


#include <SD.h>
const int chipSelect=8;
#define interval 33
unsigned long waitUntil=0;

void setup()
  pinMode(10, OUTPUT);
    waitUntil = millis() + interval;

void loop()
  while((long) (millis() - waitUntil) >= 0)
    int star = millis();
    int t = analogRead(3);
    int c = analogRead(1);
    int b = analogRead(5);
    String dataString = "";
    dataString += String(t);
    dataString += ",";
    dataString += String(c);
    dataString += ",";
    dataString += String(b);
    dataString += ",";
    File dataFile ="log.txt", FILE_WRITE);
    int en = millis();
    int dur = en-star;
    waitUntil = waitUntil + interval;

Another solution may be to keep an extra file on the SD card that has the name of the last used datafile - that way you won't end up scanning for the last file to work out which one it is. Just an idea - I haven't tried it on an Arduino.

If the Arduino powers off when you swtich off the ignition do you have plans to ensure that any data not yet written to the SD card is written before power is lost?

Use of String is somewhat hazardous at present due to a bug in the heap memory managment. You can obtain a patch to correct the problem, but may be better off not using Strings at all just use normal character strings.


Another solution may be to keep an extra file on the SD card

I have used that solution in my logger, i just have an extra file which holds a number that will be increased everytime the Arduino is started.
And to avoid using Strings I use sprintf and a character array for the file name

#include <SdFat.h>
#include <SdFatUtil.h> 
#include <ctype.h>

//Create the variables to be used by SdFat Library
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
int reading;
float tempC;
int tempPin=1;
char newfile[] = "";
const uint8_t SdChipSelect =5;
int test=10;
char name[] = "Test.txt";     //Create an array that contains the name of our file.
char numname[] = "number.txt";  
//char contents[256];           //This will be a data buffer for writing contents to the file.
char in_char=0;

  void setup(void)
      Serial.begin(9600);        //Start a serial connection.
     pinMode(5, OUTPUT);       //Pin 10 must be set as an output for the SD communication to work.
      card.init();               //Initialize the SD card and configure the I/O pins.
      volume.init(card);         //Initialize a volume on the SD card.
      root.openRoot(volume);     //Open the root directory in the volume. 
 , numname,O_READ); //Read the number
    num++;, numname,O_WRITE); //save new number
  //Create new filename and file
  sprintf(newfile, "sens%02d.txt", num);  

void loop(void){ 
reading = analogRead(tempPin);
reading = analogRead(tempPin);
tempC = reading / 9.31;
Serial.println(tempC);,newfile , O_CREAT | O_APPEND | O_WRITE); // Tested OK

file.print("temperatur, ");

    delay(2000);     //Wait 2 second before repeating the process.


Another way to do it (this also incorporates the date into the filename–yymmddnn.csv, where nn is a two-digit sequential number). This was pulled from one of the SDFatLib examples, IIRC:

#include <Time.h>

char logFile[13];
int i;

boolean createLogFile()

/* Creates /logs/ directory, if not already present, and log file
 * file name is yymmddnn.csv
 * yy = 2-digit year
 * mm = 2-digit month
 * dd = 2-digit day
 * nn = first unused number from 00-99
 * Requires system clock to be set to year >= 2000

  if (!sd.exists("/logs/"))
    if (!sd.mkdir("/logs"))
      //couldn't create logs directory
      return false;
  } // create logs directory, if not already present
  if  (!sd.chdir("/logs"))
    // error
    return false;
  time_t t = now();
  int yr = year(t) - 2000;
  yr, month(t), day(t));
  for (i = 0; i < 100; i++)
    logFile[6] = i/10 + '0';
    logFile[7] = i%10 + '0';
    if (sd.exists(logFile))
    if(,O_RDWR | O_CREAT | O_AT_END))
      //it worked
      return true;
      return false;

Obviously this isn’t a complete sketch; it’s only the function to create the logfile.

From AnalogLogger.ino example (SdFat examples), increases the “…00.CSV” by one each time the sdcard starts:

// create a new file in root, the current working directory
  char name[] = "LOGGER00.CSV";

  for (uint8_t i = 0; i < 100; i++) {
    name[6] = i/10 + '0';
    name[7] = i%10 + '0';
    if (sd.exists(name)) continue;;
  if (!logfile.is_open()) error("");
 cout << pstr("Logging to: ") << name << endl;