SD Card not writing files consistently.

Hi,

I am creating a programm in arduino that stores data from some weather station’s sensors to use them later by sending them to my server bia Wifi.

So, I chose to use an sd card reader with a 4GB (I also used other SDs) card which is formated with FAT32 and 4kb cluster size attached to my Arduino Mega 2560 (I have already formated it to work with this shield). Now, after a few tests and fixes I have a code that can save data to the SD by making new .txt files named as thet current time that gets from an rtc every 4sec.

However, when I intialize my Sd card and then my module starts making those files, it is unable for it to save them with the DATA consistently and for this reason I force it with an If to try again but it is very unreliable for me.

Could you please check my code and help me because is the first time for me using SD with Arduino.
Also, if there’s sth that i could change to my SD to help things out I would appreciate it!

If you want clariffications l am going to be 24/7 available!!!

Code:

//Libraries
#include <dht.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_SI1145.h>
#include "RTClib.h"

//Constants

//Temperature Sensor
#define DHT21_PIN 5     // DHT 21  (AM2301) - what pin we're connected to

//Cloud Sensor
#define cloudSensor_PIN A0

//Rain Meter
#define Rain_PIN 1

//Rain Sensor
#define RainSensor_PIN A1

//Wind Gauge
#define WindGauge_PIN 0

//Wind Vane
#define WindVane_PIN A2

//Dust Sensor
#define measurePin A6
#define ledPower 12

#define samplingTime 280
#define deltaTime 40
#define sleepTime 9680

//Sets
dht DHT;
Adafruit_BMP280 bme;
Adafruit_SI1145 uv = Adafruit_SI1145();
RTC_DS3231 rtc;
File myFile;

//Sensors' Variables
boolean FirstTimeDATA = true;
unsigned long DataCatch_DelayTick;
//Temperature Sensor
float hum;  //Stores humidity value
float temp; //Stores temperature value

//Atmospheric Pressure Sensor
float airpress;

//Cloud Sensor
int cloudata;

//Rain Meter
int RainPulses = 0;

//Rain Sensor
int rainDensity;

//Wind Gauge
int wPulses;

//Wind Vane
String WindDirection = "";

//Dust Sensor
bool dustFirstTime = true;
float voMeasured = 0;
float calcVoltage = 0; 
float dustDensity = 0;
long dustTimer = 0;

//UV Sensor
float UVindex;


//Main System
boolean tester;

//Save SD
const int chipSelect = 53;
boolean SD_begun;

//Sending data to: SerialPort

//1.Taking Temperature and Humidity from the sensor
boolean temphum()
{
    int chk = DHT.read21(DHT21_PIN);
    //Read data and store it to variables hum and temp
    hum = DHT.humidity;
    temp = DHT.temperature; 
   return true;
}


//5. Metering Rain 
void RainMeter(){
  RainPulses ++;
}

//6. Metering Wind Speed
void WindGauge(){ 
  wPulses++;
}


//7. Taking Wind Direction
boolean WindVane(){
 // Serial.println(analogRead(A2));
  if((analogRead(A2) > 780) && (analogRead(A2) < 793)){
    WindDirection = "N";
 }else if((analogRead(A2) > 400) && (analogRead(A2) < 413)){
    WindDirection = "NNE";
 }else if((analogRead(A2) > 455) && (analogRead(A2) < 466)){
    WindDirection = "NE";
 }else if((analogRead(A2) > 79) && (analogRead(A2) < 90)){
    WindDirection = "NEE";
 }else if((analogRead(A2) > 95) && (analogRead(A2) < 105)){
    WindDirection = "E";   
 }else if((analogRead(A2) > 61) && (analogRead(A2) < 75)){
    WindDirection = "SEE";  
 }else if((analogRead(A2) > 181) && (analogRead(A2) < 198)){
    WindDirection = "SE";
 }else if((analogRead(A2) > 124) && (analogRead(A2) < 140)){
    WindDirection = "SSE";
 }else if((analogRead(A2) > 285) && (analogRead(A2) < 305)){
    WindDirection = "S";
 }else if((analogRead(A2) > 244) && (analogRead(A2) < 260)){
    WindDirection = "SSW";
 }else if((analogRead(A2) > 625) && (analogRead(A2) < 636)){
    WindDirection = "SW";
 }else if((analogRead(A2) > 590) && (analogRead(A2) < 607)){
    WindDirection = "SWW";
 }else if((analogRead(A2) > 930) && (analogRead(A2) < 949)){
    WindDirection = "W";
 }else if((analogRead(A2) > 820) && (analogRead(A2) < 834)){
    WindDirection = "NWW";
 }else if((analogRead(A2) > 874) && (analogRead(A2) < 893)){
    WindDirection = "NW";
 }else if((analogRead(A2) > 700) && (analogRead(A2) < 711)){
    WindDirection = "NNW";
 }else{
   WindDirection = "Null";     
 }
 return true;
}

//8. Metering Dust Density
boolean dustSensor(){
  
 if(millis() - dustTimer > 32000){
    digitalWrite(9,LOW);
  
  digitalWrite(ledPower,LOW); // power on the LED
  delayMicroseconds(samplingTime);
 
  voMeasured = analogRead(measurePin); // read the dust value
 
  delayMicroseconds(deltaTime);
  digitalWrite(ledPower,HIGH); // turn the LED off
  delayMicroseconds(sleepTime);
 // digitalWrite(9,LOW);
  // 0 - 3.3V mapped to 0 - 1023 integer values
  // recover voltage
  calcVoltage = voMeasured * (3.3 / 1024);
  // linear eqaution taken from http://www.howmuchsnow.com/arduino/airquality/
  dustDensity = 1000 * 0.17 * calcVoltage ;
  dustTimer = millis();
 }else if(millis() - dustTimer > 28000){
    digitalWrite(9,HIGH);
 }
  return true;
}

boolean TestSData(String Data,String strfName){
  String SDData;
  char fileName[strfName.length()+1];
  strfName.toCharArray(fileName, strfName.length()+1);
    //Serial.println(fileName);
  myFile = SD.open(fileName); 
  while (myFile.available()){ 
     SDData +=(char) myFile.read();     
  }
   Serial.println("MyData "+Data);
   Serial.println("SDData "+SDData);
   SDData = SDData.substring(0, SDData.length() -2);
   myFile.close();
  return SDData.equals(Data);
}

boolean dataCollecting(){
   tester = temphum();
  //2. Taking Air Pressure sensor data
  airpress = bme.readPressure()/100 + 21;  
  //3. Taking Cloud Sensor results
  cloudata = analogRead(cloudSensor_PIN);
  //4. Metering Rain Density
  rainDensity = analogRead(A1);
  //7. Taking Wind Direction
  tester = WindVane();
  //8. Metering Dust Density
  tester = dustSensor();
  //9. UV Sensor
  UVindex = uv.readUV();
  UVindex /= 100.0;  
  return true;
}


void setup() {
 //Pin's se
 Serial.begin(9600);
 attachInterrupt(WindGauge_PIN ,WindGauge ,RISING);
 attachInterrupt(Rain_PIN ,RainMeter ,RISING); 
  pinMode(A0,INPUT);
  pinMode(A2,INPUT);
  pinMode(measurePin,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(ledPower,OUTPUT);
  pinMode(SS, OUTPUT);
  //Beginings
  bme.begin(0x76);
  if(!(SD.begin(chipSelect))){
    SD_begun = false;
  }else{
    SD_begun = true;
  }
  rtc.begin();
  uv.begin();
  Serial.println(SD_begun);
 //WIFI
  // initialize serial for ESP module
  Serial3.begin(9600);

}

void loop() { 
  if(FirstTimeDATA){
   dataCollecting(); 
   DataCatch_DelayTick = millis();
   FirstTimeDATA = false;
  }else if((millis() - DataCatch_DelayTick) > 4000){
    Serial.println("OK1");
    if(SD_begun){    
    back1:
    Serial.println("OK2");
    dataCollecting();
    DateTime now = rtc.now();    
    String DATA = ((String)temp+";"+hum+";"+airpress+";"+cloudata+";"+rainDensity+";"+RainPulses+";"+wPulses+";"+dustDensity+";"+UVindex+";"+(now.hour())+";"+(now.minute())+";"+(now.second())+";"+(now.day())+";"+(now.month())+";"+(now.year()));//18 parts            
    String fName = ((String)(now.day())+(now.hour())+(now.minute())+(now.second())+".txt");   
    char FileName[fName.length()+1];
     fName.toCharArray(FileName, fName.length()+1);
     
     myFile = SD.open(FileName, FILE_WRITE);\
    if(! myFile){
      SD.remove(FileName);
    }
     Serial.println(myFile.name());
     myFile.println(DATA);
     myFile.close();    
      tester = TestSData(DATA,FileName);
      if(tester){

      }else{
        SD.remove(FileName);
        Serial.println("SD fail 1");
        goto back1;
      }
          
    }else{
      Serial.println("TrySD");
      if(!(SD.begin(chipSelect))){
       SD_begun = false;
     }else{
       SD_begun = true;
     }
    }
    
    DataCatch_DelayTick = millis();
    wPulses = 0;
    RainPulses = 0;
  }
   //WiFi

}

This is a report on my serial port.

//Libraries
#include <dht.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_SI1145.h>
#include "RTClib.h"

//Constants

//Temperature Sensor
#define DHT21_PIN 5     // DHT 21  (AM2301) - what pin we're connected to

//Cloud Sensor
#define cloudSensor_PIN A0

//Rain Meter
#define Rain_PIN 1

//Rain Sensor
#define RainSensor_PIN A1

//Wind Gauge
#define WindGauge_PIN 0

//Wind Vane
#define WindVane_PIN A2

//Dust Sensor
#define measurePin A6
#define ledPower 12

#define samplingTime 280
#define deltaTime 40
#define sleepTime 9680

//Sets
dht DHT;
Adafruit_BMP280 bme;
Adafruit_SI1145 uv = Adafruit_SI1145();
RTC_DS3231 rtc;
File myFile;

//Sensors' Variables
boolean FirstTimeDATA = true;
unsigned long DataCatch_DelayTick;
//Temperature Sensor
float hum;  //Stores humidity value
float temp; //Stores temperature value

//Atmospheric Pressure Sensor
float airpress;

//Cloud Sensor
int cloudata;

//Rain Meter
int RainPulses = 0;

//Rain Sensor
int rainDensity;

//Wind Gauge
int wPulses;

//Wind Vane
String WindDirection = "";

//Dust Sensor
bool dustFirstTime = true;
float voMeasured = 0;
float calcVoltage = 0; 
float dustDensity = 0;
long dustTimer = 0;

//UV Sensor
float UVindex;


//Main System
boolean tester;

//Save SD
const int chipSelect = 53;
boolean SD_begun;

//Sending data to: SerialPort

//1.Taking Temperature and Humidity from the sensor
boolean temphum()
{
    int chk = DHT.read21(DHT21_PIN);
    //Read data and store it to variables hum and temp
    hum = DHT.humidity;
    temp = DHT.temperature; 
   return true;
}


//5. Metering Rain 
void RainMeter(){
  RainPulses ++;
}

//6. Metering Wind Speed
void WindGauge(){ 
  wPulses++;
}


//7. Taking Wind Direction
boolean WindVane(){
 // Serial.println(analogRead(A2));
  if((analogRead(A2) > 780) && (analogRead(A2) < 793)){
    WindDirection = "N";
 }else if((analogRead(A2) > 400) && (analogRead(A2) < 413)){
    WindDirection = "NNE";
 }else if((analogRead(A2) > 455) && (analogRead(A2) < 466)){
    WindDirection = "NE";
 }else if((analogRead(A2) > 79) && (analogRead(A2) < 90)){
    WindDirection = "NEE";
 }else if((analogRead(A2) > 95) && (analogRead(A2) < 105)){
    WindDirection = "E";   
 }else if((analogRead(A2) > 61) && (analogRead(A2) < 75)){
    WindDirection = "SEE";  
 }else if((analogRead(A2) > 181) && (analogRead(A2) < 198)){
    WindDirection = "SE";
 }else if((analogRead(A2) > 124) && (analogRead(A2) < 140)){
    WindDirection = "SSE";
 }else if((analogRead(A2) > 285) && (analogRead(A2) < 305)){
    WindDirection = "S";
 }else if((analogRead(A2) > 244) && (analogRead(A2) < 260)){
    WindDirection = "SSW";
 }else if((analogRead(A2) > 625) && (analogRead(A2) < 636)){
    WindDirection = "SW";
 }else if((analogRead(A2) > 590) && (analogRead(A2) < 607)){
    WindDirection = "SWW";
 }else if((analogRead(A2) > 930) && (analogRead(A2) < 949)){
    WindDirection = "W";
 }else if((analogRead(A2) > 820) && (analogRead(A2) < 834)){
    WindDirection = "NWW";
 }else if((analogRead(A2) > 874) && (analogRead(A2) < 893)){
    WindDirection = "NW";
 }else if((analogRead(A2) > 700) && (analogRead(A2) < 711)){
    WindDirection = "NNW";
 }else{
   WindDirection = "Null";     
 }
 return true;
}

//8. Metering Dust Density
boolean dustSensor(){
  
 if(millis() - dustTimer > 32000){
    digitalWrite(9,LOW);
  
  digitalWrite(ledPower,LOW); // power on the LED
  delayMicroseconds(samplingTime);
 
  voMeasured = analogRead(measurePin); // read the dust value
 
  delayMicroseconds(deltaTime);
  digitalWrite(ledPower,HIGH); // turn the LED off
  delayMicroseconds(sleepTime);
 // digitalWrite(9,LOW);
  // 0 - 3.3V mapped to 0 - 1023 integer values
  // recover voltage
  calcVoltage = voMeasured * (3.3 / 1024);
  // linear eqaution taken from http://www.howmuchsnow.com/arduino/airquality/
  dustDensity = 1000 * 0.17 * calcVoltage ;
  dustTimer = millis();
 }else if(millis() - dustTimer > 28000){
    digitalWrite(9,HIGH);
 }
  return true;
}

boolean TestSData(String Data,String strfName){
  String SDData;
  char fileName[strfName.length()+1];
  strfName.toCharArray(fileName, strfName.length()+1);
    //Serial.println(fileName);
  myFile = SD.open(fileName); 
  while (myFile.available()){ 
     SDData +=(char) myFile.read();     
  }
   Serial.println("MyData "+Data);
   Serial.println("SDData "+SDData);
   SDData = SDData.substring(0, SDData.length() -2);
   myFile.close();
  return SDData.equals(Data);
}

boolean dataCollecting(){
   tester = temphum();
  //2. Taking Air Pressure sensor data
  airpress = bme.readPressure()/100 + 21;  
  //3. Taking Cloud Sensor results
  cloudata = analogRead(cloudSensor_PIN);
  //4. Metering Rain Density
  rainDensity = analogRead(A1);
  //7. Taking Wind Direction
  tester = WindVane();
  //8. Metering Dust Density
  tester = dustSensor();
  //9. UV Sensor
  UVindex = uv.readUV();
  UVindex /= 100.0;  
  return true;
}


void setup() {
 //Pin's se
 Serial.begin(9600);
 attachInterrupt(WindGauge_PIN ,WindGauge ,RISING);
 attachInterrupt(Rain_PIN ,RainMeter ,RISING); 
  pinMode(A0,INPUT);
  pinMode(A2,INPUT);
  pinMode(measurePin,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(ledPower,OUTPUT);
  pinMode(SS, OUTPUT);
  //Beginings
  bme.begin(0x76);
  if(!(SD.begin(chipSelect))){
    SD_begun = false;
  }else{
    SD_begun = true;
  }
  rtc.begin();
  uv.begin();
  Serial.println(SD_begun);
 //WIFI
  // initialize serial for ESP module
  Serial3.begin(9600);

}

void loop() { 
  if(FirstTimeDATA){
   dataCollecting(); 
   DataCatch_DelayTick = millis();
   FirstTimeDATA = false;
  }else if((millis() - DataCatch_DelayTick) > 4000){
    Serial.println("OK1");
    if(SD_begun){    
    back1:
    Serial.println("OK2");
    dataCollecting();
    DateTime now = rtc.now();    
    String DATA = ((String)temp+";"+hum+";"+airpress+";"+cloudata+";"+rainDensity+";"+RainPulses+";"+wPulses+";"+dustDensity+";"+UVindex+";"+(now.hour())+";"+(now.minute())+";"+(now.second())+";"+(now.day())+";"+(now.month())+";"+(now.year()));//18 parts            
    String fName = ((String)(now.day())+(now.hour())+(now.minute())+(now.second())+".txt");   
    char FileName[fName.length()+1];
     fName.toCharArray(FileName, fName.length()+1);
     
     myFile = SD.open(FileName, FILE_WRITE);\
    if(! myFile){
      SD.remove(FileName);
    }
     Serial.println(myFile.name());
     myFile.println(DATA);
     myFile.close();    
      tester = TestSData(DATA,FileName);
      if(tester){

      }else{
        SD.remove(FileName);
        Serial.println("SD fail 1");
        goto back1;
      }
          
    }else{
      Serial.println("TrySD");
      if(!(SD.begin(chipSelect))){
       SD_begun = false;
     }else{
       SD_begun = true;
     }
    }
    
    DataCatch_DelayTick = millis();
    wPulses = 0;
    RainPulses = 0;
  }
   //WiFi

}

Have you read the second post in this forum about formatting?

No where is it?

I formated again with this sdformater but nothing changed

Your code seems overly complicated and definitely hard to read. You should need no more than the datalogging example included in the IDE. If Setup and Loop are hard to find, they are either missing or in the wrong place. If you get smarty-arsy with that, people won't bother to look. The String class is always a bad idea.

Ok my code is a bit of mess but Ithink it is easy to understand that I have almost the same things thatevery sd code has. What do you mean that String class is a bad idea?

orestis146:
I have almost the same things that every sd code has.

I guess, if it has almost the same things, it will almost work, and the bit that it hasn’t got is the bit that kills it.

Strings are badly handled by micro like Arduino, and clog up the memory. There is a raft of information on this by people who explain it better than I do.

and there are bound to be recent threads on this forum.