Arduino won't create new file in SD card when the filename change depends on date

Hello guys, i think i need your help, i already work on my project around 3 weeks i guess.
My Arduino project this time is to make a turnstile door access system. Maybe if you look at my program as a whole it will look messy, but what I want to pay attention to is in the sections :

void createNewAccess () {
  DateTime now = rtc.now();
  char newday1 [15];
  sprintf(newday1, "%02d/%02d/%04d.csv", now.day(), now.month(), now.year());
  String newday = String(newday1);
  if (!SD.exists(newday1)) {
    Serial.println("Error 1");
    dataFile = SD.open(newday1, FILE_WRITE);
    Serial.println("Error 2");
    if (dataFile) {
      dataFile.println("Tag, Waktu Akses");
      dataFile.close();
      Serial.print("New access log file created : ");
      Serial.println(newday);
    }
    else {
      Serial.println("Error membuat data akses baru");
      Serial.println(newday);
    }
  }
}

My Arduino doesn't create new files no matter what, and I don't think there's anything wrong with my program code. And if you need the entire program code, here is the program code:

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

RTC_DS3231 rtc;
const int chipSelectSD = 53;  // Chip Select pin untuk modul SD
const int relayPin = 5;       // Relay Kontrol Solenoid 1
const int relayPin2 = 6;      // Relay Kontrol Solenoid 2
bool relayIsActive = false;  
bool relay2IsActive = false;

void setup() {
  // Mulai komunikasi serial dengan komputer
  Serial.begin(9600);
  Wire.begin();
  rtc.begin();
  // Mulai komunikasi serial dengan RDM6300 pada baud rate 9600
  Serial1.begin(9600);
  // Konfigurasi pin relay sebagai output dan matikan relay
  Serial2.begin(9600);
  pinMode(relayPin, OUTPUT);
  pinMode(relayPin2, OUTPUT);
  digitalWrite(relayPin, HIGH);
  digitalWrite(relayPin2, HIGH);

  // Inisialisasi kartu SD
  if (!SD.begin(chipSelectSD)) {
    Serial.println("Initialization of SD card failed!");
    while (1); // Hentikan program jika kartu SD gagal diinisialisasi
  }
  if (!rtc.begin()) {
    Serial.println("Initialization of RTC failed!");
    while (1);
  }
  Serial.println("SD card initialized.");
  Serial.println("Place RFID tag near the RDM6300...");
}

unsigned long lastTagReadTime = 0;
unsigned long lastTagReadTime2 = 0;
const unsigned long tagDebounceTime = 1500; // Jendela waktu untuk mengabaikan pembacaan berulang
String lastProcessedTag = ""; // Menyimpan tag terakhir serial 1 yang diproses
String lastProcessedTag2 = "";// Menyimpan tag terakhir serial 2 yang diproses
bool isReadingActive = true;
bool isReading2Active = true;
unsigned long lastActivationTime = 0;
unsigned long lastActivationTime2 = 0;
const unsigned long activationInterval = 1500; // Interval antara setiap aktivasi relay dalam milidetik (misalnya 3 detik)
String waktuSkrg = "";
int lastDay = -1;
File dataFile;

void loop() {
  int currentDay = rtc.now().day();
  if (currentDay != lastDay) {
    lastDay = currentDay;
    createNewAccess(); // Buat File Log Akses Baru
  }
if (Serial.available() > 0) {
    String input = Serial.readStringUntil('\n');
    if (input.startsWith("WAKTU")){
      DateTime now = rtc.now();
      char waktu[20];
      sprintf(waktu, "%02d.%02d, %02d/%02d/%04d", now.hour(), now.minute(), now.day(), now.month(), now.year());
      waktuSkrg = String(waktu);
      Serial.println("WAKTU :");
      Serial.println(waktuSkrg);
    }
    // Lakukan parsing perintah untuk mengatur waktu RTC
    if (input.startsWith("SETWAKTU : ")) {
      // Lakukan parsing waktu dari input
      String waktuStr = input.substring(11); // Hilangkan bagian "SETWAKTU : "

      // Lakukan parsing jam dan menit
    int pos = waktuStr.indexOf(':');
    String jamStr = waktuStr.substring(0, pos);
    String menitStr = waktuStr.substring(pos + 1, waktuStr.indexOf(',')); // Ganti '.' menjadi ',' sesuai input

    // Lakukan parsing tanggal dan bulan
    waktuStr = waktuStr.substring(waktuStr.indexOf(',') + 2); // Hilangkan koma dan spasi
    pos = waktuStr.indexOf('/');
    String tanggalStr = waktuStr.substring(0, pos);
    String bulanStr = waktuStr.substring(pos + 1, waktuStr.indexOf('/', pos + 1));

    // Lakukan parsing tahun
    waktuStr = waktuStr.substring(waktuStr.indexOf('/') + 1); // Hilangkan garis miring dan spasi
    pos = waktuStr.indexOf(',');
    String tahunStr = waktuStr.substring(waktuStr.lastIndexOf('/') + 1); // Ambil tahun dari posisi terakhir '/' sampai akhir string

    // Lakukan pengaturan waktu RTC
    int jam = jamStr.toInt();
    int menit = menitStr.toInt();
    int tanggal = tanggalStr.toInt();
    int bulan = bulanStr.toInt();
    int tahun = tahunStr.toInt();
    
      // Lakukan pengaturan waktu RTC
      // Misalnya, jika menggunakan library RTC dari DS3231:
      // rtc.adjust(DateTime(tahun, bulan, tanggal, jam, menit, 0));
      rtc.adjust(DateTime(tahun, bulan, tanggal, jam, menit, 0));
      DateTime now = rtc.now();
      String menitFormatted = (menit < 10) ? "0" + String(menit) : String(menit); // Tambahkan nol di depan jika menit kurang dari 10
      waktuSkrg = String(now.hour()) + "." + menitFormatted + ", " + String(now.day()) + "/" + String(now.month()) + "/" + String(now.year());

      // Tampilkan waktu di Serial Monitor
      Serial.print("Waktu RTC: ");
      Serial.println(waktuSkrg);
    }
  }

  if (Serial1.available() > 0 && millis() - lastTagReadTime > tagDebounceTime && !relayIsActive && isReadingActive) {
    String tag = readRFIDTag();
    if (tag.length() > 0 && tag != lastProcessedTag) {
      Serial.print("RFID Tag: ");
      Serial.println(tag);
      lastTagReadTime = millis(); // Perbarui waktu pembacaan tag terakhir
      lastProcessedTag = tag; // Perbarui tag terakhir yang diproses

      if (checkAccess(tag)) {
        Serial.println("Access Granted");
        relayIsActive = true;
        logAccess(tag); // Menandakan bahwa relay sedang aktif
        digitalWrite(relayPin, LOW);  // Aktifkan relay (asumsi relay aktif rendah)
        lastActivationTime = millis();
        tag="";
        isReadingActive = true;
        resetRFIDReader() ;
      } else {
        lastProcessedTag="";
        tag="";
        Serial.println ("Access Denied");
        isReadingActive = true;
        resetRFIDReader() ;
      }
    } else {
      lastProcessedTag="";
      isReadingActive = true;
      resetRFIDReader() ;
    }
  }
  if (relayIsActive && millis() - lastActivationTime >= activationInterval) {
    digitalWrite(relayPin, HIGH); // Non-Aktifkan relay
    relayIsActive = false;
  }
  if (Serial2.available() > 0 && millis() - lastTagReadTime2 > tagDebounceTime && !relay2IsActive && isReading2Active) {
    String tag2 = readRFIDTag2();
    if (tag2.length() > 0 && tag2 != lastProcessedTag2) {
      Serial.print("RFID Tag: ");
      Serial.println(tag2);
      lastTagReadTime2 = millis(); // Perbarui waktu pembacaan tag terakhir
      lastProcessedTag2 = tag2; // Perbarui tag terakhir yang diproses

      if (checkAccess(tag2)) {
        Serial.println("Access 2 Granted");
        relay2IsActive = true; 
        logAccess(tag2); // Menandakan bahwa relay sedang aktif
        digitalWrite(relayPin2, LOW);  // Aktifkan relay (asumsi relay aktif rendah)
        lastActivationTime2 = millis();
        tag2="";
        isReading2Active = true;
        resetRFIDReader2() ;
      } else {
        lastProcessedTag2="";
        tag2="";
        Serial.println ("Access Denied");
        isReading2Active = true;
        resetRFIDReader2() ;
      }
    } else {
      lastProcessedTag2="";
      isReading2Active = true;
      resetRFIDReader2() ;
    }
  }
      // Periksa apakah relay aktif dan sudah melewati interval waktu
  if (relay2IsActive && millis() - lastActivationTime2 >= activationInterval) {
    digitalWrite(relayPin2, HIGH); // Non-Aktifkan relay
    relay2IsActive = false;
  }
}

void createNewAccess () {
  DateTime now = rtc.now();
  char newday1 [15];
  sprintf(newday1, "%02d/%02d/%04d.csv", now.day(), now.month(), now.year());
  String newday = String(newday1);
  if (!SD.exists(newday1)) {
    Serial.println("Error 1");
    dataFile = SD.open(newday1, FILE_WRITE);
    Serial.println("Error 2");
    if (dataFile) {
      dataFile.println("Tag, Waktu Akses");
      dataFile.close();
      Serial.print("New access log file created : ");
      Serial.println(newday);
    }
    else {
      Serial.println("Error membuat data akses baru");
      Serial.println(newday);
    }
  }
}

void logAccess(String tag) {
  // Dapatkan timestamp saat ini dari RTC
  DateTime now = rtc.now();
  // Dapatkan format nama file sesuai dengan tanggal (akses_dd-mm-yyyy.csv)
  String filename = "akses_" + String(now.day()) + "_" + String(now.month()) + "_" + String(now.year()) + ".csv";

  // Buka file dengan nama yang sesuai
  dataFile = SD.open(filename, FILE_WRITE);
  if (dataFile) {
    // Format penyimpanan timestamp menjadi string
    char waktu[20];
    sprintf(waktu, "%02d.%02d, %02d/%02d/%04d", now.hour(), now.minute(), now.day(), now.month(), now.year());
    String timestamp =  String(waktu);

    // Tulis data akses ke file CSV berdasarkan tag
    dataFile.println(tag + "," + timestamp);
    dataFile.close();
  }
  else {
    Serial.println("file tidak ada");
  }

}

String readRFIDTag() {
  String tag = "";
  char ch;
  unsigned long startTime = millis();
  while (millis() - startTime < 500) {
    if (Serial1.available() > 0) {
      if (tag.length() <= 11){
      ch = Serial1.read();
      if (ch == 2 || ch == 3) continue; // Abaikan karakter STX dan ETX
      if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
        tag += ch;
      } else if (ch == '\n') {
        break; 
      }// Jika menemukan newline, hentikan pembacaan
      }
    }
  }
  isReadingActive = false;
  return tag; // Langsung kembalikan tag tanpa memotongnya menjadi panjang tertentu
}

String readRFIDTag2() {
  String tag2 = "";
  char ch;
  unsigned long startTime = millis();
  while (millis() - startTime < 500) {
    if (Serial2.available() > 0) {
      if (tag2.length() <= 11){
      ch = Serial2.read();
      if (ch == 2 || ch == 3) continue; // Abaikan karakter STX dan ETX
      if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
        tag2 += ch;
      } else if (ch == '\n') {
        break; 
      }// Jika menemukan newline, hentikan pembacaan
      }
    }
  }
  isReading2Active = false;
  return tag2; // Langsung kembalikan tag tanpa memotongnya menjadi panjang tertentu
}

bool checkAccess(String tag) {
  File dataFile = SD.open("database.csv", FILE_READ);
  if (dataFile) {
    String headerLine = dataFile.readStringUntil('\n'); // Baca dan abaikan header
    bool accessGranted = false;
    while (dataFile.available()) {
      String storedTag = dataFile.readStringUntil('\n');
      storedTag.trim();
      if (storedTag.equalsIgnoreCase(tag)) {
        dataFile.close();
        accessGranted = true;
        break;
      }
    }
    dataFile.close();
    return accessGranted;
  } else {
    Serial.println("Failed to open database.csv");
  }
  return false;
}

void resetRFIDReader() {
    while (Serial1.available() > 0) { // Bersihkan semua data yang tersisa di buffer
        Serial1.read();
    }
}

void resetRFIDReader2() {
  while (Serial2.available() > 0) {
    Serial2.read();
  }
}

According to above, your new filename for today should be

19/02/2024.csv

where '/' means going to next level of the folder structure.
Is it what you want?

Do you really meant to create a lot of files with the same name 2024.csv in many of enclosed directories?

yes sir, i use '/' this so the .csv file saved on my SD card have structure.
and also yes sir, because i don't mind it though, but if by using '/' creating problem in my code, then i already tried before without using '/' so the new filename for today would be : 19022024.csv
But still it doesn't work sir.

the symbol '/' has special meaning and is not allowed in the regular filenames.

The phrase "doesn't work" it's not very informative.
What exactly is the problem? do you get any errors when creating such a file?

Please show a full code, that you tested with 19022024.csv filename
Also a full output that you receive in Serial Monitor could help

wow, it works like what you said sir, but last time i tried it's not working properly, because at first i tried to format the file name by :

akses_dd/mm/yyy.csv
akses_dd_mm_yyyy.csv
akses_ddmmyyyy.csv
aksesddmmyyyy.csv

and nothing works so i tried to simplify it to
dd/mm/yyyy.csv
and still not working that's why i'm here but after delete '/', it's working properly, thank you very much sir :slight_smile:

Congratulations!

Please mark the thread as Solved

Just a FYI:

Filenames need to adhere to the 8.3 format; so max 8 characters before the dot and max. 3 characters after the dot.

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