The problem is clearly NOT due to the use of String in the loop() code
Strings are the 'right' tool for this job as you can easily add more text to the log msg without having to worry about buffer overflows and crashes.
The reduced sketch below (keeping the String stuff)
does not change freeMemory from loop() to loop()
6:1:0 3/5/2021,167.70,456.00,5.55
pump is ON
pump is OFF
FreeMemory:634
6:1:0 3/5/2021,146.60,393.00,5.55
pump is ON
pump is OFF
FreeMemory:634
6:1:0 3/5/2021,138.69,371.00,5.55
pump is ON
pump is OFF
FreeMemory:634
You might want to open the file just once and keep it open. Check what the freeMemory is doing with your complete sketch.
//https://forum.arduino.cc/t/the-system-is-getting-stuck-after-a-while/856565/2
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else // __ARM__
extern char *__brkval;
#endif // __arm__
int freeMemory() {
char top;
#ifdef __arm__
return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
return &top - __brkval;
#else // __arm__
return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#endif // __arm__
}
//#include <Wire.h>//for DS3231 (rtc)
#include "RTClib.h"// for DS3231 (rtc)
//#include <SPI.h>//SD card
#include <SD.h>//SD card
//#include <LiquidCrystal.h>
//#include <string.h>
#include <SoftwareSerial.h>
//#include <MHZ.h>
/* please ReCheck !
CH4 sensor (MQ4) analog ourput is conect to A0
pressure sensor (MPXH6400A) is conect to A1
co2 sensor (MH-Z19B) PMW output is conected to D8
*/
#define ch4Pin A0
#define pressurPin A1
byte CO2_IN = 8;
byte pump_PIN = 30; // pump on\off control
int Interval = 1;//setthe interval between readings (in minutes)
// rtc //
//RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
char buffer[24];
int secq, minq, hourq, dayq, monthq, yearq;
//SD card//
char FileName[] = "120421.txt";// change the file name
char FileNameP[] = "1104P.txt";// change the file name
const int chipSelect = 53;//SD input
String LoggerHeader = "Date [hh:mm:ss dd/mm/yyyy],pressure [mBar],CH4 [ppm],CO2 [ppm]:";//insert the heaters for the SD logging
String LoggerHeaderP = "Date [hh:mm:ss dd/mm/yyyy],Pumps status:";
File dataFile;
File dataFileP;
//CO2 sesor//
// pin for uart reading
#define MH_Z19_RX 4 // D7
#define MH_Z19_TX 0 // D6
//MHZ co2(MH_Z19_RX, MH_Z19_TX, CO2_IN, MHZ19B);
//pressure//
double V_out;
double V_s = 5 + 0.36;
void setup(void) {
Serial.begin(9600);
Serial.println("Hi");
digitalWrite(pump_PIN, LOW);
//SD card//
Serial.print(F("Initializing SD card..."));
// see if the card is present and can be initialized:
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);// davekw7x: If it's low, the Wiznet chip corrupts the SPI bus
// SD.begin(chipSelect);
// if (!SD.begin(chipSelect)) {
// Serial.println(F("Card failed, or not present"));
// while(1);
// }
Serial.println(F("card initialized."));
Serial.print("File name: ");
Serial.println(FileName);
// dataFile = SD.open(FileName, FILE_WRITE);// testing if this is a new file then add heaters
// if (dataFile == NULL) {
// Serial.println(F("error creating new datalog.txt"));
// File dataFile = SD.open(FileName, FILE_WRITE);// testing if this is a new file then add heaters
// delay (1000);
// }
// Serial.print("File size: ");
// Serial.println(dataFile.size());
// if (dataFile.size() == 0) {
// dataFile.println(LoggerHeader);
// // print to the serial port too:
// Serial.print("create new file: ");
// Serial.println(LoggerHeader);
// }
// dataFile.close();
// Initialize DS3231
// if (!rtc.begin()) {
// Serial.println("Couldn't find RTC");
// while (1);
// }
// Set sketch compiling time
///
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//use this line only if time calibration is needed
/* IF THINK HERE IS THE RTC'S PROBLME */
Serial.println("All good, no worries :) ");
// for CO2 sensor
pinMode(CO2_IN, INPUT);
pinMode(pump_PIN, OUTPUT);
// dataString.reserve(50);
// dataStringCheck.init(dataString, Serial); // init( ) will print a msg if memory is low and checkReserve( ) will print a msg
}
void loop(void) {
//Serial.println("HI ");
//DateTime now = rtc.now();
DateTime now = DateTime (2021, 5, 3,
6, 1, 0);
secq = (now.second());
minq = (now.minute());
hourq = (now.hour());
sprintf(buffer, "%02u:%02u:%02u %02u/%02u", hourq, minq, secq, dayq, monthq);//this is to zero in single nreadings (e.g., 5 sec to 05 sec)
// int Interval=1;//setthe interval between readings (in minutes)
int Mod_A = (hourq * 60 + minq) % Interval;
//if (Mod_A == 0 && secq == 0){ // for sampling evry [Interval] minutes
if (secq == 0) { // for sampling evry minute
// Serial.println(Mod_A);
double V_out = 0;
double CH4 = 0;
CH4 = analogRead(ch4Pin);
// double CH4 = (10.938*exp(1.7742*CH4pin));
V_out = analogRead(pressurPin) * (5.0 / 1023.0);
double pressure = ((V_out / V_s) + 0.00842) / 0.002421; //conversion equation to convert analog reading to kPa
//SD logging//
// make a string for assembling the data to log:
String dataString = "";
dataString += String(now.hour());
dataString += ":";
dataString += String(now.minute());
dataString += ":";
dataString += String(now.second());
dataString += " ";
dataString += String(now.day());
dataString += "/";
dataString += String(now.month());
dataString += "/";
dataString += String(now.year()); //HH:MM:SS DD/MM/YY
dataString += ",";
// dataString += ", Sensor 1: ";
dataString += String(pressure);// pressure
dataString += ",";
// dataString += ", Sensor 2: ";
dataString += String(CH4);//Mehtane
dataString += ",";
// dataString += ", Sensor 3: ";
dataString += String(5.552); //String(co2.readCO2PWM());//CO2 ppm
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
// dataFile = SD.open(FileName, FILE_WRITE);
delay(1000);
// if the file is available, write to it:
// if (dataFile) {
// dataFile.println(dataString);
// dataFile.close();
// }
// if the file isn't open, pop up an error:
// else {
// Serial.println(F("error opening datalog.txt"));
// }
// print to the serial port too:
Serial.println(dataString);
delay(2000);
}
if ( ((minq == 1) && (secq == 0)) || ((minq == 40) && (secq == 0)) ) { // for sampling evry 30 minute
digitalWrite(pump_PIN, HIGH);
Serial.println("pump is ON");
delay(1000);
digitalWrite(pump_PIN, LOW);
Serial.println("pump is OFF");
}
delay(1000);
Serial.print(" FreeMemory:"); Serial.println(freeMemory());
Serial.println();
}