Teensy3.5 SD Card File creation timestamp error

Status
Not open for further replies.

MogaRaghu

Well-known member
This code grabs 8 channel analog value and writes to SD Card. All well but when i open the SD card in WIN10 laptop I see the file creation time as a fixed date time. ( see the image below ) But inside the log file each record has the correct time stamp.

Any idea why the files have a uniform date / time stamp of creation ?

Code:
void readAnalogValues()                            // Function to read analog values / scale them / write them to SD File 
{
  if ( millis() - readAdcMs > readAdcInterval ) {

    readAdcMs = millis();

     sdFile = SD.open(currentFile, FILE_WRITE);   // Open the SDfile for the next session 
     if (!sdFile ) {
      Serial.println(" Error Opening SD Card"  );
      digitalWrite( LED, HIGH);
      while (1 == 1);                              // Error opening SD File...Wait for reset
     }
 
      sdFile.print(now());                         // Start writing to the SD file Date&Time in Epoch and then 8 channel values...
      sdFile.print(',');
      for (int i = 0 ; i < 8; i++)
      {
        voltage[i] = adc->adc0->analogRead(readPin[i]) * resolution ;
        sdFile.print(voltage[i], 3);
        delay(2);
        if (i < 7)
          sdFile.print(',');
      }
      sdFile.println();
      
      sdFile.close();                              // Done writing. Close the SD File..
    }
  }

Log File folder.PNG
 
Instead of posting patches of the code let me post the whole code. Right now besides the date/time stamp issue, the one other thing is there is no start / stop for the Logging process. I plan to bring in Push Buttons or a simple Touch Screen to do this. Till that time the open file in SD card will be unceremoniously left in that condition when power is removed. I know its bad but only till I bring in Start and Stop. So here is the full code : ( Incidentally I will be happy to get some critical comments on the coding style per se. Of course it has lots of patches from other example codes )

Code:
/*
   28 July 2020
   This code runs on Teensy3.5 which has a battery backed RTC.  This code
   must be compiled with the Teensy version of SPI and Wire libraries..

   This is a bare bone code to just check the ADC functionality and writing to SD Card.
   Code for Auto update of RTC from PC time base is included.
   Auto file name generation is done.
   Other aspects like facility to start / stop logging, scaling of ADC channels etc
   need to be built in. 

   29 July 2020
   Refine the code removing the String object. Also use Arrays to handle 8 ch in a FOR loop.
   Code a Fixed duration LED flash to denote SD card write.OK 

*/

#include <ADC.h>
#include <ADC_util.h>
#include <SPI.h>
#include <SD.h>
#include <TimeLib.h>

#define VREF 3.3
#define resolution (VREF/((pow(2,12))-1))

const int chipSelect = BUILTIN_SDCARD;

const int readPin[8] = {A0, A1, A2, A3, A4, A5, A6, A7};

const int LED = 13;
bool ledState ;

double voltage[8];
unsigned long readAdcMs = millis();
unsigned long ledOnMs = millis();
unsigned long writeSDMs = millis();
unsigned long readAdcInterval = 1000;               // How often to read ADC
unsigned long ledOnInterval = 100;                  // How long the LED is on to denote SD write.
unsigned long writeSDInterval = 5000;               // How often to write to SD

char filename[32];
char currentFile[32];

// Instantiate objects..
File sdFile;
ADC *adc = new ADC();

//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO

void setup() {

  setSyncProvider(getTeensy3Time);                           // Set the Time library to use Teensy 3.5's RTC to keep time

  for (int i = 0; i < 8 ; i++) {
    pinMode(readPin[i], INPUT );                             // Set all 8 adc inputs..
  }

  pinMode(LED, OUTPUT);

  Serial.begin(9600);
  while (!Serial);                                            // Serial printing does not happen without this while loop delay !!
  delay(500);

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

  if (!SD.begin(chipSelect))                                   // Start the SD Card interface..
  {
    Serial.println( " SD Card Init failure !!");
    while ( 1 == 1) {
      ledState = !ledState ;
      digitalWrite( LED, ledState);
      delay(500);                                               // Hang on here for Reset flashing the LED..
    }
  }

  char filename[] = "T35LOG00.CSV";                           // Create a logging file
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) {
      sdFile = SD.open(filename, FILE_WRITE);                  // Only open a new file if it doesn't exist
      if (sdFile) {
        strcpy(currentFile, filename);                         // Get a copy of the active filename
        sdFile.close();
      }
      else {
        Serial.println(" Error Opening SD Card"  );
        digitalWrite( LED, HIGH);
        while (1 == 1);                                       // Wait for reset
      }
      break;
    }
  }

  // Configure the ADC0

  adc->adc0->setReference(ADC_REFERENCE::REF_3V3);
  adc->adc0->setAveraging(8);
  adc->adc0->setResolution(12);
  adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED);
  adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED);
}

//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO

void loop()
{
  getTimeFromPC();
  readAnalogValues();
  logToMicroSD();
  ledForSDWrite();
}

//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
//OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO


void readAnalogValues()                            // Function to read analog values / scale them / save them to SD File to write later
{
  if ( millis() - readAdcMs > readAdcInterval ) {

    readAdcMs = millis();
 
      sdFile.print(now());
      sdFile.print(',');
      for (int i = 0 ; i < 8; i++)
      {
        voltage[i] = adc->adc0->analogRead(readPin[i]) * resolution ;
        sdFile.print(voltage[i], 3);
        delay(2);
        if (i < 7)
          sdFile.print(',');
      }
      sdFile.println();
    }
  }


//.............................................

void logToMicroSD() {
 
  if ( millis() - writeSDMs > writeSDInterval) {

    writeSDMs = millis();

    sdFile.close();                                // Transfer the logged data from buffer to SD Card
    
    digitalClockDisplay();
    ledState = HIGH ;
    ledOnMs = millis();
    digitalWrite(LED, HIGH);                      // Enable the LED .. will switch off after a fixed time.

    Serial.println(now());
    for (int i = 0 ; i < 8; i++)
    {
      Serial.println(voltage[i], 3);              // Print on monitor..
    }

     sdFile = SD.open(currentFile, FILE_WRITE);   // Open the SDfile for the next session 
     if (!sdFile ) {
      Serial.println(" Error Opening SD Card"  );
      digitalWrite( LED, HIGH);
      while (1 == 1);                              // Wait for reset
     }
  }
}

//.............................................

void digitalClockDisplay()
{
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

//..............................................

time_t getTeensy3Time()
{
  return Teensy3Clock.get();
}

//...............................................

void printDigits(int digits)                     // Utility  clock display: prints preceding colon and leading 0
{
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

//.............................................

void getTimeFromPC ()
{
  if (Serial.available() )
  {
    time_t t = processSyncMessage();              // Try to synch with PC clock..
    if (t != 0)
    {
      Teensy3Clock.set(t);                        // Set the RTC
      setTime(t);
    }
  }
}

//.............................................

#define TIME_HEADER  "T"                        // Header tag for serial time sync message
unsigned long processSyncMessage()
{
  unsigned long pctime = 0L;
  const unsigned long DEFAULT_TIME = 1577836800; // Jan 1 2020
  if (Serial.find(TIME_HEADER))
  {
    pctime = Serial.parseInt();
    return pctime;
    if ( pctime < DEFAULT_TIME)                 // Check the value is a valid time (greater than Jan 1 2013)
    {
      pctime = 0L;                              // Return 0 to indicate that the time is not valid
    }
  }
  return pctime;
}

//............................................

void ledForSDWrite() {
  if ( ledState) {
    if (millis() - ledOnMs > ledOnInterval) {
      digitalWrite(LED, LOW);
      ledState = LOW;
    }
  }
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 
Status
Not open for further replies.
Back
Top