So, maybe I'm too tired to see the obvious issue here, but my SD card script is causing a "blank" file to be created, then a secondary file to be correctly created.
I'm trying to store data logs, and I don't want to overwrite old logs, I just want to "move" them to the back of the queue. So I start with six files on the SD card:
DATA.TXT
DATA~1.TXT
DATA~2.TXT
DATA~3.TXT
DATA~4.TXT
DATA~5.TXT
Everything writes to DATA.TXT
, and DATA~1.TXT
through DATA~5.TXT
are "old" logs, from oldest to newest. This means that, the next time I boot up the Arduino, I want the contents of DATA.TXT
to be read into a new file called DATA~6.TXT
, I want the old DATA.TXT
to be deleted, and I want a new DATA.TXT
to be created for the rest of the program. It should look like this:
DATA.TXT <=== New, blank file, primed for logging new data
DATA~1.TXT
DATA~2.TXT
DATA~3.TXT
DATA~4.TXT
DATA~5.TXT
DATA~6.TXT <=== "Old" DATA.TXT
In reality, it's creating two files: instead of DATA~6.TXT
holding the contents it should, it's blank -- and a file called DATA~7.TXT
is created with the contents of the "old" DATA.TXT
. After that, it's writing to the "new" DATA.TXT
as it should. Something is lost (or added) in shifting the data, for some reason, looking like this:
DATA.TXT <=== New, blank file, primed for logging new data
DATA~1.TXT
DATA~2.TXT
DATA~3.TXT
DATA~4.TXT
DATA~5.TXT
DATA~6.TXT <=== Blank, unused "new" file?
DATA~7.TXT <=== "Old" DATA.TXT
EDIT: Each file contains test data ( e.g. - file DATA~1.TXT
contains a line like This is "DATA~1.TXT"
) So I can track which files are "moved," and where they go. That's how I know where the "old" DATA.TXT
file is going, and how I know DATA~6.TXT
is "blank." It's actually a blank file, with no data in it.
EDIT #2: As stated in the comments below, the Uno doesn't actually wait for a serial connection. I just tested this, and it is true... that being said: I'm still getting a blank DATA~6.TXT
and DATA.TXT
is being moved into DATA~7.TXT
without cause.
Now that you know the goal, and (probably) see the issue, here's the code:
/*
* Tests the SD card slot, assuring no functional code is missing
* for BIB process to correctly log data.
*
*/
#include <SPI.h>
#include <SD.h>
String fileName = "DATA.TXT"; // Declare a filename with FAT 8.3 naming conventions
File dataLog; // Store our "opened" file in an object
void setup(){
Serial.begin( 115200 );
while( !Serial ){ // Wait for serial port to open before doing anything
}
Serial.println( "\nInitializing SD card..." ); // Start SD card
if( !SD.begin( 4 ) ){
Serial.println( "Initialization failed!" );
while( 1 );
}
Serial.println( "Initialization done." );
Serial.println( "\nChecking if we have a unique filename..." );
if( SD.exists( fileName ) ) // Give our data log a unique filename if the current filename already exists
moveFiles();
dataLog = SD.open( fileName, FILE_WRITE ); // Open our file for editing if it doesn't already exist
Serial.println( "Created save file!" );
// Write to file the first time
if( dataLog ){
Serial.println( "\nWriting int test to file..." );
dataLog.println( "Testing Sequence1..." );
dataLog.println( "\tSequence1 complete." );
Serial.println( "\tFirst test written!" );
dataLog.close();
Serial.println( "\tData log closed." );
}
else
Serial.println( "---Error opening data log file!---" );
}
void loop(){
}
// Moves the last `DATA.TXT` to `DATA~x.TXT` where `x` is the largest integer.
// This makes the "highest" numbered file the last data log, and `DATA.TXT` the current data log.
// Follows SFN8.3 standards of naming, with 8 chars for filename, 4 chars for extension, and preceeding
// periods converted to `~` chars.
// This leaves us with only 999 possible "backup" data logs.
void moveFiles(){
bool sdCardFull = false; // Keep track of if our SD card is "full" or not
byte num = 1;
File newFile;
String existingFile = String( "DATA~" ) + String( num ) + String( ".TXT" ); // Creates a filename of `DATA~num.TXT` to test
// Check if this filename exists, too. Iterate `num` to avoid overwriting currently existing files
while( SD.exists( existingFile ) ){
if( num == 999 ){ // If the SD card is full
sdCardFull = true;
noMoreRoom( sdCardFull );
}
num++;
existingFile = String( "DATA~" ) + String( num ) + String( ".TXT" );
}
dataLog = SD.open( fileName );
// Create the new file, with the new filename
newFile = SD.open( existingFile, FILE_WRITE );
// Move the old data log into the new filename
while( dataLog.available() )
newFile.write( dataLog.read() );
// Close, remove, then re-open the data log
newFile.close();
dataLog.close();
SD.remove( fileName ); // Deletes the old data log
}
// We cannot find a good filename for the SFN8.3 format, since all of the available filenames have been
// used up, so we will stop the program from running until the SD card is cleaned up, before we "destroy"
// the last backup file.
void noMoreRoom( bool sdCardFull ){
/*
lcd.setCursor( 0, 0 );
lcd.print( " SD card is " );
lcd.setCursor( 0, 1 );
lcd.print( " too full!! " );
*/
Serial.println( "The SD card is full and we will not proceed until it is cleaned up." );
while( sdCardFull ){} // Do absolutely nothing until the SD card is "cleaned up"
}
while( !Serial )
loop until the Serial Monitor is attached, right?while (!Serial)
works only for MCU with native USB (32u4, SAMD), not for Uno, Nano, Mega, Mini. Uno & co. reset on new connection. they start to run and then they are reset on new connection