Data logging interval takes 1 sec longer every 15 minutes

I would like some help on a data logging interval. Around every 17 minutes (nearby 1240 seconds) the usual interval of 5 seconds now takes 6 seconds, before a new String of data will be written.

for this logger i use:

  • Arduino uno R3
  • Velleman VMA 202 SD Card shield with soldered molex connector for NTC
  • Velleman VMA 203 LCD Shield (Pin 10 isn’t present anymore because this pin is in usage for the SD SPI Bus, and was on the LCD shield only used for an hardware lcd backlight disabel function)
  • 2 NTC 10K Ohm

Here’s my code

// libriary's 
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
RTC_DS1307 rtc;
/*
#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
   #define Serial SerialUSB
#endif */

// Sensors variables 
int ThermistorPin_1 = A2;
int Vo_1;
float R1_1 = 9970;
float logR2_1, R2_1, T_1, Tc_1;

int ThermistorPin_2 = A1;
int Vo_2;
float R1_2 = 9944;
float logR2_2, R2_2, T_2, Tc_2;

float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;

float DeltaT_1;


// Timers variables
unsigned long previoustime = 0;
const long interval = 5000;     // interval logging
unsigned long currenttime;

byte RunningMode = 0;
unsigned long previoustimeLaunch = 0;
long intervalLaunch; 
long intervalLaunchIcon = 2500;
unsigned long currenttimeLaunch;


// Average temp variables 
const int numReadings = 5;    // number of readings for average 
int readingsT1[numReadings];     
int readIndexT1;              
int totalT1;                  
float averageT1;           

int readingsT2[numReadings];     
int readIndexT2;              
int totalT2;                  
float averageT2; 


// SD logging variables
const int chipSelect = 10;
File dataFile;
DateTime now;
byte dataFileStart = 0;
byte Filenameupset = 0;
byte dataFileFirstRule = 0;
String filename;


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);

//Display showing starting up
lcd.begin(16, 2);
lcd.setCursor(2,0);
lcd.print("Data Logger");
lcd.setCursor(2,1);
lcd.print("starting up");

//RTC setup (Real Time Clock)
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
   Serial.println("RTC is NOT running!");
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

   SdFile::dateTimeCallback(dateTime); 

//Average Temperatur Setup
 for (int thisReadingT1 = 0; thisReadingT1 < numReadings; thisReadingT1++) {
  readingsT1[thisReadingT1] = 0;
 }

 for (int thisReadingT2 = 0; thisReadingT2 < numReadings; thisReadingT2++) {
  readingsT2[thisReadingT2] = 0;
 }
}


void loop() {
//General Startin/ equal some variables 
 unsigned long currenttime = millis ();
 unsigned long currenttimeLaunch = millis ();
 
 long intervalLaunch = interval * numReadings;

//interval programs
 if (currenttime - previoustime >= interval)  {
  previoustime = currenttime;
  Temperaturen();
  AverageTemperaturen();  
  Filenamesetup();
    if (currenttimeLaunch - previoustimeLaunch >= intervalLaunch) {
    Display(); 
    Datalogger();
    RunningMode = 1;
    }
  }
  if (RunningMode == 0 and currenttimeLaunch - previoustimeLaunch >= intervalLaunchIcon) {
    lcd.setCursor(1,1);
    lcd.print("Loading temps");
  }
}

void Temperaturen() {
  Vo_1 = analogRead(ThermistorPin_1);
  R2_1 = R1_1 * (1023.0 / (float)Vo_1 - 1.0);
  logR2_1 = log(R2_1);
  T_1 = (1.0 / (c1 + c2*logR2_1 + c3*logR2_1*logR2_1*logR2_1));
  Tc_1 = ((T_1 - 273.15) * 1.1308) - 2.35;

  Vo_2 = analogRead(ThermistorPin_2);
  R2_2 = R1_2 * (1023.0 / (float)Vo_2 - 1.0);
  logR2_2 = log(R2_2);
  T_2 = (1.0 / (c1 + c2*logR2_2 + c3*logR2_2*logR2_2*logR2_2));
  Tc_2 = ((T_2 - 273.15) * 1.0905) - 1.86;
}

void AverageTemperaturen()  {
  totalT1 = totalT1 - readingsT1[readIndexT1];
  readingsT1[readIndexT1] = (float) Tc_1 * 10;
  totalT1 = totalT1 + readingsT1[readIndexT1];
  readIndexT1 = readIndexT1 + 1;

  if (readIndexT1 >= numReadings) {
    readIndexT1 = 0;
    }
   averageT1 = ((float)totalT1 / numReadings) / 10;


  totalT2 = totalT2 - readingsT2[readIndexT2];
  readingsT2[readIndexT2] = (float) Tc_2 * 10;
  totalT2 = totalT2 + readingsT2[readIndexT2];
  readIndexT2 = readIndexT2 + 1;

  if (readIndexT2 >= numReadings) {
    readIndexT2 = 0;
    }
   averageT2 = ((float)totalT2 / numReadings) / 10;

   DeltaT_1 = averageT1 - averageT2;
}

void Display()  {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("T1=");
  lcd.print(averageT1,1);
  
  lcd.setCursor(0,1);
  lcd.print("T2=");
  lcd.print(averageT2,1);

  lcd.setCursor(9,0);
  lcd.print("Delta T");
  lcd.setCursor (11,1);
  lcd.print(DeltaT_1,1);
}

void Filenamesetup()  {
DateTime now = rtc.now(); 

if ((Filenameupset == 0) or (now.hour() == 0 and now.minute() == 1 and now.second() <= ((interval - 1) / 1000)))  {
  filename = "";
  if (now.day() < 10)
  { filename += 0;  }
  filename += now.day();
  if (now.month() < 10)
  { filename += 0;  }
  filename += now.month();
  if (now.hour() < 10)
  { filename += 0;  }
  filename += now.hour();
  if (now.minute() < 10)
  { filename += 0;  }
  filename += now.minute();
  filename += ".xls";
  Filenameupset = 1;
  dataFileStart = 0;
  dataFileFirstRule = 1;
  }
}

void Datalogger() {
  
   // data for the sd write string
  String dataString = "";
  DateTime now = rtc.now(); 
  if (now.hour() < 10)
  { dataString += 0;  }  
  dataString += now.hour();
  dataString += ":";
  if (now.minute() < 10)
  { dataString += 0;  }
  dataString += now.minute();
  dataString += ":";
  if (now.second() < 10)
  { dataString += 0;  }
  dataString += now.second();
  dataString += ("\t");
  if (now.day() < 10)
  { dataString += 0;  }
  dataString += now.day();
  dataString += "-";
  if (now.month() < 10)
  { dataString += 0;  }
  dataString += now.month();
  dataString += "-";    
  if (now.year() < 10)
  { dataString += 0;  }   
  dataString += now.year();
  dataString += ("\t");
  dataString += averageT1;
  dataString += ("\t");
  dataString += averageT2;
  dataString += ("\t");
  dataString += DeltaT_1;
  
  
//SD Card logging
SD.begin(chipSelect);
dataFile = SD.open(filename.c_str(), FILE_WRITE);

  if (dataFile) {
    if (dataFileFirstRule == 1) {
      dataFileStart = 1;
      dataFileFirstRule = 2;
      dataFile.println("Time \t Date \t T01 \t T02 \t Delta T");
      dataFile.println("");
      dataFile.close();
    }
    if (dataFileStart == 1)  {
      dataFile.println(dataString);
      dataFile.close();
    }
  }
}

Can't look at your code as I'm on a cellphone.

What probably happens:
When you use write or print, the data is written to a buffer and not to the card. When that buffer us full, the actual write to the card happens.

A flush or closing the file forces writing to the card.

I updated the post, and you should be able to look at my code from a cellphone.

As you can see in the code bellow i close the file in every interval/ loop. So the buffer should be flushed and be written to the card. I also can see the data on the card when i plug it in for a few loops, so it isn't be written once when the buffer is full.

//SD Card logging
SD.begin(chipSelect);
dataFile = SD.open(filename.c_str(), FILE_WRITE);

  if (dataFile) {
    if (dataFileFirstRule == 1) {
      dataFileStart = 1;
      dataFileFirstRule = 2;
      dataFile.println("Time \t Date \t T01 \t T02 \t Delta T");
      dataFile.println("");
      dataFile.close();
    }
    if (dataFileStart == 1)  {
      dataFile.println(dataString);
      dataFile.close();
    }
  }
}