How do I read last write date/time from sd card with sdfat

I have included a sketch that I am trying to read the time stamp for a file and include it in the file listing. I have managed to get the file size, but no luck on getting the time stamp. I can list it to the console, but what I need is to read it so I can send it to the listing on client. The sketch included is a test sketch that lists the files fine for the root directory, but I haven’t been able to make it list the files in a sub directory. In this case the data directory.

clientListfiles_WorksForRootONLY.ino (11.9 KB)

console output.JPG

client output.JPG

I have changed my approach and am trying to modify code taken from the timestamp example in latest release of SdFat library.

Here is what I have, I have a function that lists the files to the console fine (ListFile(), but I need to get the file name,modify date/time and size into some variables that I can print with Client.print.

I am using IDE 1.6.8 and SdFat was downloaded from
GitHub - greiman/SdFat: Arduino FAT16/FAT32 exFAT Library about 2 weeks ago so I guess it is as of 19 jul 2016

I was trying to make a function ListFilesB() to print to the console and when I get that to
work I would change the Serial.print commands to Client.print. ListFilesB() isn’t coming up with a name
or modify attribute, but since I left the file.printFileSize(&Serial); in it that of course works but not for getting the size into a variable of course.

This library is giving me fits. I know it is because of my limited knowledge of library structure, but I am hoping someone can get me headed in the right direction on this.

Here is the entire sketch …I did edit out some things that I though were not relevant.

/*
 * This program tests the dateTimeCallback() function
 * and the timestamp() function.
 */
#include <DS1307new.h>
#include <SdFat.h>
#include <Wire.h>


SdFat sd;

SdFile file;

// Default SD chip select is SS pin
 const uint8_t chipSelect = 4;

// create Serial stream
ArduinoOutStream cout(Serial);
//------------------------------------------------------------------------------
// store error strings in flash to save RAM
#define error(s) sd.errorHalt(F(s))
 
void dateTime(uint16_t* date, uint16_t* time) // Fx gets called by sdfat to get the dateTime
{                                             // to write into directory
uint8_t month = 10;  uint8_t day = 1; uint16_t year = 2009;   // date 1-Oct-09
uint8_t hour = 20; uint8_t minute = 30; uint8_t second = 40;  // time 20:30:40
 
  RTC.getTime(); 
  month = RTC.month; day = RTC.day; year = RTC.year; // Note: these are all  uint8_t except year is uint16_t
  hour = RTC.hour;  minute = RTC.minute; second = RTC.second;
  *date = FAT_DATE(year,month, day); // return date using FAT_DATE macro to format fields 
  *time = FAT_TIME(hour, minute, second);   // return time using FAT_TIME macro to format fields
 // cout << F("Call Back Function, Time is  ") << int(hour) << ":" << int(minute) << ":" << int(second) << endl;
  
}  // end of dateTime 


 //  ListFilesB() my attempt to store the attributes into some variables.
//  THIS IS THE FUNCTION I'M TRYING TO MAKE WORK..   
 
void ListFilesB()
{   dir_t d;
    SdFile file;

  while (file.openNext(sd.vwd(), O_READ))
  {   for (uint8_t i = 0; i < 11; i++)
       { if(d.name[i] == ' ') continue;
         if (i == 8) { Serial.print('.'); }
         Serial.print((char)d.name[i]);
       }  
    
 //file.printName(&Serial);
    if (file.isDir()) 
     {   Serial.write('/');  // Indicate a directory
     }
 // print modifiy date/time *****************************************************  
    cout  << ("  ");
  cout << F("Modify: ");
  uint16_t lastWrtYr =  (FAT_YEAR(d.lastWriteDate));
  cout << int(lastWrtYr) << "-";
    byte testval = FAT_MONTH(d.lastWriteDate);  //cout << pstr("testval= ") << int(testval) << endl;
    if(testval < 10) { Serial.print("0");           //    Serial.print("0"); 
                     } 
       Serial.print(FAT_MONTH(d.lastWriteDate));   //client.print(str); 
       Serial.print("-");
       //Serial.print(FAT_MONTH(p.lastWriteDate)); Serial.print(", "  ); //Serial.print(str);
       testval = FAT_DAY(d.lastWriteDate);
       if(testval < 10) Serial.print("0");
       Serial.print(FAT_DAY(d.lastWriteDate)); Serial.print("    "); // client.print(str);   
       Serial.print(FAT_HOUR(d.lastWriteTime));  Serial.print(':');     // client.print(str); these were before 
       if(FAT_MINUTE(d.lastWriteTime) < 10) Serial.print("0");
       Serial.print(FAT_MINUTE(d.lastWriteTime));  Serial.print(':');   //client.print(str);
       if(FAT_SECOND(d.lastWriteTime) < 10) Serial.print("0");
       Serial.print(FAT_SECOND(d.lastWriteTime));     //client.print(str);

    file.printFileSize(&Serial);
    Serial.write(' ');
   // file.printModifyDateTime(&Serial);
  //  Serial.write(' ');
    
    Serial.println();
    file.close();
  }
}
  // this Function works to print to console, but I want to store the attributes name,date/time,and size
  // into varialbles so I can use client.print
void ListFiles()
{
  while (file.openNext(sd.vwd(), O_READ))
  {  file.printName(&Serial);
    if (file.isDir()) 
     {   Serial.write('/');  // Indicate a directory
     }
    cout <<F("    Modify:  ");
    //Serial.write(' ');
    file.printModifyDateTime(&Serial);
   
   // Serial.write('     ');
      cout <<F("  Size: ");
    file.printFileSize(&Serial);
    Serial.println();
    file.close();
  }
}
//------------------------------------------------------------------------------
void setup(void) 
{
  Serial.begin(9600);
  // Wait for USB Serial
  while (!Serial)
  {   SysCall::yield();
  }
  
  pinMode(10, OUTPUT);                       // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);                    // then turn off the W5100 chip!
  
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) {
    sd.initErrorHalt();
  }
 

  SdFile::dateTimeCallback(dateTime);
   
 // create a new file with timestamps
 cout << F("Open NEWfile.TXT in root with callback times\n");
  if (!file.open("/NEWfile.TXT", O_CREAT | O_WRITE)) 
      { error("open NEWfile.TXT failed");  }
  file.close();
  
  printTimestamps(file); 

 
  cout << F("\nOpen /data/testlog.txt for write with ofstream\n\n");  
    char fault_log[] = "/testlog.txt";
     ofstream fault_log_file(fault_log, ios::out| ios::app);    //   see sdstream.cpp for flags
       //{  error("open testfile.TXT failed");  }
     fault_log_file << F(" LogFault\n");
     printTimestamps(file); 
     fault_log_file.close();
 cout << F("\nPrint the timestamp after closing the file\n");    
 cout << F("to see if it displays the same info\n\n");    
        printTimestamps(file); 
                // cwd to data
       //sd.remove("testlog.txt");
//sd.ls(LS_R | LS_DATE | LS_SIZE); 
  sd.vwd()->rewind();
  sd.chdir("/"); 
  cout << F("\nList files in root with ListFiles\n\n");

 ListFiles();
 cout << F("listing with ListFilesB\n");
 sd.vwd()->rewind();
  
 ListFilesB();
 sd.chdir("/data");              // cwd to data
  cout << F("\n\nList files in /data\n");
// Does this list the data directory correctly
 ListFiles();

}

void loop() {}

ListFilesB() isn’t coming up with a name
or modify attribute

Look at the code:

void ListFilesB()
{   dir_t d;
    SdFile file;

  while (file.openNext(sd.vwd(), O_READ))
  {   for (uint8_t i = 0; i < 11; i++)
       { if(d.name[i] == ' ') continue;

Where does d get assigned a value?

NOTHING follows a { on the same line, except in an array initialization statement. I don’t see any arrays.

Format your code properly before posting it. Your code looks like it was typed by a drunken monkey.