Which SD library to create file with date?

I have Adafruit datalogger shield with real-time clock.
I need create files on SD with correct file creation dates. As I understand, SD library recommended by Adafruit cannot create files with dates.
With so many SD libraries available which one I should stick to for creating a file with proper date?

Sdfat Google Code Archive - Long-term storage for Google Code Project Hosting. supports timestamps on the Adafruit Data Logging Shield.

Look at the AnalogLogger example in the SdFat/examples folder.

Set USE_DS1307 nonzero at line 7

#define USE_DS1307       1  // set nonzero to use DS1307 RTC

At line 40 change the comments like this:

//#error remove this line and uncomment the next two lines.
#include <Wire.h>
#include <RTClib.h>

Apropos of this, I had a go at using the file timestamp support in the Arduino 0022 SD library but couldn't figure it out - there are various functions in the source that suggest a current time callback is supported - is this so and if so how to use it?

The SD.h 0022 library is a wrapper for an old version of SdFat. The Arduino developers did not choose to expose timestamp callback support in their wrapper.

Here is a sketch that works with their 0022 version of SD.h. It will produce a file, TEST_SD.TXT, that will be timestamped with creation and modify time. Modify time will be maintained if you write the file.

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

File file;  // test file
const uint8_t SD_CS = 10; // SD chip select
RTC_DS1307 RTC;  // define the Real Time Clock object
//------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = RTC.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Wire.begin();
  if (!RTC.begin()) {
    Serial.println("RTC failed");
    while(1);
  };
  // set date time callback function
  SdFile::dateTimeCallback(dateTime); 

  if (!SD.begin(SD_CS)) {
    Serial.println("SD.begin failed");
    while(1);
  }
  file = SD.open("TEST_SD.TXT", FILE_WRITE);
  file.close();
  Serial.println("Done");
}
//------------------------------------------------------------------------------
void loop() {}
1 Like

Many thanks for this info!.

Lenny

fat16lib:
The SD.h 0022 library is a wrapper for an old version of SdFat. The Arduino developers did not choose to expose timestamp callback support in their wrapper.

Here is a sketch that works with their 0022 version of SD.h. It will produce a file, TEST_SD.TXT, that will be timestamped with creation and modify time. Modify time will be maintained if you write the file.

#include <SD.h>

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

File file;  // test file
const uint8_t SD_CS = 10; // SD chip select
RTC_DS1307 RTC;  // define the Real Time Clock object
//------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
 DateTime now = RTC.now();

// return date using FAT_DATE macro to format fields
 *date = FAT_DATE(now.year(), now.month(), now.day());

// return time using FAT_TIME macro to format fields
 *time = FAT_TIME(now.hour(), now.minute(), now.second());
}
//------------------------------------------------------------------------------
void setup() {
 Serial.begin(9600);
 Wire.begin();
 if (!RTC.begin()) {
   Serial.println("RTC failed");
   while(1);
 };
 // set date time callback function
 SdFile::dateTimeCallback(dateTime);

if (!SD.begin(SD_CS)) {
   Serial.println("SD.begin failed");
   while(1);
 }
 file = SD.open("TEST_SD.TXT", FILE_WRITE);
 file.close();
 Serial.println("Done");
}
//------------------------------------------------------------------------------
void loop() {}

Is this still the way to add timestamps to sd files with Arduino 1.0 or later?
Best regards
Jantje

The version of SdFat used in 1.0 and 1.01 is the same old version used in 022 and before. Only the SD.h wrapper has changed so this is still the best way.

If you had access to the SdFat API for files you could use the timestamp function to set all date/time fields on a per file basis.

bool SdBaseFile::timestamp ( uint8_t flags,
uint16_t year,
uint8_t month,
uint8_t day,
uint8_t hour,
uint8_t minute,
uint8_t second
)

Set a file's timestamps in its directory entry.

Parameters:
[in] flags Values for flags are constructed by a bitwise-inclusive OR of flags from the following list

T_ACCESS - Set the file's last access date.

T_CREATE - Set the file's creation date and time.

T_WRITE - Set the file's last write/modification date and time.

Parameters:
[in] year Valid range 1980 - 2107 inclusive.
[in] month Valid range 1 - 12 inclusive.
[in] day Valid range 1 - 31 inclusive.
[in] hour Valid range 0 - 23 inclusive.
[in] minute Valid range 0 - 59 inclusive.
[in] second Valid range 0 - 59 inclusive

Note:
It is possible to set an invalid date since there is no check for the number of days in a month.
Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().

Returns:
The value one, true, is returned for success and the value zero, false, is returned for failure.

Or copy timestamps from another file:

bool SdBaseFile::timestamp ( SdBaseFile * file )

Copy a file's timestamps

Parameters:
[in] file File to copy timestamps from.

Note:
Modify and access timestamps may be overwritten if a date time callback function has been set by dateTimeCallback().

Returns:
The value one, true, is returned for success and the value zero, false, is returned for failure.

fatlib
Thanks for the great library and quick response.
I'll try the callback first. if that doesn't satisfy my needs I'll look at using the fatlib natively.

Greetings from Belgium
Jantje

FYI - I am using an external RTC, so I do this as well (I think I must not call RTC with each timestamp request then, comes from sdfat examples):

...
void dateTime(uint16_t* date, uint16_t* time) {
   time_t t = now();
  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(year(t), month(t), day(t));  
  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(hour(t), minute(t), second(t));
}
...
  setSyncProvider(rtc.get_tm);   // the function to get the actual time from my RTC

  if(timeStatus()!= timeSet) 
     Serial.println(F("Unable to sync with the RTC"));
  else
     Serial.println(F("RTC has set the system time"));  

     setSyncInterval(1000);         // set the number of seconds between re-sync of time

     SdFile::dateTimeCallback(dateTime);
...

p.

..a question to the TIME and RTC libs, related to the timestamps as well:
http://arduino.cc/forum/index.php/topic,116661.0.html
p.

pito,

See my reply in your original post about RTC libs.

I have been using the Rogue Robotics RS-232 SD modules which don't do timestamps either. As a work-around I put year and then month sub-diectories on the SD (e.g. 12/07) before use and construct a filename for the day with its date in it (e.g. AR31.CSV). Each record has date and time fields. Most of the projects have used a dallas RTC, but i have also used a watch crystal and a CD4060 and even an actual watch (detecting the 1-sec current surge when it advances the hands). My latest does use the Adafruit logger shield, which is much cheaper, and its SD library.
John

Fatlib
It works great now. I'm using my gps module to get the time.
Greetings from Belgium
Jantje

It has been so long I am not talking about arduino. I have a project with arduino and I will expose it yet. But, one part of the project (programmes) is to have a log file in SD card named by date.

Woot! It works!

fat16lib:
The SD.h 0022 library is a wrapper for an old version of SdFat. The Arduino developers did not choose to expose timestamp callback support in their wrapper.

Here is a sketch that works with their 0022 version of SD.h. It will produce a file, TEST_SD.TXT, that will be timestamped with creation and modify time. Modify time will be maintained if you write the file.

#include <SD.h>

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

File file;  // test file
const uint8_t SD_CS = 10; // SD chip select
RTC_DS1307 RTC;  // define the Real Time Clock object
//------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = RTC.now();

// return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

// return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Wire.begin();
  if (!RTC.begin()) {
    Serial.println("RTC failed");
    while(1);
  };
  // set date time callback function
  SdFile::dateTimeCallback(dateTime);

if (!SD.begin(SD_CS)) {
    Serial.println("SD.begin failed");
    while(1);
  }
  file = SD.open("TEST_SD.TXT", FILE_WRITE);
  file.close();
  Serial.println("Done");
}
//------------------------------------------------------------------------------
void loop() {}

Still works in Arduino 1.0.6, Thanks so much!!!

// Just like the above posts
// after your rtc is set up and working you code just needs:

void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = rtc.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}

//put that outside of any functions, before your 'setup'

//Then inside your 'loop' or 'setup'

void loop(void)
{

  //Other code that does stuff

  //put this next line *Right Before* any file open line:
  SdFile::dateTimeCallback(dateTime);
  dataFile = SD.open(datafilename, FILE_WRITE);

  //other code that does stuff

}

Thanks so much!!!!!!!!!!!!!!!!!!!!!!

Amazing, thanks for this simple and clean code!!!

Arduino IDE 1.8.8 - works today too!
Thank you very much - only 4 years later i found a solution without a known problem.
Now it works fine with actual date/time on sd-card.

Sorry for digging out the body

betterthanalemur:
Still works in Arduino 1.0.6, Thanks so much!!!

// Just like the above posts

// after your rtc is set up and working you code just needs:

void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = rtc.now();

// return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

// return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}

//put that outside of any functions, before your 'setup'

//Then inside your 'loop' or 'setup'

void loop(void)
{

//Other code that does stuff

//put this next line Right Before any file open line:
  SdFile::dateTimeCallback(dateTime);
  dataFile = SD.open(datafilename, FILE_WRITE);

//other code that does stuff

}





Thanks so much!!!!!!!!!!!!!!!!!!!!!!