Inconsistent SD saving

I'm using a micro SD for a sensor, and I'm recording the data for an hour. Sometimes the data saves, and sometimes it doesn't, with no changes to the code or hardware. Is there any way I can fix this? It's really annoying. I'm using a DFRobot MicroSD Card Module For Arduino, and a few other sensors. It always recognises the SD card as well, but I'll check afterwards and its just an empty file sometimes.

#include <Arduino.h>
#include <SensirionI2CSen5x.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <dht.h>

LiquidCrystal_I2C lcd(0x27,20,4);
File myFile;
const int chipselect = 4;

dht DHT;
#define DHT11_PIN 7

// The used commands use up to 48 bytes. On some Arduino's the default buffer
// space is not large enough
#define MAXBUF_REQUIREMENT 48

#if (defined(I2C_BUFFER_LENGTH) &&                 \
     (I2C_BUFFER_LENGTH >= MAXBUF_REQUIREMENT)) || \
    (defined(BUFFER_LENGTH) && BUFFER_LENGTH >= MAXBUF_REQUIREMENT)
#define USE_PRODUCT_INFO
#endif
int timer=0;

SensirionI2CSen5x sen5x;
float massConcentrationPm1p0;
float massConcentrationPm2p5;
float massConcentrationPm4p0;
float massConcentrationPm10p0;
float ambientHumidity;
float ambientTemperature;
float vocIndex;
float noxIndex;

void setup() {
    lcd.init();
    lcd.backlight();
    Serial.begin(115200);
    while (!Serial) {
        delay(100);
    }
    lcd.clear();
    if (SD.begin(chipselect)){
      lcd.println("SD card accepted");
    }else{
      lcd.println("SD card missing or rejected");
      while(1);
    }
    delay(1000);
    lcd.clear();
    myFile =SD.open("RESULTS.TXT", FILE_WRITE);
    if (myFile){
      lcd.print("Wrting headers to csv");
      myFile.println("\n------------------NEW TEST-----------------");
      myFile.print("pm1,pm2.5,pm4,pm10,temp,humid\n");
    }else{
      lcd.print("Error opening csv");
    }
    delay(1000);
    Wire.begin();

    sen5x.begin(Wire);
    sen5x.deviceReset();
    sen5x.setTemperatureOffsetSimple(0);
    // Start Measurement
    sen5x.startMeasurement();
}

void loop() {
    delay(1000);
    timer++;

    if (timer<=3600){
    // Read Measurement
      sen5x.readMeasuredValues(
          massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
          massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
          noxIndex);
      int chk =DHT.read11(DHT11_PIN);
      String temp=String(massConcentrationPm1p0)+","+String(massConcentrationPm2p5)+","+String(massConcentrationPm4p0)+","+String(massConcentrationPm10p0)+","+String(DHT.temperature)+","+String(DHT.humidity)+"\n";
      myFile.print(temp);

      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("PM1:");
      lcd.setCursor(9,0);
      lcd.print("PM25:");
      lcd.setCursor(0,1);
      lcd.print("PM4:");
      lcd.setCursor(9,1);
      lcd.print("PM10:");
      lcd.setCursor(0,2);
      lcd.print("Temp:");
      lcd.setCursor(11,2);
      lcd.print("Hum.:");
      lcd.setCursor(4,0);
      lcd.print(String(massConcentrationPm1p0));
      lcd.setCursor(14,0);
      lcd.print(String(massConcentrationPm2p5));
      lcd.setCursor(4,1);
      lcd.print(String(massConcentrationPm4p0));
      lcd.setCursor(13,1);
      lcd.print(String(massConcentrationPm10p0));
      lcd.setCursor(5,2);
      lcd.print(DHT.temperature);
      lcd.setCursor(16,2);
      lcd.print(DHT.humidity);
      lcd.setCursor(0,3);
      lcd.print("Datapoint:");
      lcd.print(timer);
    }else{
      myFile.close();
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.println("Please eject");
      lcd.setCursor(1,0);
      lcd.println("the SD Card");
      lcd.println("Experiment complete!");
      delay(1000000);
    }
    }

The most obvious piece of advice I would give you is to avoid using the String data type if you are using a microcontroller with limited amounts of RAM.

Try using ordinary c strings instead. You can use the sprintf function to do formatted print to a small char buffer before printing to a file.

Which Arduino are you using? Especially on AVR-based MCUs Uno, Mega and similar), use of String objects leads to memory problems and program crashes.

This:

      String temp=String(massConcentrationPm1p0)+","+String(massConcentrationPm2p5)+","+String(massConcentrationPm4p0)+","+String(massConcentrationPm10p0)+","+String(DHT.temperature)+","+String(DHT.humidity)+"\n";
      myFile.print(temp);

Should be replaced with the following, and your program will be smaller and faster:

myFile.print(massConcentrationPm1p0);
myFile.print(",");
myFile.print(massConcentrationPm2p5);
myFile.print(",");
// .etc

By the way, it is a common observation that with Arduino, data storage on SD cards is problematic and error prone, compared to implementations on other platforms, like Raspberry Pi.

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