Please help with date in filename

Dear friends: I'm working in a temperature datalogger and need to name my files with the date . Also, I need to store data in one file per day.
I read many topics using RTC and its libraries but I don't have RTC and use NTP server to syncronize date and time.
I've tried with the daystamp.substring function but have many problems to convert the output to char.
I'm new writing code, I'm just a chemist trying to write simple code and I'm needing your help.
Many thanks in advance
regards
DL

Can you print the date from the NTP to the Serial monitor ?

Express the number of seconds since some epoch as ASCII hex.

It won't be recognised by humans, but a simple program will read it easily.

Or YYMMDD will still allow you a couple of extras characters for other id purposes.

Hi UKHeliBob, yes I can. In fact, my data file currently is named data.txt and stores the date and time fine.

Hi TheMemberFormerlyKnownAsAWOL, thank you.
YYMMDD would be fine but I don't know how to translate it to a filename.
Could you please help me?
Thank you
DL

For example, this is part of my code. I know that code has faults, but it's what I tried to do

 // Function to get date and time from NTPClient
void getTimeStamp() {
  while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
  // The formattedDate comes with the following format:
  // 2018-05-28T16:00:13Z
  // We need to extract date and time
  formattedDate = timeClient.getFormattedDate();
  Serial.println(formattedDate);

  // Extract date
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
  Serial.println(dayStamp);
  // Extract time
  timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
  Serial.println(timeStamp);
//-----------aca inserto en 2.1
// establish the file name with timestamp and extension
  char fname[] = "DL";
  String theyear = dayStamp.substring(0, 4);
  String themonth = dayStamp.substring(5, 7);
  String theday = dayStamp.substring(9, 11);
  char fext[] = ".csv";

//Convert string to integer and assign date to variables theyear, themonth, theday
  yearval = theyear.toInt();
  monthval = themonth.toInt();
  dayval = theday.toInt();

  // convert integer to char
  yearvaltxt = yearval + '0';
  monthvaltxt = monthval + '0';
  dayvaltxt = dayval + '0';
  
  strcat(filename, fname);
  strcat(filename, yearvaltxt);
  strcat(filename, monthvaltxt);
  strcat(filename, dayvaltxt);  
  strcat(filename, fext);
  Serial.println(filename);

Does the object timeClient also have methods for extracting the year, month and day. For example, timeClient.getYear ? If so, it would be much easier.

char filename[] = "00000000.CSV";   // in preamble
.
.
.
   GetClock();    // in loop
  if (today != day)
  {
   today = day;
   getFileName(); 
  }
.
.
.

void getFileName(){
sprintf(filename, "%02d%02d%02d.csv", year, month, day);
}

The above presupposes you have the variables year,month, day, derived by whatever means and here you access them at midnight. It should not matter that you use NTP.

Dear Nick: I’ll try this. Many thanks for your help
Regards
DL

Hi again, Nick.
Now my error msg says

'GetClock' was not declared in this scope

What must I do?
Thank you again
regards
DL

Hi friend. In the code I uploaded, it can. But I obtain a string, and need a cons or char (I don't know exactely) to work with it as filename.
Regards
DL

Or go full Japanese with: YYYYMMDD
Why?
It is a date format that sorted correctly!
or if you need more precision: YYYYMMDDHHMMSS
YMMV

Sorry for being so cryptic. Getclock is simply the subroutine that I use for getting the time - from an RTC. You should have your own srtn to get time from NTP. The point is that you need the variables to create the file name, and to know when to create it. Then, the one-line subroutine
getFileName()
should be all you need. I think you are making this far more difficult than it should be.

YYMMDD will still sort correctly for some time to come.

Can we see all your code including the #include statements which are usually near the top.
The definition of timeClient would be interesting because there are [probably] better ways of extracting the day, month and year data that your alternative method of attempting to sift these out of a character string.

Hi 6v6gt, many thanks for your help.
Of course I can upload my code. I'll share the "clean" version, without any try to name the files with date. The filename here is fixed.

// Libraries to get time from NTP Server
#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

// Libraries for SD card
#include "FS.h"
#include "SD.h"
#include <SPI.h>

//DS18B20 libraries
#include <AsyncMqttClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

extern "C" {
  #include "freertos/FreeRTOS.h"
  #include "freertos/timers.h"
}


#define WIFI_SSID "XXXXXXXX"
#define WIFI_PASSWORD "XXXXXX"

// For a cloud MQTT broker, type the domain name
#define MQTT_HOST IPAddress(192, 168, 1, 2)


#define MQTT_PORT 1883

// Temperature MQTT Topic
#define MQTT_PUB_TEMP "esp32/ds18b20/temperature"

// Save reading number on RTC memory
RTC_DATA_ATTR int readingID = 0;

String dataMessage;

// GPIO where the DS18B20 is connected to
const int oneWireBus = 22;          
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);
// Temperature value
float temp;

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

// Variables to save date and time
String formattedDate;
String dayStamp;
String timeStamp;

AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;

unsigned long previousMillis = 0;   // Stores last time temperature was published
const long interval = 60000;        // Interval at which to publish sensor readings

void connectToWifi() {
  Serial.println("Connecting to Wi-Fi...");
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}

void connectToMqtt() {
  Serial.println("Connecting to MQTT...");
  mqttClient.connect();
}

void WiFiEvent(WiFiEvent_t event) {
  Serial.printf("[WiFi-event] event: %d\n", event);
  switch(event) {
    case SYSTEM_EVENT_STA_GOT_IP:
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
      connectToMqtt();
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      Serial.println("WiFi lost connection");
      xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
      xTimerStart(wifiReconnectTimer, 0);
      break;
  }
}

void onMqttConnect(bool sessionPresent) {
  Serial.println("Connected to MQTT.");
  Serial.print("Session present: ");
  Serial.println(sessionPresent);
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  Serial.println("Disconnected from MQTT.");
  if (WiFi.isConnected()) {
    xTimerStart(mqttReconnectTimer, 0);
  }
}

/*void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
  Serial.println("Subscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
  Serial.print("  qos: ");
  Serial.println(qos);
}
void onMqttUnsubscribe(uint16_t packetId) {
  Serial.println("Unsubscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}*/

void onMqttPublish(uint16_t packetId) {
  Serial.println("Publish acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(fs, file.name(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}


// Function to get temperature
void getReadings(){
  sensors.requestTemperatures(); 
  temp = sensors.getTempCByIndex(0); // Temperature in Celsius
  //temperature = sensors.getTempFByIndex(0); // Temperature in Fahrenheit
  Serial.print("Temperature: ");
  Serial.println(temp);
}

void setup() {
  // Start the DS18B20 sensor
  sensors.begin();
  
  Serial.begin(115200);
  Serial.println();
  Serial.println();

  mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
  wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));

  WiFi.onEvent(WiFiEvent);

  mqttClient.onConnect(onMqttConnect);
  mqttClient.onDisconnect(onMqttDisconnect);
  //mqttClient.onSubscribe(onMqttSubscribe);
  //mqttClient.onUnsubscribe(onMqttUnsubscribe);
  mqttClient.onPublish(onMqttPublish);
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);
  // If your broker requires authentication (username and password), set them below
  //mqttClient.setCredentials("REPlACE_WITH_YOUR_USER", "REPLACE_WITH_YOUR_PASSWORD");
  connectToWifi();

// Initialize a NTPClient to get time
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(-10800);

 // Initialize SD card
  SD.begin();  
  if(!SD.begin()) {
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();
  if(cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }
  Serial.println("Initializing SD card...");
  if (!SD.begin()) {
    Serial.println("ERROR - SD card initialization failed!");
    return;    // init failed
  }

  // If the temp1.txt file doesn't exist
  // Create a file on the SD card and write the data labels
  File file = SD.open("/temp1.txt");
  if(!file) {
    Serial.println("File doens't exist");
    Serial.println("Creating file...");
    writeFile(SD, "/temp1.txt", "Reading ID, Date, Hour, Temp (ºC) \r\n");
  }
  else {
    Serial.println("File already exists");  
  }
  file.close();

//  getReadings();
//  getTimeStamp();
//  logSDCard();
  
  // Increment readingID on every new reading
//  readingID++;
  


}

void loop() {
  unsigned long currentMillis = millis();
  // Every X number of seconds (interval = 60 seconds) 
  // it publishes a new MQTT message
  if (currentMillis - previousMillis >= interval) {
    // Save the last time a new reading was published
    previousMillis = currentMillis;
    // New temperature readings
    sensors.requestTemperatures(); 
    // Temperature in Celsius degrees
    temp = sensors.getTempCByIndex(0);
    // Temperature in Fahrenheit degrees
    //temp = sensors.getTempFByIndex(0);}
    
    // Publish an MQTT message on topic esp32/ds18b20/temperature
    uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temp).c_str());                            
    Serial.printf("Publishing on topic %s at QoS 1, packetId: ", MQTT_PUB_TEMP);
    Serial.println(packetIdPub1);
    Serial.printf("Message: %.2f /n", sensors.getTempCByIndex(0));
  
  getReadings();
  getTimeStamp();
  logSDCard();
  
  // Increment readingID on every new reading
  readingID++;
  }
}
  // Function to get date and time from NTPClient
void getTimeStamp() {
  while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
  // The formattedDate comes with the following format:
  // 2018-05-28T16:00:13Z
  // We need to extract date and time
  formattedDate = timeClient.getFormattedDate();
  Serial.println(formattedDate);

  // Extract date
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
  Serial.println(dayStamp);
  // Extract time
  timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
  Serial.println(timeStamp);
}

// Write the sensor readings on the SD card
void logSDCard() {
  dataMessage = String(readingID) + "," + String(dayStamp) + "," + String(timeStamp) + "," + 
                String(temp) + "\r\n";
  Serial.print("Save data: ");
  Serial.println(dataMessage);
  appendFile(SD, "/temp1.txt", dataMessage.c_str());
}

// Write to the SD card (DON'T MODIFY THIS FUNCTION)
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();
}

// Append data to the SD card (DON'T MODIFY THIS FUNCTION)
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();
}

I would like my data filename to be 210801-1.txt instead of temp1.txt.
Many thanks for your help.
Regards
DL

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