ESP32 - SD card date as a file name

Hi,

I have problem to set a date as a file name in my project. I use ESP32 DEVKIT V1. Below is my code. The file name is created, but software could not create file. Message in serial monitor is “Failed to open file for writing”. Could you help me and please, tell what’s wrong in my code?

I use DS3231 RTC module.

#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include "Wire.h"
#include "RTClib.h"

int analogPin = 27;

int c = 0;

RTC_DS3231 rtc;

String path;
String patha;

void writeFile(fs::FS &fs, const char * path, const char * message) {
 Serial.printf("Writing file: %s\n", path);

 File file = fs.open(path, FILE_WRITE);
 if (!file) {
   Serial.println("Failed to open file for writing");
   return;
 }
 if (file.print(message)) {
   Serial.println("File written");
 } else {
   Serial.println("Write failed");
 }
 file.close();
}

void appendFile(fs::FS &fs, const char * , const char * message) {
 Serial.printf("Appending to file: %s\n", path);

 File file = fs.open(path, FILE_APPEND);
 if (!file) {
   Serial.println("Failed to open file for appending");
   return;
 }
 if (file.print(message)) {
   Serial.println("Message appended");
 } else {
   Serial.println("Append failed");
 }
 file.close();
}

void createFile() {
 DateTime now = rtc.now();
 patha = String(now.day(), DEC) + String(now.month(), DEC) + String(now.year(), DEC) + ".csv";
 Serial.println(patha.c_str());
 delay(500);
 writeFile(SD, patha.c_str(), "Parameter \r\n");
}

void setup() {
 Serial.begin(9600);

 if (!SD.begin()) {
   Serial.println("Card Mount Failed");
   return;
 }

 if (!rtc.begin()) {
   Serial.println("Couldn't find RTC");
   while (1);
   delay(200);
 }
 Serial.print("Starting...");
 delay(1000);

 createFile();

}

void loop() {

 String dataString = "";

 int c = analogRead(analogPin);

 dataString += String(c);
 dataString += "\r\n";

 Serial.println(dataString);
 appendFile(SD, patha.c_str(), dataString.c_str());

 delay(2000);
}

haakaahuu:
Hi,

I have problem to set a date as a file name in my project. I use ESP32 DEVKIT V1. Below is my code. The file name is created, but software could not create file. Message in serial monitor is "Failed to open file for writing". Could you help me and please

You seem to be using irregular and/or redundant commands, possibly those for the SDFat library. Check the examples in the SD section in the IDE. Also, there are a lot ot Strings in there which may cause you grief.

Some snippets

char filename[13]

void loop() {
 GetClock();
if (today != day)
{
 today = day;
 getFileName(); 
}..............

void getFileName(){
myFile.close();
sprintf(filename, "%04u%02u%02u.csv", year, month, monthDay);
myFile = SD.open(filename, FILE_WRITE);
}

new file created at midnight

Thank you a lot for your advice!!! I modified the code as per you tips. The modified code doesn't work yet. I got an error message "exit status 1 'path' was not declared in this scope" when I tried to upload the code to ESP32 board.

ESP32 has own SD library and I think that command "myFile = SD.open(filename, FILE_WRITE);" is not used with ESP32. So I used instead of it "writeFile(SD, filename, "Parameter \r\n");".

I use RTClib and it doesn't include GetClock and I will modify that part of code later, when the basic file creation will work fine.

The modified code is:

#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include "Wire.h"
#include "RTClib.h"

int analogPin = 27;

int c = 0;

RTC_DS3231 rtc;

char filename[13];

void getFileName() {
 File close();
 DateTime now = rtc.now();
 sprintf(filename, "%04u%02u%02u.csv", now.year(), now.month(), now.day());
 writeFile(SD, filename, "Parameter \r\n");
}

void writeFile(fs::FS &fs, const char * path, const char * message) {
 Serial.printf("Writing file: %s\n", path);

 File file = fs.open(path, FILE_WRITE);
 if (!file) {
   Serial.println("Failed to open file for writing");
   return;
 }
 if (file.print(message)) {
   Serial.println("File written");
 } else {
   Serial.println("Write failed");
 }
 file.close();
}

void appendFile(fs::FS &fs, const char * , const char * message) {
 Serial.printf("Appending to file: %s\n", path);

 File file = fs.open(path, FILE_APPEND);
 if (!file) {
   Serial.println("Failed to open file for appending");
   return;
 }
 if (file.print(message)) {
   Serial.println("Message appended");
 } else {
   Serial.println("Append failed");
 }
 file.close();
}

}
void setup() {
 Serial.begin(9600);

 if (!SD.begin()) {
   Serial.println("Card Mount Failed");
   return;
 }

 if (!rtc.begin()) {
   Serial.println("Couldn't find RTC");
   while (1);
   delay(200);
 }
 Serial.println("Starting...");
 delay(1000);
 getFileName();
 delay(500);

}

void loop() {

 //DateTime now = rtc.now();
 //if (today != day)
 //{
 //today = day;
 //getFileName();
 //}

 String dataString = "";

 int c = analogRead(analogPin);

 dataString += String(c);
 dataString += "\r\n";

 Serial.println(dataString);
 appendFile(SD, filename, dataString.c_str());

 delay(2000);
}

OK, I think I went off half-cocked there, and I later rather regretted replying. All I'm talking about is that you need the variables "day" and "today", which do nothing more than give you the midnight cue, and then express "date" as char. Any library method you use will give you that. I don't actually use a library at all, but simply stick with the method here

"getclock()" is simply my subroutine for getting the time, and "day" is the name of the variable that is produced therein.

I have never used my ESP32, and I was not aware that it requires a different library for SD. I think you know more about that than I do and, if you get what you expect from the various test examples, stick with it.

It seems that you have already modified my code, and I assume to good effect.

Sorry for the confusion!

You have an error in the function prototype where you left out the path

void appendFile(fs::FS &fs, const char * , const char * message) {

With this change it compiles.

void appendFile(fs::FS &fs, const char * path , const char * message) {

Hi,

After tens of attempts, I finally succeeded! Thanks to your advice! I also got ideas from other forum. Below is my code that works.

#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include "Wire.h"
#include "RTClib.h"

int analogPin = 27;

int c = 0;

RTC_DS3231 rtc;

String date1;
String filename;
String path;

void getpath() {
  path = "/" + filename;
  Serial.print("Path: ");
  Serial.println(path);
}

void getdate() {
  DateTime time = rtc.now();
  date1 = String (time.timestamp(DateTime::TIMESTAMP_DATE));
  Serial.print("Date: ");
  Serial.println(date1);
}

void getFileName() {
  File close();
  filename = date1 + ".csv";
  Serial.print("File name: ");
  Serial.println(filename);

}

void writeFile(fs::FS &fs, const char * path, const char * message) {
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if (file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

void appendFile(fs::FS &fs, const char * path , const char * message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

void setup() {
  Serial.begin(9600);
  delay(1000);
  if (!SD.begin()) {
    Serial.println("Card Mount Failed");
    return;
  }

  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
    delay(200);
  }
  getdate();
  delay(500);
  getFileName();
  delay(500);
  getpath();
  delay(500);
  writeFile(SD, path.c_str(), "Parameter \r\n");

  delay(500);
}

void loop() {

  String dataString = "";

  int c = analogRead(analogPin);

  dataString += String(c);
  dataString += "\r\n";

  Serial.println(dataString);
  appendFile(SD, path.c_str(), dataString.c_str());

  delay(2000);
}
1 Like

You are still using Strings. The ESP32 may be better at this than plain-vanilla Arduino but it still may eventually be a problem.

I tried to set the variables to chars. I got an error message "**exit status 1 **__invalid operands of types 'const char [2]' and 'char [13]' to binary 'operator+' " at row

path = "/" + filename

This might have something to do with the ESP32 libraries, and it might not be a problem anyway.

You can not concatenate two character arrays with the + operator like you use with String objects.
You can't just convert the Strings to character arrays. You also have to use the c-string functions on them like strcat.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.