Memory corruption while filling string to write to sd card?

Hi, we have made an automated greenhouse with temperature / humidity checking and datalogging.

This is the serial output

Initializing SD card...card initialized.
Ready
H= 24.0%  T= 24.0C  
,1023¬711
1,1023,701,10,1
H= 23.0%  T= 25.0C

This is the code.
NOTE: The commented out code for filling the dataString works fine, but my code doesn’t. I have no idea why.

 // make a string for assembling the data to log:
  String dataString = "";

  /* read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ","; 
    }
  }
  */
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  
  dataString += "M= ";
  dataString+= String((analogRead(0) / 10), DEC) ;
  dataString += "% ";
  
  dataString = "";
  dataString += "H= " ;
  dataString += String(int((dht11_dat[0]))) ;
  dataString += ".";
  dataString += String((dht11_dat[1])) ;
  dataString += ("%  ") ;
  
  dataString = "";
  dataString += "T= " ;
  dataString += String((dht11_dat[2])) ;
  dataString += "." ;
  dataString += String((dht11_dat[3])) ;
  dataString += "C  ";
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
  dataString = "";
 
}

This is the full program:

#define DHT11_PIN 1      // ADC0
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); 
#include <SD.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 10;

byte read_dht11_dat()
{
  byte i = 0;
  byte result=0;
  for(i=0; i< 8; i++)
  {
    while(!(PINC & _BV(DHT11_PIN)));  // wait for 50us
    delayMicroseconds(30);
    if(PINC & _BV(DHT11_PIN)) 
      result |=(1<<(7-i));
    while((PINC & _BV(DHT11_PIN)));  // wait '1' finish
    }
    return result;
}


void setup()
{
  
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  
  lcd.init();                      
 
  
  lcd.backlight();
  DDRC |= _BV(DHT11_PIN);
  PORTC |= _BV(DHT11_PIN);
  Serial.begin(9600);
  Serial.println("Ready");
}
	
void loop()
{
  
  

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  

  if (analogRead(0) < 300)
 { 
  lcd.clear(); 
  lcd.print("Water Nodig!");
  
  delay(1500);
  lcd.clear();
 }
 

  lcd.print("M=");
  lcd.print(analogRead(0));
 
  byte dht11_dat[5];
  byte dht11_in;
  byte i;// start condition
	 // 1. pull-down i/o pin from 18ms
  PORTC &= ~_BV(DHT11_PIN);
  delay(18);
  PORTC |= _BV(DHT11_PIN);
  delayMicroseconds(40);
  DDRC &= ~_BV(DHT11_PIN);
  delayMicroseconds(40);
  
  dht11_in = PINC & _BV(DHT11_PIN);
  
  delayMicroseconds(80);
  dht11_in = PINC & _BV(DHT11_PIN);
  
  
  delayMicroseconds(80);// now ready for data reception
  for (i=0; i<5; i++)
    dht11_dat[i] = read_dht11_dat();
  DDRC |= _BV(DHT11_PIN);
  PORTC |= _BV(DHT11_PIN);
  
  
  
  Serial.print("H= ");
  Serial.print(dht11_dat[0], DEC);
  Serial.print(".");
  Serial.print(dht11_dat[1], DEC);
  Serial.print("%  ");
  Serial.print("T= ");
  Serial.print(dht11_dat[2], DEC);
  Serial.print(".");
  Serial.print(dht11_dat[3], DEC);
  Serial.println("C  ");
  lcd.setCursor(8, 0);
  lcd.print("H= ");
  lcd.print(dht11_dat[0], DEC);
  lcd.print(".");
  lcd.print(dht11_dat[1], DEC);
  lcd.print("%  ");
  
  lcd.setCursor(0, 1);
  lcd.print("T= ");
  lcd.print(dht11_dat[2], DEC);
  lcd.print(".");
  lcd.print(dht11_dat[3], DEC);
  lcd.print("C  ");
  delay(5000);
  lcd.setCursor(0,0);
  
  // make a string for assembling the data to log:
  String dataString = "";

  /* read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ","; 
    }
  }
  */
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  
  dataString += "M= ";
  dataString+= String((analogRead(0) / 10), DEC) ;
  dataString += "% ";
  
  dataString = "";
  dataString += "H= " ;
  dataString += String(int((dht11_dat[0]))) ;
  dataString += ".";
  dataString += String((dht11_dat[1])) ;
  dataString += ("%  ") ;
  
  dataString = "";
  dataString += "T= " ;
  dataString += String((dht11_dat[2])) ;
  dataString += "." ;
  dataString += String((dht11_dat[3])) ;
  dataString += "C  ";
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
  dataString = "";
 
}
  String dataString = "";

Well, there's your problem right there.

The String class is the number one cause for memory corruption. And the number of contatenations you are doing can only make things worse.

I would recommend scrapping the String class and sticking purely to C strings (null-terminated character arrays).

Please note that in versions of the IDE up to and including 1.0.3, the String library has bugs as discussed here and here.

In particular, the dynamic memory allocation used by the String class may fail and cause random crashes.

I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.), as described here for example.

Alternatively, install the fix described here: Fixing String Crashes

Preferably upgrade your IDE to version 1.0.4 or above at: http://arduino.cc/en/Main/Software