datalogger trying to improve file name incrementing

I am trying to use an SD card to log data that is coming from two separate spi thermocouple chips. I have found some code to start with from this adafruit tutorial:
http://learn.adafruit.com/adafruit-data-logger-shield/using-the-real-time-clock-3
The problem I run into is getting the char for the file name passed among different functions to allow the file to close so I can use other spi devices and then open it again. Here is a piece of the code I am using from the tutorial:

#include <SPI.h>


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

// A simple data logger for the Arduino analog pins

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL 1000 // mills between entries (reduce to take more/faster data)

// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()

#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 2
#define greenLEDpin 3

// The analog pins that connect to the sensors
#define photocellPin 0 // analog 0
#define tempPin 1 // analog 1
#define BANDGAPREF 14 // special indicator that we want to measure the bandgap

#define aref_voltage 3.3 // we tie 3.3V to ARef and measure it with a multimeter!
#define bandgap_voltage 1.1 // this is not super guaranteed but its not -too- off

RTC_DS1307 RTC; // define the Real Time Clock object

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while(1);
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println();
  
  // use debugging LEDs
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
  
#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
  
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break; // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file");
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);

Any help is greatly appreciated!

The easiest solution is to make filename global, as you do with log file.

Please forgive my lack of understanding; It would seem easiest to store the dynamic portions of the char (the last two digits of the file name) as global variables and then add them in to the string that doesn't change later in the code. The problem arises that my code was written with custom libraries. Can I either pass these two digits or the entire "LOGGER00.CSV" with the updated digits amongst libraries?

Again thanks.

The issue is that filename is currently local to setup and will thus be lost when setup is over. If you make it global, you can reference it in other files using extern, or you can pass it to whatever library functions you've created that take a file name as a parameter. You can certainly do something similar just passing the varying digits, but I wouldn't bother with the extra complexity.

I am trying to make that global, but it seems my syntax and understanding of C++ is limited. Here is what I have:

char filename[] = "datalog00.csv";
Controller O2Control(StackKp, StackKi, StackKd, HeaterKp, HeaterKi, HeaterKd, StkPWM_PidKp, StkPWM_PidKi, StkPWM_PidKd, PotKp, PotKi, PotKd, filename);
File dataFile;
char *name;


void setup() {
  
  SPI.begin();

  Serial.begin(9600);
  Serial.print("Initializing SD card... - Calibrated for S/N 13061701");

  pinMode(chipSelect, OUTPUT);
  
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println(":  Card failed, or not present");
  }
  else {
  Serial.println(":  card initialized.");
  
// char filename[] = "datalog00.csv";
  for (uint8_t i = 0; i < 100; i++) {
    filename[7] = i/10 + '0';
    filename[8] = i%10 + '0';
    name1 = filename + 7;
    name2 = filename + 8;
    Serial.println(filename);
    
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
     // logfile = SD.open(filename, FILE_WRITE);
      break; // leave the loop!
    }
  }
dataFile = SD.open(filename, FILE_WRITE);
  dataFile.println("Reset - Calibrated for S/N 13061701");
  dataFile.close();
  }

and then in a library:

Controller::Controller(double SKp, double SKi, double SKd, double HKp, double HKi, double HKd, double PwKp, double PwKi, double PwKd, double PtKp, double PtKi, double PtKd, char filename) {
  _SKp = SKp;
  _SKi = SKi;
  _SKd = SKd;
  _HKp = HKp;
  _HKi = HKi;
  _HKd = HKd;
  _PwKp = PwKp;
  _PwKi = PwKi;
  _PwKd = PwKd;
  _PtKp = PtKp;
  _PtKi = PtKi;
  _PtKd = PtKd;
  _filename[] = filename;
}

void Controller::Initialize(void) {
  
  Serial.begin(9600);
  

  Serial.println("Uses Code Version T130719_0918_Basic25");
  Serial.println("header data");
  dataFile = SD.open(_filename, FILE_WRITE);

and in the library’s header file:

   char _filename[13];

it seems to have problems with the global variable. Any suggestions?

Change the definition in the constructor from char filename to char* filename

Use strcpy to get the passed content of filename into _filename.

Is _filename a class variable?

After some brutal head bashing and digging into pointers, this code worked:

char filename[] = "LOG000.CSV";

File dataFile;

void setup() {
  
  SPI.begin();

  Serial.begin(9600);

  pinMode(chipSelect, OUTPUT);
  
  // Turn the fans off
  //digitalWrite(5, LOW);
  //digitalWrite(4, HIGH);

  // initialize the SD card
  Serial.print("Initializing SD card...  ");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(53, OUTPUT);

  
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("  Card failed, or not present.");
  }
  else {
    Serial.println("  Card Initialized.");

    // create a new file

    for (int i = 0; i < 1000; i++) {
      sprintf(filename, "LOG%03d.CSV", i);
      if (! SD.exists(filename)) {
        // only open a new file if it doesn't exist
        Serial.println(filename);
        dataFile = SD.open(filename, FILE_WRITE);
        dataFile.println("Reset - Calibrated for S/N 13061701");
        dataFile.close();
        break; // leave the loop!
      }
    }
  }
  
  delay(5000);
  Control.Initialize(filename);
}

void loop() {
  Control.UpdateController();
  Control.Print(filename); 
  
  // Reset watchdog timer
  wdt_reset();
}

with this:

Controller::Controller(double SKp, double SKi, double SKd, double HKp, double HKi, double HKd, double PwKp, double PwKi, double PwKd, double PtKp, double PtKi, double PtKd) {
  _SKp = SKp;
  _SKi = SKi;
  _SKd = SKd;
  _HKp = HKp;
  _HKi = HKi;
  _HKd = HKd;
  _PwKp = PwKp;
  _PwKi = PwKi;
  _PwKd = PwKd;
  _PtKp = PtKp;
  _PtKi = PtKi;
  _PtKd = PtKd;  
}

void Controller::Initialize(char *filename) {
  
  Serial.begin(9600);

  Serial.println("Uses Code Version T130820_1346_Basic27MB");
  
  //Serial.println(filename);
  dataFile = SD.open(filename, FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println("Uses Code Version T130719_0918_Basic25");
    
    dataFile.close();
  }
  else {
    Serial.println("error opening log file - Header Line");
  }

and this:

class Controller {
  public:
    // Constructor
    
    Controller(double SKp, double SKi, double SKd, double HKp, double HKi, double HKd, double PwKp, double PwKi, double PwKd, double PtKp, double PtKi, double PtKd);
    // Initialize controller. Add this function to the Arduino Setup function.
    void Initialize(char *filename);
    // Update the controller to output the correct PWM value.
    void UpdateController(void);
    // Updates the LEDs on the face of the device
    void UpdateLEDs(void);
    // Used for printing values to the screen.  Takes as input the amount of time in
    // milliseconds the screen should wait between printing.
    void Print(char *filename);

    //Subroutine used for the Fan Tachometer
    char filename[11];  

    //int NbTopsFan;
    //int Calc;

  private:

Thanks wildbill and Matt B.!

When I see

Controller::Controller(double SKp, double SKi, double SKd, double HKp, double HKi, double HKd, double PwKp, double PwKi, double PwKd, double PtKp, double PtKi, double PtKd, char filename) {
  _SKp = SKp;

I think about the readability

you could define a

struct PID    // or PIDdefinition...
{
  double p;
  double i;
  double d;
} SK, HK, PwK, PtK;

Controller::Controller(PID SK,  PID HK,  PID PwK,  PID PtK,  char filename) 
{
  _SKp = SK.p;
  _SKi = SK.i;
   etc
   // you can also use PID datatype inside the class too of course;