Creating a new file on SD card each restart

I’m working on a project that requires I log gyroscope data to an SD card. With my current sketch, I have that ability working perfectly. However, for the application that this device is going to end up being used for, it is likely that the program will be restarted multiple times, each time recording different sets of data for different movements. Because of this, I would like to integrate the ability to create new files to log data each time the Arduino and the sketch are restarted. Can anyone shed some light on how I would go about doing this?

My current sketch is below:

// include required libraries
#include <SPI.h>
#include <SD.h>
#include <Adafruit_L3GD20.h>

// define variables for SD card
File myGyroData;
unsigned long int time;
int valuesX;
int valuesY;
int valuesZ;
const int chipSelect = 4;

// define pins for SPI communication protocal
#define GYRO_CS 4   // labeled CS
#define GYRO_DO 5   // labeled SA0
#define GYRO_DI 6   // labeled SDA
#define GYRO_CLK 7  // labeled SCL
Adafruit_L3GD20 gyro(GYRO_CS, GYRO_DO, GYRO_DI, GYRO_CLK);

// define variables for button
const int buttonPin = 2;
int buttonState = 0;

void setup()
{
  // declare pushbutton as input
  pinMode(buttonPin, INPUT);

  // set baud rate
  Serial.begin(9600);

  // initialize gyroscope
  Serial.println("Initializing gyroscope...");
  if (!gyro.begin(gyro.L3DS20_RANGE_250DPS))
  {
    Serial.println("Unable to initialize gyroscope! Please check your wiring and restart program.");
    delay(1000);
    exit(0);
    // end program if unable to initialize gyro
  }
  Serial.println("Gyroscope initiated.");

  // initialize SD card
  Serial.println("Initializing SD card...");
  pinMode(10, OUTPUT);
  // verify SD card is inserted
  if (!SD.begin(chipSelect))
  {
    Serial.println("Unable to initialize SD card! SD card failed or not inserted. Please restart program.");
    delay(1000);
    exit(0);
    // end program if unable to initialize SD card
  }
  //  SD.begin(4);
  Serial.println("SD card initialized.");
  Serial.println("Gyroscope and SD card ready.");
}

void loop()
{
  // read input from button
  buttonState = digitalRead(buttonPin);
  // run program until button is pressed
  if (buttonState == LOW)
  {
    // read gyroscope data
    gyro.read();

    // save data to SD card (note: keep the name of the csv file short; too long and it won't write >:( )
    myGyroData = SD.open("zPos1R.txt", FILE_WRITE);
    time = millis();
    valuesX = gyro.data.x;
    valuesY = gyro.data.y;
    valuesZ = gyro.data.z;

    // print to data to serial monitor and SD card if file opens correctly
    if (myGyroData)
    {
      // print gyroscope values to serial monitor
      Serial.print("X:"); Serial.print((int)gyro.data.x);   Serial.print(" ");
      Serial.print("Y:"); Serial.print((int)gyro.data.y);   Serial.print(" ");
      Serial.print("Z:"); Serial.println((int)gyro.data.z); Serial.print(" ");

      // save gyroscope data to SD card
      myGyroData.print(time);
      myGyroData.print(",");
      myGyroData.print(valuesX);
      myGyroData.print(",");
      myGyroData.print(valuesY);
      myGyroData.print(",");
      myGyroData.println(valuesZ);
    }
    myGyroData.close();
    // delay between data points for stability
    delay(500);
  }
  else
  {
    exit(0);
  }
}

For reference, I am using an Arduino Uno with the Adafruit data logging shield. The link to the shield can be found here. The gryoscope that I’m using is the Adafruit L3GD20H Triple Axis Gyro. This link to the gyro is here.

Thank you in advance for the help.

I hope that by giving you some ideas will magically give me some good karma to get my stupid SD card to initialize.

With that, remember that this is coming from a guy that is failing currently.

First it sounds like you need to create a new file on your SD card. It seems like this command would work mkdir().

The trick is that you would have to change the file name on each reset. To do this you would have to have a variable that increments up on every startup. You can store this variable in EEPROM. See this library.

https://www.arduino.cc/en/Reference/EEPROM

So start up and see where you were at using an EEPROM.read then increment that value up by and and write it back to the address. EEPROM.write

Now to make the file name using that variable. Take a string like "Data_" and concatenate it with that variable using concat().

https://www.arduino.cc/en/Reference/StringConcat

You will probably need to then concatenate on a file extension (.txt)

then use that string in mkdir(STRING)

Hope that helps some!

NickPK:

void loop()

// print gyroscope values to serial monitor
      Serial.print("X:"); Serial.print((int)gyro.data.x);  Serial.print(" ");
   
    delay(500);

Is the Serial.print implying the PC is always connected, or is it just ceremonial? If the former, you may find you can fix this with a proper PC terminal by including a timestamp. It may just depend on what you mean by "restart", but could mean you don't need the SD or millis.

Nick_Pyner:
Is the Serial.print implying the PC is always connected, or is it just ceremonial? If the former, you may find you can fix this with a proper PC terminal by including a timestamp. It may just depend on what you mean by “restart”, but could mean you don’t need the SD or millis.

For now, the serial print is included just so I can monitor the values as I develop the code. When the project is finished, I will most likely remove the serial print as the user that this project is for will not be monitoring the data via the serial monitor.

Since there is more to this project, I’ll explain a bit more to make sure everyone is on the same page. The end result of this project should be a stand-alone device that will be used to monitor peoples’ movements when the device is strapped to them. In use, the device should only be connected to a USB port for power, otherwise it will be running on its own. The SD card is necessary as once the data is recorded, the card can transfer the text file to a computer where it will be imported and operated on using a script I’ve created in MATLAB. Being that the gyro records angular velocity and I’m interested in angular position, I use MATLAB to integrate the data and then plot it to monitor changes in peoples’ position with respect to time as they move.

All that to say, the device needs to be as automated as possible as the people that will end up using it aren’t going to understand the technical stuff that makes it work and are really only interested in the plots it will be generating. Also, by restarting I mean re-executing the sketch entirely as the end use is going to require different data be logged several times, and, in my sketches current state, it appears data is just saved to the same file each time.

Hopefully that makes it more clear what I’m trying to do.

jacob84401:
I hope that by giving you some ideas will magically give me some good karma to get my stupid SD card to initialize.

With that, remember that this is coming from a guy that is failing currently.

First it sounds like you need to create a new file on your SD card. It seems like this command would work mkdir().

The trick is that you would have to change the file name on each reset. To do this you would have to have a variable that increments up on every startup. You can store this variable in EEPROM. See this library.

Arduino - EEPROM

So start up and see where you were at using an EEPROM.read then increment that value up by and and write it back to the address. EEPROM.write

Now to make the file name using that variable. Take a string like "Data_" and concatenate it with that variable using concat().

concat() - Arduino Reference

You will probably need to then concatenate on a file extension (.txt)

then use that string in mkdir(STRING)

Hope that helps some!

Thanks for the advice! I'll try implementing something like that and see if I can get the results I'm looking for.

OK

NickPK:
. The end result of this project should be a stand-alone device that will be used to monitor peoples' movements when the device is strapped to them.

OK. I use date as filename. If you are seriously interested in time, you might be better off using a realtime clock, which may thereby enable you to do something similar. I use the plain old SD library to deliver "20160620.csv" but one of the other libraries may enable you to use long filenames or, if the date is not important, you could simply use time as a filename.