Can't open file on an SD card with .open() from SDFat.

I decided to make another topic because my question from my original post was answered. The OP can be found here:

Here is my code as of right now:

// Serial data logger example.
// Maximum baud rate for a 328 Arduino is 57600.
// Maximum baud rate for a Mega Arduino is 115200.
const uint32_t BAUD_RATE = 115200;

// Maximum time between sync() calls in milliseconds.  If Serial is always
// active, you must provide a way to stop the program and close the file.
const uint32_t MAX_TXSYNC_TIME_MSEC = 1000;
const uint32_t MAX_RXSYNC_TIME_MSEC = 2000;

// Pin number for error blink LED.
// Set ERROR_LED_PIN to -1 for no error LED.
const int8_t ERROR_LED_PIN = 22;
const int8_t CHIP_SELECT = 53;  // Set to 53 cause using with a Mega

// File names to save files on the SD card
char TxFileName[11];
char RxFileName[11];

#include <SPI.h>
#include <SdFat.h>
#include <Sd2Card.h>
#include <SerialPort.h>
#include <Wire.h>
#include <RTClib.h>

#if defined(__AVR_ATmega1280__)\
|| defined(__AVR_ATmega2560__)
// Mega, use 4096 byte RX buffer
SerialPort<0, 2048, 0> NewSerial;
SerialPort<1, 2048, 0> NewSerial1;
SerialPort<2, 2048, 0> NewSerial2;
#else // Mega
// not a Mega, use 1024 RX byte buffer
SerialPort<0, 1024, 0> NewSerial;
#endif
 
SdFat sd;
SdFile logfile;

RTC_DS1307 RTC;

//------------------------------------------------------------------------------
// Error codes repeat as errno short blinks with a delay between codes.
const uint8_t ERROR_INIT   = 1;  // SD init error
const uint8_t ERROR_OPEN   = 2;  // file open error
const uint8_t ERROR_SERIAL = 3;  // serial error
const uint8_t ERROR_TXWRITE  = 4;  // SD write or sync error
const uint8_t ERROR_RTC	   = 5;  // DTC did not begin
const uint8_t ERROR_RXOPEN = 6;  // Rx File open error
const uint8_t ERROR_RXWRITE = 7; // Can't write or sync the RX file
const uint8_t ERROR_LOOP_OPEN = 8; // Cant open file in the loop

void errorBlink(uint8_t errno) {
	uint8_t i;
	while (ERROR_LED_PIN < 0);
	while (1) {
		for (i = 0; i < errno; i++) {
			digitalWrite(ERROR_LED_PIN, HIGH);
			delay(200);
			digitalWrite(ERROR_LED_PIN, LOW);
			delay(200);
			NewSerial.println(errno);
		}
		delay(1600);
	}
}

//------------------------------------------------------------------------------
void setup() {
	
	
	pinMode(ERROR_LED_PIN, OUTPUT);
	pinMode(CHIP_SELECT, OUTPUT);
	
	NewSerial.begin(BAUD_RATE);
	NewSerial1.begin(BAUD_RATE);
	NewSerial2.begin(BAUD_RATE);
	
	if (!sd.begin(CHIP_SELECT)) {
		errorBlink(ERROR_INIT);
	}

	// Create new TX file on SD card
	char TxFile[] = "GR_TX00.csv";
	for (uint8_t i = 0; i <100; i++){
		TxFile[5] = i/10 + '0';
		TxFile[6] = i%10 + '0';
		if (! sd.exists(TxFile)){
			// Only open new file if it doesn't exist
			if (!logfile.open(TxFile, O_WRITE | O_CREAT | O_AT_END)){
			errorBlink(ERROR_OPEN);}
			strncpy(TxFileName,TxFile,sizeof(TxFile));
			break;  //leave loop
		}
	}	
	
	if (logfile.fileSize() == 0) {
		// Make sure first cluster is allocated.
		logfile.write((uint8_t)0);
		logfile.rewind();
		logfile.sync();
	}
	
	// Create new RX file on SD card
	// Close the TX file first
	logfile.close();
	char RxFile[] = "GR_RX00.csv";
	for (uint8_t i = 0; i <100; i++){
		RxFile[5] = i/10 + '0';
		RxFile[6] = i%10 + '0';
		if (! sd.exists(RxFile)){
			// Only open new file if it doesn't exist
			if (!logfile.open(RxFile, O_WRITE | O_CREAT | O_AT_END)){
			errorBlink(ERROR_RXOPEN);}
			break;  //leave loop
		}
	}
	
	if (logfile.fileSize() == 0) {
		// Make sure first cluster is allocated.
		logfile.write((uint8_t)0);
		logfile.rewind();
		logfile.sync();
	}
	
	// Close the Rx file
	logfile.close();	
	
	// Connect to the RTC
	Wire.begin();
	if (!RTC.begin()){
		// Save to Tx file
		logfile.open(TxFile, O_WRITE);
		logfile.println("RTC Failed");
		logfile.close();
		errorBlink(ERROR_RTC);
		
		// Save to Rx file
		logfile.open(RxFile, O_WRITE);
		logfile.println("RTC Failed");
		logfile.close();
		errorBlink(ERROR_RTC);
	}
	
	// Get RTC time at start up
	DateTime now;
	
	// Fetch the current time
	now = RTC.now();
	// Log the time
	//logfile.print(now.secondstime()); // seconds since 2000
	//logfile.print(",");
	logfile.open(TxFile, O_WRITE);
	logfile.print(now.year(), DEC);
	logfile.print("/");
	logfile.print(now.month(), DEC);
	logfile.print("/");
	logfile.print(now.day(), DEC);
	logfile.print(" ");
	logfile.print(now.hour(), DEC);
	logfile.print(":");
	logfile.print(now.minute(), DEC);
	logfile.print(":");
	logfile.print(now.second(), DEC);
	logfile.println("");
	logfile.close();
	// Other File
	logfile.open(RxFile, O_WRITE);
	logfile.print(now.year(), DEC);
	logfile.print("/");
	logfile.print(now.month(), DEC);
	logfile.print("/");
	logfile.print(now.day(), DEC);
	logfile.print(" ");
	logfile.print(now.hour(), DEC);
	logfile.print(":");
	logfile.print(now.minute(), DEC);
	logfile.print(":");
	logfile.print(now.second(), DEC);
	logfile.println("");
	logfile.close();
	
//	 DEBUGGING: Print out to the serial port to see what is going the time is.

	NewSerial.print(now.year(), DEC);
	NewSerial.print("/");
	NewSerial.print(now.month(), DEC);
	NewSerial.print("/");
	NewSerial.print(now.day(), DEC);
	NewSerial.print(" ");
	NewSerial.print(now.hour(), DEC);
	NewSerial.print(":");
	NewSerial.print(now.minute(), DEC);
	NewSerial.print(":");
	NewSerial.print(now.second(), DEC);
	NewSerial.println("");

	
	
}


//------------------------------------------------------------------------------
// Time of last sync call.
uint32_t txSyncTime = 0;
uint32_t rxSyncTime = 0;
uint8_t buf[32];
int h = 0;

void loop() {
	
	DateTime now;
	uint8_t n=0;
	uint8_t m=0;
	
	// Get the Garmin TX traffic
	if (NewSerial1.getRxError()) {
		errorBlink(ERROR_SERIAL);
	}
	
	n = NewSerial1.read(buf, sizeof(buf));
	
	if (n > 0) { // If there is something in the buffer
		
		// Need to open the Ts file to write out the data

		if (!logfile.open(TxFileName, O_WRITE)){
			NewSerial.println(TxFileName);
		errorBlink(ERROR_LOOP_OPEN);}
		
		// Attempt to log the correct time stamp to file
		now = RTC.now();
		logfile.timestamp(T_WRITE, now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
		
		// Commented this out 3/13/14 to try to get the HEX values saved to the file.
		//if (logfile.write(buf, n) != n) {
		//errorBlink(ERROR_WRITE);
		//}
		
		for (int i=0; i<sizeof(buf); i++){
			if (buf[i]<0x10) {logfile.print("0");
			}
			logfile.print(buf[i],HEX);
			logfile.print(" ");
		}
		
		// Get the current micros time
		logfile.print(",");
		logfile.println(micros());
		
		// Don't sync if active.
		return;
	}
	if ((millis() - txSyncTime) < MAX_TXSYNC_TIME_MSEC) return;

	//if (!logfile.sync()) {
		////NewSerial.println(TxFileName);
		//NewSerial.println("can't sync to the Tx file");
		//errorBlink(ERROR_TXWRITE);
	//}
	txSyncTime = millis();

	logfile.close();

	// Log the RX side *****************************************************************
	// Get the Garmin RX traffic
	if (NewSerial2.getRxError()) {
		errorBlink(ERROR_SERIAL);
	}

	m = NewSerial2.read(buf, sizeof(buf));

	if (m > 0) { // If there is something in the buffer
		
		logfile.open(RxFileName, O_WRITE);
		// Attempt to log the correct time stamp to file
		now = RTC.now();
		logfile.timestamp(T_WRITE, now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
		
		// Commented this out 3/13/14 to try to get the HEX values saved to the file.
		//if (logfile.write(buf, n) != n) {
		//errorBlink(ERROR_WRITE);
		//}
		
		for (int i=0; i<sizeof(buf); i++){
			if (buf[i]<0x10) {logfile.print("0");
			}
			logfile.print(buf[i],HEX);
			logfile.print(" ");
		}
		
		// Get the current micros time
		logfile.print(",");
		logfile.println(micros());
		
		// Don't sync if active.
		return;
	}
	if ((millis() - rxSyncTime) < MAX_RXSYNC_TIME_MSEC) return;

	//if (!logfile.sync()) {
		//NewSerial.println("can't sync to the Rx file");
		//errorBlink(ERROR_RXWRITE);
	//}
	rxSyncTime = millis();

	logfile.close();
	h = h++;
	NewSerial.print("Times through the loop: ");
	NewSerial.println(h);
}

I keep getting an error at:

		if (!logfile.open(TxFileName, O_WRITE)){
			NewSerial.println(TxFileName);
		errorBlink(ERROR_LOOP_OPEN);}

I have checked the name of TxFileName with the print statement and it shows me the file that it should GR_TXxx.csv. What would cause this error. All the examples I have looked at access the files like this. Why won’t this work?

It may be due to the dimension of

char TxFileName[11];

This is really only room for ten characters since there must be a zero byte to terminate a string.

This string requires 12 bytes when you include the zero byte.

char TxFile[] = "GR_TX00.csv";

This will overwrite an extra byte somewhere.

strncpy(TxFileName,TxFile,sizeof(TxFile));

The same is true for RX files. This may not be the open problem but it will bite at some point.

I made this change but I still get the same error.

It looks like you can return from loop without closing logfile.

Put

 if (logfile.isOpen()) sd.errorHalt("file is open error");

just before the open that fails to check for this problem.

A far bigger problem is that you cannot get any performance if you open and close files in loop. You need a rxFile and a txFile that are opened in setup().

I don't fully understand your post. Please excuse my ignorance. I have inserted the code you supplied and I don't get that error any longer. Does that mean that the logfile was never closed at the end of setup like I thought I was?

Next, how do I access the files to write to them if I can't do that from loop. I thought I had seen examples that did exactly that but I may be mistaken. What do you mean by

A far bigger problem is that you cannot get any performance if you open and close files in loop. You need a rxFile and a txFile that are opened in setup().

Are you saying that I need to open the files in setup and just leave them open? Would having separate functions open, write and close the files outside of loop work better?
Pseudo code:
if there is something on the UART line for tx, goto the Tx function open file, record whats in the serial buffer for that UART and write to the SD card file for TX, then close file and return to loop. Then do the same for Rx? Thanks for the guidance. Sorry for being such a noob.

So I decided to try something. I wanted to see if I could just do this with a single file instead of worrying about opening and closing two separate files on one SD. I still get the same error as I was before at

		if (!logfile.open(FileName, O_WRITE)){
			NewSerial.println(FileName);
		errorBlink(ERROR_LOOP_OPEN);}

Here is the whole code:

// Serial data logger example.
// Maximum baud rate for a 328 Arduino is 57600.
// Maximum baud rate for a Mega Arduino is 115200.
const uint32_t BAUD_RATE = 115200;

// Maximum time between sync() calls in milliseconds.  If Serial is always
// active, you must provide a way to stop the program and close the file.
const uint32_t MAX_TXSYNC_TIME_MSEC = 1000;
const uint32_t MAX_RXSYNC_TIME_MSEC = 2000;

// Pin number for error blink LED.
// Set ERROR_LED_PIN to -1 for no error LED.
const int8_t ERROR_LED_PIN = 22;
const int8_t CHIP_SELECT = 53;  // Set to 53 cause using with a Mega

// File names to save files on the SD card
char FileName[11];
//char RxFileName[11];

#include <SPI.h>
#include <SdFat.h>
#include <Sd2Card.h>
#include <SerialPort.h>
#include <Wire.h>
#include <RTClib.h>

#if defined(__AVR_ATmega1280__)\
|| defined(__AVR_ATmega2560__)
// Mega, use 4096 byte RX buffer
SerialPort<0, 2048, 0> NewSerial;
SerialPort<1, 2048, 0> NewSerial1;
SerialPort<2, 2048, 0> NewSerial2;
#else // Mega
// not a Mega, use 1024 RX byte buffer
SerialPort<0, 1024, 0> NewSerial;
#endif

SdFat sd;
SdFile logfile;

RTC_DS1307 RTC;

//------------------------------------------------------------------------------
// Error codes repeat as errno short blinks with a delay between codes.
const uint8_t ERROR_INIT   = 1;  // SD init error
const uint8_t ERROR_OPEN   = 2;  // file open error
const uint8_t ERROR_SERIAL = 3;  // serial error
const uint8_t ERROR_TXWRITE  = 4;  // SD write or sync error
const uint8_t ERROR_RTC	   = 5;  // DTC did not begin
const uint8_t ERROR_RXOPEN = 6;  // Rx File open error
const uint8_t ERROR_RXWRITE = 7; // Can't write or sync the RX file
const uint8_t ERROR_LOOP_OPEN = 8; // Cant open file in the loop

void errorBlink(uint8_t errno) {
	uint8_t i;
	while (ERROR_LED_PIN < 0);
	while (1) {
		for (i = 0; i < errno; i++) {
			digitalWrite(ERROR_LED_PIN, HIGH);
			delay(200);
			digitalWrite(ERROR_LED_PIN, LOW);
			delay(200);
			NewSerial.println(errno);
		}
		delay(1600);
	}
}

//------------------------------------------------------------------------------
void setup() {
	
	
	pinMode(ERROR_LED_PIN, OUTPUT);
	pinMode(CHIP_SELECT, OUTPUT);
	
	NewSerial.begin(BAUD_RATE);
	NewSerial1.begin(BAUD_RATE);
	NewSerial2.begin(BAUD_RATE);
	
	if (!sd.begin(CHIP_SELECT)) {
		errorBlink(ERROR_INIT);
	}

	// Create new TX file on SD card
	char TxFile[] = "GAR_00.csv";
	for (uint8_t i = 0; i <100; i++){
		TxFile[4] = i/10 + '0';
		TxFile[5] = i%10 + '0';
		if (! sd.exists(TxFile)){
			// Only open new file if it doesn't exist
			if (!logfile.open(TxFile, O_WRITE | O_CREAT | O_AT_END)){
			errorBlink(ERROR_OPEN);}
			strncpy(FileName,TxFile,sizeof(TxFile));
			break;  //leave loop
		}
	}
	
	if (logfile.fileSize() == 0) {
		// Make sure first cluster is allocated.
		logfile.write((uint8_t)0);
		logfile.rewind();
		logfile.sync();
	}
// ************************************************************************************
// Commented this out to attempt to get all traffic into a single file.  RTM 04/07/14 

	
	//// Create new RX file on SD card
	//// Close the TX file first
	//logfile.close();
	//char RxFile[] = "G_RX00.csv";
	//for (uint8_t i = 0; i <100; i++){
		//RxFile[4] = i/10 + '0';
		//RxFile[5] = i%10 + '0';
		//if (! sd.exists(RxFile)){
			//// Only open new file if it doesn't exist
			//if (!logfile.open(RxFile, O_WRITE | O_CREAT | O_AT_END)){
			//errorBlink(ERROR_RXOPEN);}
			//break;  //leave loop
		//}
	//}
	//
	//if (logfile.fileSize() == 0) {
		//// Make sure first cluster is allocated.
		//logfile.write((uint8_t)0);
		//logfile.rewind();
		//logfile.sync();
	//}
	//
	//// Close the Rx file
	//logfile.close();
//***********************************************************************************************
	
	// Connect to the RTC
	Wire.begin();
	if (!RTC.begin()){
		// Save to Tx file
		//logfile.open(TxFile, O_WRITE);
		logfile.println("RTC Failed");
		//logfile.close();
		errorBlink(ERROR_RTC);
		
		//// Save to Rx file
		//logfile.open(RxFile, O_WRITE);
		//logfile.println("RTC Failed");
		//logfile.close();
		//errorBlink(ERROR_RTC);
	}
	
	// Get RTC time at start up
	DateTime now;
	
	// Fetch the current time
	now = RTC.now();
	// Log the time
	//logfile.print(now.secondstime()); // seconds since 2000
	//logfile.print(",");
	logfile.open(TxFile, O_WRITE);
	logfile.print(now.year(), DEC);
	logfile.print("/");
	logfile.print(now.month(), DEC);
	logfile.print("/");
	logfile.print(now.day(), DEC);
	logfile.print(" ");
	logfile.print(now.hour(), DEC);
	logfile.print(":");
	logfile.print(now.minute(), DEC);
	logfile.print(":");
	logfile.print(now.second(), DEC);
	logfile.println("");
	logfile.println("data,millis,direction");
	//logfile.close();
	
	//// Other File
	//logfile.open(RxFile, O_WRITE);
	//logfile.print(now.year(), DEC);
	//logfile.print("/");
	//logfile.print(now.month(), DEC);
	//logfile.print("/");
	//logfile.print(now.day(), DEC);
	//logfile.print(" ");
	//logfile.print(now.hour(), DEC);
	//logfile.print(":");
	//logfile.print(now.minute(), DEC);
	//logfile.print(":");
	//logfile.print(now.second(), DEC);
	//logfile.println("");
	//logfile.close();
	//
	//	 DEBUGGING: Print out to the serial port to see what is going the time is.

	NewSerial.print(now.year(), DEC);
	NewSerial.print("/");
	NewSerial.print(now.month(), DEC);
	NewSerial.print("/");
	NewSerial.print(now.day(), DEC);
	NewSerial.print(" ");
	NewSerial.print(now.hour(), DEC);
	NewSerial.print(":");
	NewSerial.print(now.minute(), DEC);
	NewSerial.print(":");
	NewSerial.print(now.second(), DEC);
	NewSerial.println("");	
}


//------------------------------------------------------------------------------
// Time of last sync call.
uint32_t txSyncTime = 0;
uint32_t rxSyncTime = 0;
uint8_t buf[32];
int h = 0;

void loop() {
	
	DateTime now;
	uint8_t n=0;
	uint8_t m=0;
	
	// Get the Garmin TX traffic
	if (NewSerial1.getRxError()) {
		errorBlink(ERROR_SERIAL);
	}
	
	n = NewSerial1.read(buf, sizeof(buf));
	
	if (n > 0) { // If there is something in the buffer
		
		// Need to open the Ts file to write out the data

		if (!logfile.open(FileName, O_WRITE)){
			NewSerial.println(FileName);
		errorBlink(ERROR_LOOP_OPEN);}
		
		// Attempt to log the correct time stamp to file
		now = RTC.now();
		logfile.timestamp(T_WRITE, now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
		
		// Commented this out 3/13/14 to try to get the HEX values saved to the file.
		//if (logfile.write(buf, n) != n) {
		//errorBlink(ERROR_WRITE);
		//}
		
		for (int i=0; i<sizeof(buf); i++){
			if (buf[i]<0x10) {logfile.print("0");
			}
			logfile.print(buf[i],HEX);
			logfile.print(" ");
		}
		
		// Get the current micros time
		logfile.print(",");
		logfile.print(micros());
		logfile.print(",");
		logfile.println("TX");
		
		// Don't sync if active.
		return;
	}
	if ((millis() - txSyncTime) < MAX_TXSYNC_TIME_MSEC) return;

	//if (!logfile.sync()) {
	////NewSerial.println(TxFileName);
	//NewSerial.println("can't sync to the Tx file");
	//errorBlink(ERROR_TXWRITE);
	//}
	txSyncTime = millis();

	//logfile.close();

	// Log the RX side *****************************************************************
	// Get the Garmin RX traffic
	if (NewSerial2.getRxError()) {
		errorBlink(ERROR_SERIAL);
	}

	m = NewSerial2.read(buf, sizeof(buf));

	if (m > 0) { // If there is something in the buffer
		
		//logfile.open(RxFileName, O_WRITE);
		//// Attempt to log the correct time stamp to file
		//now = RTC.now();
		//logfile.timestamp(T_WRITE, now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
		
		// Commented this out 3/13/14 to try to get the HEX values saved to the file.
		//if (logfile.write(buf, n) != n) {
		//errorBlink(ERROR_WRITE);
		//}
		
		for (int i=0; i<sizeof(buf); i++){
			if (buf[i]<0x10) {logfile.print("0");
			}
			logfile.print(buf[i],HEX);
			logfile.print(" ");
		}
		
		// Get the current micros time
		logfile.print(",");
		logfile.println(micros());
		logfile.print(",");
		logfile.println("RX");
		
		// Don't sync if active.
		return;
	}
	if ((millis() - rxSyncTime) < MAX_RXSYNC_TIME_MSEC) return;

	//if (!logfile.sync()) {
	//NewSerial.println("can't sync to the Rx file");
	//errorBlink(ERROR_RXWRITE);
	//}
	rxSyncTime = millis();

	//logfile.close();
	h = h++;
	NewSerial.print("Times through the loop: ");
	NewSerial.println(h);
}

I thought that if I create the file in setup and never close the file that I would avoid the problem. That doesn’t appear to be the case. Let me know if you see where things are getting hosed. Thanks.