Suspected memory leak arduino hanging after a while

Hi,

been trying to solve that for over a mont, but no chance. Random freezing after a few hours. I suspect a memory leak in either of the 2 functions:
char * timeprint(DateTime nowtime)
void logsd(float array_sensor[6][2], byte hyst, const char *datastatus)


// TO FIX
//xxxincrease hysteresis to 10
//add solar panel
//xxxfix writing
//xxxfix error 85 and wrong number
// check if better to use temp tuy for stopping



// ********************* LIBS *************************************
// For ds18b20 temperature sensor to work, needs 2 libraries: DallasTemperature by Miles Burton & al and OneWire by Jim Studt & al
#include <OneWire.h> //downgrading from 2.35 to 2.30 as a possible solution for the 85 deg problem
#include <DallasTemperature.h>
// For I2C (LCD and clock)
#include <Wire.h> 
// For LCD
#include <LiquidCrystal_I2C.h> //needs to add library
// For SD
#include <SPI.h>
#include <SD.h>
// For sleep
#include <LowPower.h>
// For clock
#include <RTClib.h>
//for watchdog
#include <avr/wdt.h>

#include <avr/pgmspace.h>



// ********************* CONST *************************************
// pins const byte vs define doesn't change memory use or even using number in code
#define WAKEUPPIN 2         //get the clock signal
#define BUTTONPIN 3         //button to show screen
#define DAMPERCLOSEPIN 4    //to close the damper and set fan to blow inside house
#define DAMPEROPENPIN 5     //to open the damper and set fan to blow inside capteur
#define FANPIN 6            //to start fan either direction
#define ONE_WIRE_BUS 8      //bus to read temp sensors
#define BATTERYV A1         // battery voltage
#define POT A3              //potentiometer to set temp diff

// temp sensors in one wire bus and in sensor array and in tsensor
#define TEMPCAP 0           //sensor nber for temp inside capteur
#define TEMPTUY 1           //sensor nber for temp exit pipe
#define TEMPEXT 2           //sensor nber for temp ext
#define TEMPMAIS 3          //sensor nber for temp int mais

//index in sensor array
#define TEMPDIFF 4
#define BATT 5

//const
#define FILEDATA "logfile.csv"
#define HYSTERESIS 10        //in degree
#define LOGDELAY 1          //number of sleep interrupts between logs under 255 
#define LCDDELAY 30         //lcd stays on for that many seconds after button pressed
#define ALARMSECONDS 60     //nber of seconds between each wake up, need to be high than time to process loop >4s
#define BUFF_SIZE 10        // 10 data piece for each sensor
#define LOGTIME 10           // time in s to log after alarm triggered SHOULD BE BIGGER THAN DURATION OF LOOP AND LOWER THAN ALARMSECONDS 

// ********************* GLOBAL VAR AND OBJECTS *************************************
// Global variables
unsigned long PreviousSecondsLCD = 0;     // last we wrote to lcd
volatile boolean SDok = false;          // status of SD reader 
volatile byte syststatus = 4;            // 0 for off, 1 for normal run, 2 for summer run, 4 for start undetermined
volatile boolean ButtonPressed = false;          // status of button
boolean lcdon = false;                  // status of lcd
volatile boolean alarmset = false;      //alarm status
volatile byte timeforsaving = 0;         //keeps track of number of wake up of alarm for knowing when to save data, under 255
boolean writtingps = false;             //is writing on SD in ps
volatile unsigned long timesetalarm=0;    //time for next alarm
volatile unsigned long ventstarttime=0; //last time the vent started operating
volatile float testtemp=2;                  //timer in unixtime
volatile int nbersensorpb=0;       //becomes true if more than 10 sensor problems in a row
volatile long nberrun=0;

// Global object for sensors
OneWire oneWire(ONE_WIRE_BUS);          // Setup a oneWire instance to communicate with sensors
DallasTemperature sensors(&oneWire);    // Pass oneWire reference to DallasTemperature library
LiquidCrystal_I2C lcd(0x27,20,4);       // set the LCD address to 0x27 for a 20 chars and 4 line display
RTC_DS3231 rtc; //for the clock

DeviceAddress tsensor[4]=
{
  { 0x28, 0xEE, 0x16, 0xBE, 0x33, 0x20, 0x01, 0xE5 }, //temp capt num 0
  { 0x28, 0x11, 0x3E, 0xC0, 0x63, 0x20, 0x01, 0xB3 }, //temp tuyau num 1
  { 0x28, 0x73, 0x29, 0x90, 0x63, 0x20, 0x01, 0xEB }, //temp ext num 2
  { 0x28, 0x97, 0x94, 0xD2, 0x33, 0x20, 0x01, 0x21 } //temp mais num 3
};

//text string in progmem to save memory
const char msg_start[] PROGMEM = {"************************** STARTING *****************************"};
const char msg_header[] PROGMEM = {"temp_cap,temp_tuy,temp_ext,temp_mais,temp_diff,hyst,battv,syststatus"};
const char msg_sensorerror[] PROGMEM = {"Not doing anything as sensor trouble"};
const char msg_startnormal[] PROGMEM = {"Starting normal operations"};
const char msg_stopnormal[] PROGMEM = {"Stopping normal operations"};
const char msg_startsummer[] PROGMEM = {"Starting summer operations"};
const char msg_stopsummer[] PROGMEM = {"Stopping summer operations"};
const char msg_stoptrouble[] PROGMEM = {"Stopping Sensor trouble"};

const char msg1[] PROGMEM = {"1"};
const char msg2[] PROGMEM = {"2"};
const char msg3[] PROGMEM = {"3"};
const char msg4[] PROGMEM = {"4"};
const char msg5[] PROGMEM = {"5"};
const char msg6[] PROGMEM = {"6"};
const char msg7[] PROGMEM = {"7"};
const char msg8[] PROGMEM = {"8"};
const char msg9[] PROGMEM = {"9"};
const char msg10[] PROGMEM = {"10"};
const char msg11[] PROGMEM = {"11"};
const char msg12[] PROGMEM = {"12"};
const char msg13[] PROGMEM = {"13"};
const char msg14[] PROGMEM = {"14"};
const char msg15[] PROGMEM = {"15"};
const char msg16[] PROGMEM = {"16"};
const char msg17[] PROGMEM = {"17"};
const char msg18[] PROGMEM = {"18"};
const char msg19[] PROGMEM = {"19"};



const char msg_sleep[] PROGMEM = {"going to sleep"};
const char msg_wakeup[] PROGMEM = {"waking up"};








const char type_linetype[] PROGMEM = {"line_type"};
const char type_status[] PROGMEM = {"status"};

const char datatype_status[] PROGMEM = {"statusdata"};
const char datatype_data[] PROGMEM = {"data"};

// ********************* FUNCTIONS *************************************

//return temperature for one of the sensor, need to have the sensors initialised before calling
float readTemp(int sensor)
{
  return sensors.getTempC(tsensor[sensor]);
}

//return pot value
float readPot(){
  float temppot;
  temppot=0;
  for (int i=0; i< BUFF_SIZE; i++) {  
    temppot=temppot+map(analogRead(POT),0,1023,0,40);
  }
  return temppot/BUFF_SIZE;
}

//return batt value
//resistor of 333 and 1000 ohm
float readBatt(){
  float tempbat;
  tempbat=0;
  for (int i=0; i< BUFF_SIZE; i++) {  
    tempbat=tempbat+1333 / 333 * analogRead(BATTERYV) * (5.0 / 1023.0);
  }
  return tempbat/BUFF_SIZE;
}

//print the data on lcd
void lcdprintvalue(float sensor_array[6][2], byte hysteresis)
{
  if (!lcdon){
    PreviousSecondsLCD = rtc.now().unixtime(); 
    lcdon=true;
  }

  if (rtc.now().unixtime() - PreviousSecondsLCD < LCDDELAY){
    if (nbersensorpb<=10){
      lcd.setCursor(0, 0); lcd.print(F("Cap=")); lcd.setCursor(4, 0); lcd.print(sensor_array[0][0],1);      
      lcd.setCursor(10, 0); lcd.print(F("Tuy=")); lcd.setCursor(14, 0); lcd.print(sensor_array[1][0],1);
      lcd.setCursor(0, 1); lcd.print(F("Ext=")); lcd.setCursor(4, 1); lcd.print(sensor_array[2][0],1);     
      lcd.setCursor(10, 1); lcd.print(F("Mai=")); lcd.setCursor(14, 1); lcd.print(sensor_array[3][0],1);
      lcd.setCursor(0, 2); lcd.print(F("Diff=")); lcd.setCursor(5, 2); lcd.print((byte)sensor_array[4][0]); 
      lcd.setCursor(10, 2); lcd.print(F("Hy=")); lcd.setCursor(14, 2); lcd.print((byte)hysteresis);    
      lcd.setCursor(0, 3); lcd.print(F("BatV=")); lcd.setCursor(5, 3); lcd.print(sensor_array[5][0]);
      lcd.setCursor(13, 3); lcd.print(F("Fan "));
      lcd.setCursor(17, 3);
      switch (syststatus) {
        case 0:
          lcd.print(F("off")); 
          break;
        case 1:
          lcd.print(F("on ")); 
          break;
        case 2:
          lcd.print(F("sum")); 
          break;
        case 4:
          lcd.print(F("xxx")); 
          break;          
      }
    }
    else{
//      Serial.print(F("in the sensor problem loop"));
      lcd.setCursor(0, 0); lcd.print(F("Sensor trouble"));
    }
  }
  else {
    noInterrupts();
    ButtonPressed=false;
    interrupts();
  }
}

//return byte 2 digits with leading 0 
char * convert2digits(byte x){
  char static xtrg[3];                      // static so the result is available outside but memory is never freed, still more readable than global var
  char tempstr[3];
  itoa(x,tempstr,10);

  if (x<10){
    strcpy(xtrg,"0");
    strcat(xtrg,tempstr);
  }
  else {
    strcpy(xtrg,tempstr);
  }
  return xtrg;
}

// return char with time
char * timeprint(DateTime nowtime){
  char yr[5];
  char static timetoprint[20];                   // static so the result is available outside but memory is never freed, still more readable than global var
  itoa(nowtime.year(),yr,10);
  strcpy(timetoprint,yr);
  strcat(timetoprint,"-");
  strcat(timetoprint,convert2digits(nowtime.month()));
  strcat(timetoprint,"-");
  strcat(timetoprint,convert2digits(nowtime.day()));
  strcat(timetoprint," ");
  strcat(timetoprint,convert2digits(nowtime.hour()));
  strcat(timetoprint,":");
  strcat(timetoprint,convert2digits(nowtime.minute()));
  strcat(timetoprint,":");
  strcat(timetoprint,convert2digits(nowtime.second()));
  return timetoprint;    
}

void WriteMsgSD(const char *msg, const char *linetype){ 
                   WriteMsgSD(msg11,type_status);

  
  while (writtingps) {
    ; // wait for previous writing to be finished
  }
 
  writtingps=true;
  char fullline[100];
  File myFile;
  myFile = SD.open(FILEDATA, FILE_WRITE);
  if (myFile){
    strcpy(fullline,timeprint(rtc.now()));
    strcat(fullline,",");
    strcat_P(fullline,linetype); 
    strcat(fullline,",");
    strcat_P(fullline,msg);
    myFile.println(fullline);
//Serial.print(F("writemsgsd saving: "));Serial.println(fullline);
    myFile.close();
  }
  writtingps=false;
                    WriteMsgSD(msg12,type_status);

}

//log sensor data to SD with data status msg, hysteresis and system status(global)
// need to make sure that each string as a an additional space for \0 otherwise random bug
void logsd(float array_sensor[6][2], byte hyst, const char *datastatus){
  char temp_cap_c[8], temp_tuy_c[8],temp_ext_c[8], temp_mais_c[8], temp_diff_c[3],hyst_c[3],battv_c[6],syststatus_c[2];
  char linetowrite[80];
                    WriteMsgSD(msg13,type_status);
 
  while (writtingps) {
    ; // wait for previous writing to be finished
  }
  writtingps=true;

  File myFile;
  myFile = SD.open(FILEDATA, FILE_WRITE);
  if (myFile){
    timeprint(rtc.now());
    strcpy(linetowrite,timeprint(rtc.now()));
    strcat(linetowrite,",");
    strcat_P(linetowrite,datastatus); 
    strcat(linetowrite,",");
    dtostrf(array_sensor[0][0],6, 2, temp_cap_c);
    strcat(linetowrite,temp_cap_c);
    strcat(linetowrite,",");
    dtostrf(array_sensor[1][0],6, 2, temp_tuy_c);
    strcat(linetowrite,temp_tuy_c);
    strcat(linetowrite,",");
    dtostrf(array_sensor[2][0],6, 2, temp_ext_c);
    strcat(linetowrite,temp_ext_c);
    strcat(linetowrite,",");
    dtostrf(array_sensor[3][0],6, 2, temp_mais_c);
    strcat(linetowrite,temp_mais_c);
    strcat(linetowrite,",");
    itoa(array_sensor[4][0],temp_diff_c,10);
    strcat(linetowrite,temp_diff_c);
    strcat(linetowrite,",");
    itoa(hyst,hyst_c,10);
    strcat(linetowrite,hyst_c);
    strcat(linetowrite,",");
    dtostrf(array_sensor[5][0],6, 2, battv_c);
    strcat(linetowrite,battv_c);
    strcat(linetowrite,",");
    itoa(syststatus,syststatus_c,10);// use an additional variable to save syststatus because of bug
    strcat(linetowrite,syststatus_c);
        myFile.println(linetowrite);

//Serial.print(F("logsd saving: "));Serial.println(linetowrite);
    myFile.close();
  }
  writtingps=false;
                    WriteMsgSD(msg14,type_status);

}

void onAlarm() {
  alarmset = false;
}

void onButton() {
  ButtonPressed = true;  
}

void sensor_loop (float array_avg[6][2]){
  float data;

  for (int j=0; j<6; j++){              // initialise array
    array_avg[j][0]=0;
    array_avg[j][1]=0;
  }
  
  for (int i=0; i< BUFF_SIZE; i++) {        // take measures
      for (int j=0; j<6; j++){              // loop through the temp sensors
        switch (j) {
          case 0 ...3:
            data = readTemp(j); 
            break;
          case 4:
              data=readPot();       //took out of function to reduce prog size
            break;
          case 5:
            data= readBatt(); //took out of function to reduce prog size
        }
//          Serial.print(F("data"));Serial.println(data);

        if (data==-127 or data==85){//check sensor problem
          array_avg[j][1] = array_avg[j][1]+1;

        }
        else {
          array_avg[j][0] = array_avg[j][0]+data;
        }
     }
  }
  for (int j=0; j<6; j++){
    if (array_avg[j][1]!=BUFF_SIZE){
      array_avg[j][0] = array_avg[j][0]/(BUFF_SIZE-array_avg[j][1]);
    }
    else {
      array_avg[j][0]=-127;
    }
  }
}

//return false if for one of the sensor there is only wrong values on mais or capt
boolean checkarray(float arraytocheck[6][2]){
  boolean nopb = true;

  if (arraytocheck[0][1]==BUFF_SIZE or arraytocheck[3][1]==BUFF_SIZE){
      nopb = false;
  }
  return nopb;
}

int freeRam() 
{
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}


void setup() 
{

  // Start serial communication for debugging purposes
  Serial.begin(9600);
    while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
//Serial.print(F("*******STARTING **** RAM at begining of setup:"));
//Serial.println(freeRam());
//  Serial.print(F("running the setup at "));Serial.println(rtc.now().unixtime());
  // Start lcd
  lcd.init();
  lcd.backlight();

  // Start up the library for DallasTemperature on OneWire
  sensors.begin();

  // initialize the pins (not need for analog pin)
  pinMode(BUTTONPIN, INPUT_PULLUP);
  pinMode(FANPIN, OUTPUT);
  pinMode(DAMPEROPENPIN, OUTPUT);
  pinMode(DAMPERCLOSEPIN, OUTPUT);
  pinMode(WAKEUPPIN, INPUT_PULLUP); //for accepting the interrupt signal from RTC DS3231

  //initialize RTC
  lcd.setCursor(0, 0);
  if (!rtc.begin()) {
    lcd.print(F("Couldn't find RTC"));
  }
  else{
    lcd.print(F("Found RTC"));
  }

  //set RTC time at each compile
  // Following line sets the RTC to the date & time this sketch was compiled
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // Comment out below lines once you set the date & time.
  // Following line sets the RTC with an explicit date & time
  // for example to set January 27 2022 at 02:20 you would call:
  // rtc.adjust(DateTime(2022, 03, 10, 05, 49, 0));

  //intialise the SD and RTC and write its state on lcd even if off
  lcd.setCursor(0, 1);
  SDok = SD.begin(10);
  if (!SDok) {
    lcd.print(F("SD init failed!"));
 //   Serial.println(F("CARD not OK"));

  }
  else {
    lcd.print(F("CARD OK"));
//Serial.println(F("CARD OK"));

    WriteMsgSD(msg_header,type_linetype);
    WriteMsgSD(msg_start,type_status);
  }

  // print RTC time on LCD for a few seconds
  timeprint(rtc.now());
  lcd.setCursor(0, 3);
  lcd.print(timeprint(rtc.now()));
  delay(5000);
  lcd.noBacklight();
  lcdon=false;
  lcd.clear();

  //clear any pending alarms !! it doesn't need to be done every time before sleeping
  rtc.clearAlarm(1);
  rtc.clearAlarm(2);
  //Set SQW pin to OFF
  rtc.writeSqwPinMode(DS3231_OFF);
  // turn off alarm 2 (in case it isn't off already)
  rtc.disableAlarm(2);

  //set interrupt for button
  attachInterrupt(digitalPinToInterrupt(BUTTONPIN), onButton, FALLING);
  //!!!!!! changed to low for stability
  //set interrupt for RTC alarm
  attachInterrupt(digitalPinToInterrupt(WAKEUPPIN), onAlarm, FALLING);
    //!!!!!! changed to low for stability

  timesetalarm = rtc.now().unixtime()+ALARMSECONDS;
  noInterrupts();
  alarmset=true;
  interrupts();
  rtc.setAlarm1(timesetalarm, DS3231_A1_Second); // this mode triggers the alarm when the minutes match. See Doxygen for other options)
  timesetalarm=timesetalarm+ ALARMSECONDS;
  timeforsaving++; 
//timertest=31;
    wdt_enable(WDTO_8S); //8s is ok as long as the processing of the main loop doestn't last longer than 8s (for now 2s)

}

//*******************************************************************************
//*******************************************************************************

void loop() {
          WriteMsgSD(msg_wakeup,type_status);

//!!!!!!!!!!to check with other arduino  
//Serial.write("Y",1);// to wake up other arduino
// delay(500);
//Serial.write("Y",1);// to confirm other arduino
//!!!!!!!!!!to check with other arduino  

 delay(500);

//  Serial.print(F("starting loop at "));Serial.println(rtc.now().unixtime());
  sensors.requestTemperatures(); //done here rather than in the function to avoid reapeating it multiple times
//  delay(1000); //give time to temp sensors to initialize
  //reading the sensors with BUFFER_SIZE value average
  //using a global array and not passing it doesn't affect memory usage
  float array_sensor[6][2]; //row= 0 to 3 for temp, 4 for temp_diff,5 for battv

  sensor_loop(array_sensor);
//  Serial.print(F("read temp at "));Serial.println(rtc.now().unixtime());
                 WriteMsgSD(msg1,type_status);

// log to SD every LOGDELAY times, will be done after psing so may not be exactly spaced in time
// and will be more often when lcd on
  if (SDok){
    if (timeforsaving==LOGDELAY) {
//        Serial.print(F("starting writing to SD at "));Serial.println(rtc.now().unixtime());

       logsd(array_sensor, HYSTERESIS,datatype_data);
       timeforsaving = 0;
                 WriteMsgSD(msg2,type_status);

//      delay((LOGTIME-(rtc.now().unixtime()-(timesetalarm-ALARMSECONDS)))*1000);
//        Serial.print(F("done writing to SD at "));Serial.println(rtc.now().unixtime());

    }
  }

  boolean sensorpb = not(checkarray(array_sensor));
//Serial.print(F("the value of sensorpb "));Serial.println(sensorpb);

  if (sensorpb) {
    WriteMsgSD(msg_sensorerror,type_status);
    nbersensorpb++;
    }
    else {
      nbersensorpb=0;
    }

                 WriteMsgSD(msg3,type_status);

//array_sensor[0][0] = 500; //capteur
//array_sensor[3][0] = 10; //mais


/*
for (int i=0; i< 6; i++) {  
  Serial.print(F("temp"));Serial.print(i);Serial.print(F(": "));Serial.println(array_sensor[i][0]);
    delay(500); //give time to temp sensors to print
}
*/

  //no summer mode for testing
  boolean issummer = (rtc.now().month()==7 or rtc.now().month()==8); 


//array_sensor[0][0]=80;
//        Serial.print(F("before loop on motor "));Serial.println(rtc.now().unixtime());

                 WriteMsgSD(msg4,type_status);

  if (!sensorpb){
    if (!issummer){  
      //open or close airvent.Start based on cap temp, stop based on tuy temp. Check hysteresis necessary
      if (array_sensor[0][0] - array_sensor[3][0] - array_sensor[4][0] - HYSTERESIS>= 0 && syststatus!=1){                    //must run based on temp_cap - temp_mais
        digitalWrite(DAMPERCLOSEPIN, LOW);
        digitalWrite(DAMPEROPENPIN, HIGH);
        ventstarttime=rtc.now().unixtime();
        digitalWrite(FANPIN, HIGH);
        syststatus=1;
        WriteMsgSD(msg_startnormal,type_status);//"Starting normal operations","status");
        logsd(array_sensor, HYSTERESIS,datatype_status);
                 // Serial.println(F("start normal"));
     delay(500); //give time to temp sensors to initialize

      }
      if (array_sensor[0][0] - array_sensor[3][0] - array_sensor[4][0] - HYSTERESIS <= -HYSTERESIS && syststatus!=0){          //must stop based on temp_cap - temp_mais
        digitalWrite(DAMPEROPENPIN, LOW);
        digitalWrite(DAMPERCLOSEPIN, HIGH);
        ventstarttime=rtc.now().unixtime();
        digitalWrite(FANPIN, LOW);
        syststatus=0;
        WriteMsgSD(msg_stopnormal,type_status);//"Stopping normal operations","status"); 
        logsd(array_sensor, HYSTERESIS,datatype_status);  
              //    Serial.println(F("stop normal"));
        delay(500); //give time to temp sensors to initialize

      }
    }
    else {
      if (array_sensor[0][0]>50 && syststatus!=2) {
        digitalWrite(DAMPEROPENPIN, LOW);
        digitalWrite(DAMPERCLOSEPIN, HIGH);
        ventstarttime=rtc.now().unixtime();
        digitalWrite(FANPIN, HIGH);
        syststatus=2;
        WriteMsgSD(msg_startsummer,type_status);//"Starting summer operations","status");
        logsd(array_sensor, HYSTERESIS,datatype_status);
        delay(500); //give time to temp sensors to initialize
      }
      if (array_sensor[0][0]<45 && syststatus!=0) { // use 5 as hysteresis
        digitalWrite(DAMPEROPENPIN, LOW);
        digitalWrite(DAMPERCLOSEPIN, HIGH);
        ventstarttime=rtc.now().unixtime();
        digitalWrite(FANPIN, LOW);
        syststatus=0;
        WriteMsgSD(msg_stopsummer,type_status);//"Stopping summer operations","status");
        logsd(array_sensor, HYSTERESIS,datatype_status);
        delay(500); //give time to temp sensors to initialize
      }  
    }
  }
  else {
    if (nbersensorpb>10){//in case more than 10 sensor pb in a row, switch off
      digitalWrite(DAMPEROPENPIN, LOW);
      digitalWrite(DAMPERCLOSEPIN, HIGH);
      ventstarttime=rtc.now().unixtime();
      digitalWrite(FANPIN, LOW);
      syststatus=0;
      WriteMsgSD(msg_stoptrouble,type_status);//"Stopping normal operations","status"); 
      logsd(array_sensor, HYSTERESIS,datatype_status);  
      delay(500); //give time to temp sensors to initialize

    }
  }
                 WriteMsgSD(msg5,type_status);

//switch of vent relay after 30s of last activation
if (ventstarttime!=0 && rtc.now().unixtime()-ventstarttime>30){
  digitalWrite(DAMPERCLOSEPIN, LOW);
  digitalWrite(DAMPEROPENPIN, LOW);
  ventstarttime=0;
}
                 WriteMsgSD(msg6,type_status);

//display values on LCD if needed
//TO DO: change cond to be on ButtonPressed and put the switch off in the function
//this would avoid having to wait for next loop before switching off
  noInterrupts();
  boolean ButtonPressed_temp=ButtonPressed;
  interrupts();

  if (!ButtonPressed_temp){
    if (lcdon){
      lcd.noBacklight();
      lcd.clear();
      lcdon = false; // could be in the lcdprintini
    }
  }
  else {
      lcd.backlight(); 
      lcd.clear();
      lcdprintvalue(array_sensor,HYSTERESIS);
  }
                 WriteMsgSD(msg7,type_status);
   
  // manage alarm
  noInterrupts();
  boolean alarmset_temp = alarmset;
  interrupts();

  if (!alarmset_temp){
    rtc.clearAlarm(1); // this and below cannnot be done in interrupt
    rtc.setAlarm1(timesetalarm, DS3231_A1_Second); // this mode triggers the alarm when the minutes match. See Doxygen for other options)
    noInterrupts();
    alarmset = true;
    interrupts();
    timesetalarm=timesetalarm+ ALARMSECONDS;
    timeforsaving++;  
                     WriteMsgSD(msg8,type_status);

  }

  wdt_disable();
                  WriteMsgSD(msg9,type_status);

  if (!lcdon && !writtingps){
              WriteMsgSD(msg_sleep,type_status);
              Serial.print(F("----------- going to sleep --------------- at "));Serial.println(rtc.now().unixtime());
              delay(500);


    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);   //arduino enters sleep mode here
  }
                  WriteMsgSD(msg10,type_status);
         
Serial.print(F("----------- waking up --------------- at "));Serial.println(rtc.now().unixtime());
              delay(500);

}

Any help much appreciated
Thanks in advance

An out of bounds index is often the cause of unpredictable program behavior.

 char tempstr[3];
 itoa(x,tempstr,10);

For example, tempstr[] can hold only two characters, plus the zero terminator. If "x" ever exceeds 99 decimal, your program will malfunction.

How much dynamic memory is left once that all compiles?

How about this?

//return byte 2 digits with leading 0 
char * convert2digits(byte x){
  char static xtrg[3];                      // static so the result is available outside but memory is never freed, still more readable than global var
  xtrg[0] = '0' + (x/10);
  xtrg[1] = '0' + (x%10);
  xtrg[2] = 0;
  return xtrg;
}

Or maybe this?

//return byte 2 digits with leading 0 
char * convert2digits(byte x){
  char static xtrg[3];                      // static so the result is available outside but memory is never freed, still more readable than global var
  byte tens = 0;
  byte ones = x;
  while (ones >= 10) {
    ones -= 10;
    tens++;
  }
  xtrg[0] = '0' + tens;
  xtrg[1] = '0' + ones;
  xtrg[2] = 0;
  return xtrg;
}

To debug, you could use a freemem() function call to monitor your available memory. Using Google, search term "freemem() lady Ada", I found and used one last week.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.