[SOLVED] Freeze after 20-90 minutes when using serial communication

/*******************************
 ** SOLAR BATTERY CONTROLLING **
 ******************************/
void checkSolarBatteryStatus()
{
  // Retrieve battery state by measuring
  // corresponding input pin (maximum
  // value is 1024 which means that whole
  // reference voltage of 5 volts is applied)
  int nBatteryVoltage = analogRead(1);
  // Output battery voltage,
  // state of switching relay on
  // controlling pin (4) as well as
  // actual time to serial monitor
  // (not required for regular operation)
  /*
  Serial.print("Current time: ");
  Serial.print(now.year(), DEC);
  Serial.print(now.month(), DEC);
  Serial.print(now.day(), DEC);
  Serial.print(now.hour(), DEC);
  Serial.print(now.minute(), DEC);
  Serial.print(now.second(), DEC);
  Serial.print(" / ");
  Serial.print("Battery voltage: ");
  Serial.print(nBatteryVoltage, DEC);
  Serial.print(" -- Solar circuit voltage: ");
  Serial.print(nSolarCircuitVoltage, DEC);
  Serial.print(" -- Relay state: ");
  Serial.println((bSolarCircuitState ? "ON" : "OFF"));
  */
  
  // If battery is fully charged,
  // solar system circuit is currently OFF
  // (650 counts equals to 13.73 V)
  // and no external control commands were applied
  if (!bSolarCircuitState && cExternalControl != 'n' && (nBatteryVoltage > 650 || cExternalControl == '1' || cExternalControl == 'y'))
  {
    // Increase counter if not triggered externally
    // (to avoid unwanted triggering by short interferences)
    nSolarSystemCheckSecurityHighVoltage++;
    if (nSolarSystemCheckSecurityHighVoltage > 10 || cExternalControl == '1' || cExternalControl == 'y')
    {
      // Trigger current switching relay
      // to turn solar system circuit ON
      digitalWrite(4, HIGH);
      // Setup variables for a wait loop (see below)
      // to allow for switching relay operation
      bSolarRelayActive = true;
      nWaitCyclesUntilSolarRelayReset = 2;
    }
  }
  else
  {
    // Reset counter which avoids triggering via 
    // temporary external interferences
    nSolarSystemCheckSecurityHighVoltage = 0;
  }
  
  // If battery is depleted,
  // solar system circuit is currently ON
  // (613 counts equals to 12.94 V)
  // and no external control commands were applied
  if(bSolarCircuitState && cExternalControl != 'y' && (nBatteryVoltage < 613 || cExternalControl == '0' || cExternalControl == 'n'))
  {
    // Increase counter if not triggered externally
    // (to avoid unwanted triggering by short interferences)
    nSolarSystemCheckSecurityLowVoltage++;
    if (nSolarSystemCheckSecurityLowVoltage > 10 || cExternalControl == '0' || cExternalControl == 'n')
    {
      // Trigger current switching relay
      // to turn solar system circuit OFF
      digitalWrite(4, HIGH);
      // Setup variables for a wait loop (see below)
      // to allow for switching relay operation
      bSolarRelayActive = true;
      nWaitCyclesUntilSolarRelayReset = 2;
    }
  }
  else
  {
    // Reset counter which avoids triggering via 
    // temporary external interferences
    nSolarSystemCheckSecurityLowVoltage = 0;
  }
  
  // Decrement relay activation wait counter
  // (as whole function is called only once a second
  // this means 2 seconds of relay activity)
  if (bSolarRelayActive && nWaitCyclesUntilSolarRelayReset > 0)
  {
    nWaitCyclesUntilSolarRelayReset--;
  }
  
  // Deactivate solar circuit switching relay
  if (bSolarRelayActive && nWaitCyclesUntilSolarRelayReset == 0)
  {
    digitalWrite(4, LOW);
    bSolarRelayActive = false;
  }
  
  // Reset external control request flag
  // in case of SOFT toggling or clearing request
  if (cExternalControl != 'y' && cExternalControl != 'n')
  {
    cExternalControl = ' ';
  }
}


/******************************
 ** BMS SERIAL COMMUNICATION **
 ******************************/
void readBMSData()
{ 
  while (BMS.available() > 0)
  {
    // Read data from battery monitoring system
    cBMSSerialChar = BMS.read();
    
    // If carriage return character received
    // and value of a certain property is next
    // data block to expect
    if (cBMSSerialChar == '\r' && bValueNext)
    {
      // Store battery information provided by
      // BMS in floats corresponding to properties
      if (sPropertyBuffer == "V")
        fVolts = atof(aValueBuffer) / 1000;
      else if (sPropertyBuffer == "I")
        fAmps = atof(aValueBuffer) / 1000;
      else if (sPropertyBuffer == "SOC")
        fSOC = atof(aValueBuffer) / 10;
      else if (sPropertyBuffer == "H4")
        nCycles = atoi(aValueBuffer);
      else if (sPropertyBuffer == "H6")
        fTotalAh = atof(aValueBuffer) / 1000;
      else if (sPropertyBuffer == "H9")
        fDaysSinceLastSync = atof(aValueBuffer) / 86400;
      
      // Clear buffer values
      sPropertyBuffer = "";
      for (int i = 0; i <= 8; i++)
        aValueBuffer[i] = ' ';
      iValueBufferIndex = 0;
    }
    // In case of a newline character
    // next data block will contain a property
    else if (cBMSSerialChar == '\n')
    {
      bPropertyNext = true;
      bValueNext = false;
    }
    // In case of a tabulator character
    // next data block will contain a value
    // (of the property transmitted before)
    else if (cBMSSerialChar == '\t' && bPropertyNext)
    {
      bPropertyNext = false;
      bValueNext = true;
    }
    // Store incoming property characters
    // in corresponding string
    else if (bPropertyNext)
    {
      sPropertyBuffer.concat(cBMSSerialChar);
    }
    // Store incoming value characters
    // in corresponding char array
    // (in order to be able to transform it
    // to a floating point number by 'atof')
    else if (bValueNext)
    {
      aValueBuffer[iValueBufferIndex] = cBMSSerialChar;
      iValueBufferIndex++;
    }
  }
}


/************************************
 ** SEND BMS DATA TO SERIAL OUTPUT **
 ***********************************/
void sendBMSData()
{
  // Output board online timer
  // (time since last reset)
  Serial.print(nBoardOnlineTimer);
  Serial.print(";");
  // Output all battery data
  Serial.print(fVolts,3);
  Serial.print(";");
  Serial.print(fAmps,3);
  Serial.print(";");
  Serial.print(fSOC,1);
  Serial.print(";");
  Serial.print(nCycles);
  Serial.print(";");
  Serial.print(fTotalAh,3);
  Serial.print(";");
  Serial.print(fDaysSinceLastSync,2);
  Serial.print(";");
  // Append current state of solar power circuit
  // as well as external control flag
  Serial.print(bSolarCircuitState);
  Serial.print(";");
  Serial.println(cExternalControl);
}


/*********************************
 ** LOG BMS VALUES (EVERY HOUR) **
 ********************************/
void logBMSValues()
{
  // Output important BMS values
  // to serial monitor
  // (not required for regular operation)
  /*
  Serial.print(fVolts,3);
  Serial.print(" V - ");
  Serial.print(fAmps,3);
  Serial.print(" A - ");
  Serial.print(fSOC,1);
  Serial.print(" % - Cycles: ");
  Serial.print(nCycles);
  Serial.print(" - Discharge: ");
  Serial.print(fTotalAh,3);
  Serial.print(" - Last sync: ");
  Serial.print(fDaysSinceLastSync,2);
  Serial.print(" - Time: ");
  Serial.print(oLogTimestamp.year(), DEC);
  Serial.print("/");
  Serial.print(oLogTimestamp.month(), DEC);
  Serial.print("/");
  Serial.print(oLogTimestamp.day(), DEC);
  Serial.print(" ");
  Serial.print(oLogTimestamp.hour(), DEC);
  Serial.print(":");
  Serial.print(oLogTimestamp.minute(), DEC);
  Serial.print(":");
  Serial.println(oLogTimestamp.second(), DEC);
  */

  // Generate filename dynamically
  // so each year a new file gets
  // created
  // (e.g. log of 2013 = ARCHIVE3.CSV)
  char filenameBMSLogYear[] = "BMS/ARCHIVE0.CSV";
  filenameBMSLogYear[11] = oLogTimestamp.year()%10 + '0';
  
  // Open file if SD card is present
  // and write date as well as the current 
  // BMS dataset (6 variables) to it
  if (bSDCardInitialized)
  {
    // Set green LED on
    digitalWrite(3, HIGH);
    
    File logfileBMS = SD.open(filenameBMSLogYear, FILE_WRITE);
    
    logfileBMS.print(oLogTimestamp.year(), DEC);
    logfileBMS.print("/");
    logfileBMS.print(oLogTimestamp.month(), DEC);
    logfileBMS.print("/");
    logfileBMS.print(oLogTimestamp.day(), DEC);
    logfileBMS.print(" ");
    logfileBMS.print(oLogTimestamp.hour(), DEC);
    logfileBMS.print(":");
    logfileBMS.print(oLogTimestamp.minute(), DEC);
    logfileBMS.print(":");
    logfileBMS.print(oLogTimestamp.second(), DEC);
    logfileBMS.print(";");
    logfileBMS.print(fVolts,3);
    logfileBMS.print(";");
    logfileBMS.print(fAmps,3);
    logfileBMS.print(";");
    logfileBMS.print(fSOC,1);
    logfileBMS.print(";");
    logfileBMS.print(nCycles);
    logfileBMS.print(";");
    logfileBMS.print(fTotalAh,3);
    logfileBMS.print(";");
    logfileBMS.print(fDaysSinceLastSync,2);
    // Finish dataset with newline
    // command and close the file
    // (writes buffer to SD card)
    logfileBMS.println();
    logfileBMS.close();
    
    // Set green LED off
    digitalWrite(3, LOW);
  }
}