Hardware button & Folder creation on SD card

Hello,

I am totally novice with Arduino programming. I am trying to save GPS data on SD card with an Aduino Mega board. I would like implement it in a motorcycle and be able to launch simulation from a hardware button. Let me explain my self, a first initialization creates a folder with the date “TestJJMMYYY”. Then when rider will have decided to launch simulation, he will press the button, a sub folder “Scenario1” will be created and all acquired data will be saved into this subfolder until the button will be pressed a second time. The same scheme will repeat if the rider presses a third time a subfolder “scenario2” will be created…
I have some difficulties to understand how to proceed to create folder with a button and save data. Maybe someone can lead me to the right direction.

Thank you in advance,
Pm

I have some difficulties to understand how to proceed to create folder with a button

You need to first connect the switch properly. How have you connected the switch?

Then, you need to determine when the switch BECOMES pressed (NOT is pressed). The state change detection example explains how.

Next, you need to understand that the Arduino will start over again every time it is reset, initializing all values to the defaults, again.

Will this be a problem? Do you plan to start the motorcycle only once a day? Will starting it reset the Arduino?

Creating the date folder when the press count is 0 is easy. Creating the ScenarioN folder/file when the press count is N is not hard.

If you are using the SD library, keep in mind the 8.3 file name limitation when making up names.

Hello,

Thank you very much for your help.
I change a little bit the problem I have used a switch button instead of a press button.
I try a code which almost works. I say almost because I have a little problem with the SD.open() function into the conditionnal structure.

The code is the following:

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

const int  Button_Pin = 2;      // the pin that the pushbutton is attached to
const int Led_Pin = 13;         // the pin that the LED is attached to
const int Chip_Select = 53;     // CS pin for SD card breakout

int Button_Switch_Counter = 0;  // counter for the number of button switches
int Button_State = LOW;         // current state of the button
int Last_Button_State = HIGH;   // previous state of the button
int Loop_Index=0;               // number of void loop since the last Button_State change
int Loop_Index_Max=100;         // Max number of void loop without change Button_State to avoid bouncing
char filename;
File dataFile;

//------------------------------------------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------------------- VOID SETUP() -----------------------------------------------------------------------//
//------------------------------------------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------------------------------------------------------------------------------------------------//
void setup() {
  Serial.begin(9600);                         // initialize serial communication
  
  pinMode(Button_Pin, INPUT);                 // initialize the button pin as a input
  pinMode(Led_Pin, OUTPUT);                   // initialize the LED as an output
  
  Serial.println("Initializing SD card...");    // initialize the LED as an output
  if (!SD.begin(Chip_Select)) {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("card initialized.");

}


//------------------------------------------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------------------- VOID LOOP() ------------------------------------------------------------------------//
//------------------------------------------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------------------------------------------------------------------------------------------------//
void loop() {

  Button_State = digitalRead(Button_Pin);   // read the pushbutton input pin


  if (Button_State == LOW && Loop_Index > Loop_Index_Max ) {   // false case for the button
    if (Last_Button_State== HIGH) {
       Serial.println("Off");
       Last_Button_State=LOW;                     // change of the state of the Last_Button_State boolean
       Loop_Index=0;                              // start loop index to avoid properly boucing without delay the loop   
      }
  }

  
  if (Button_State == HIGH && Loop_Index > Loop_Index_Max ) {   // True case for the button
    if (Last_Button_State== LOW) {
       Button_Switch_Counter++;
       Serial.println("On");
       Last_Button_State=HIGH;
       Loop_Index=0;

      // NEW FILE CREATION //
      String  File_Name= "Test";
      File_Name.concat(Button_Switch_Counter);
      File_Name.concat(".txt");
      char filename[File_Name.length()+1];
      File_Name.toCharArray(filename, sizeof(filename));    // conversion of File_Name to a valid string
      }
      
      // DATA RECORDING //
      File dataFile = SD.open(filename, FILE_WRITE);
      dataFile.println("Hello World!");
      dataFile.close();
      Serial.println(filename);
      Serial.println("saved!");
    }
    
Loop_Index++; // Avoid bouncing
}

And the error is:

C:\Users\PM Damon\Desktop\StateChangeDetection4\StateChangeDetection4.ino: In function 'void loop()':

C:\Users\PM Damon\Desktop\StateChangeDetection4\StateChangeDetection4.ino:73:51: warning: invalid conversion from 'char' to 'const char*' [-fpermissive]

       File dataFile = SD.open(filename, FILE_WRITE);

                                                   ^

In file included from C:\Users\PM Damon\Desktop\StateChangeDetection4\StateChangeDetection4.ino:3:0:

C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:75:8: note: initializing argument 1 of 'SDLib::File SDLib::SDClass::open(const char*, uint8_t)'

   File open(const char *filename, uint8_t mode = FILE_READ);

The problem is that if I put the code:

      File dataFile = SD.open(filename, FILE_WRITE);
      dataFile.println("Hello World!");
      dataFile.close();
      Serial.println(filename);
      Serial.println("saved!");

in the same if structure than the FILE CREATION it works but the code is executed only one time and I need to save data every loop until switch button will became false.

What do you think about the global syntax of the code? Is there Anything to improve?

Thank you,
Pm

int Button_State = LOW;         // current state of the button
int Last_Button_State = HIGH;   // previous state of the button

I have a quirk where I like to see related variables have the same length names. It seems more logical to me to compare currButtonState to prevButtonState. I hate _ in names. I do not like variable names starting with capital letters.

And the error is:

Here’s a hint. Error is NOT spelled w, a, r, n, i, n, g.

  Button_State = digitalRead(Button_Pin);   // read the pushbutton input pin


  if (Button_State == LOW && Loop_Index > Loop_Index_Max ) {   // false case for the button

I prefer to see the statement that tests the variable on the very next line, not 3 lines later.

White space is good, in reasonable quantities, in the right place.

The values of loopIndex and loopIndexMax have NOTHING to do with the state of the switch. Do not try to make an if statement do too much.

The comment is useless and wrong.

  if (Button_State == LOW && Loop_Index > Loop_Index_Max ) {   // false case for the button
    if (Last_Button_State== HIGH) {

If the state of the pin IS low, how can it possibly be high one line later?

Look at the state change detection example, again if needed. That is NOT how the example determines that the state had changed.

      String  File_Name= "Test";
      File_Name.concat(Button_Switch_Counter);
      File_Name.concat(".txt");

Wasting resources using the String class is unnecessary. sprintf() can do the same thing, using less code space and memory. itoa() and strcat() can be used to use even less code space.

Loop_Index++; // Avoid bouncing

That is NOT what that code does.

I need to save data every loop until switch button will became false.

Switches are not true or false, so this statement doesn’t make sense.

There are several ways to open a file for write. Some append, some truncate. You need to make sure you are opening the file for append. You also need to explain whether the file is simply not opened on the next pass, or what the problem is, for those of us who are not sitting in the room with you.