arduino-uno

Error while writing file to SD in Arduino Temperature logging station


I try to write a Temperature Logging station using a RTC 1307 and timestamping my measurements. The issue is at the beginning, creating the filename:

#include <dht_nonblocking.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11

#include <LiquidCrystal.h>
#include <SD.h>
#include <Wire.h>
#include <DS1307RTC.h>

#define DATA_DIR "Temperature_Logs"
#define RECORD_FILE_EXT ".CSV"

static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_Sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);

int tempPin = 0; // Thermistor Pin

// LCD Display pins
//                BS  E  D4  D5  D6  D7
LiquidCrystal lcd(3, 4, 5, 6, 7, 8);

const int chipSelect = 9; // Set the chip select pin for the SD card
File logFile; // Create a file object

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);

  Serial.println("Wait 1000ms to boot SD");
  delay(1000);

  // Initialize SD card
  if (!SD.begin(chipSelect)) { 
    Serial.println("SD Initialization failed!");
    while (1); // Halt
  }
  else {
    Serial.println("SD card initialized");
  }

  // Initialize RTC
  Serial.print("Initializing RTC...");
  setSyncProvider(RTC.get);
  if (timeStatus()!= timeSet) { // Check if the time is set
    Serial.println("Unable to sync with the RTC");
    while (1); // Halt
  }
  Serial.println("RTC is running.");

  // Create filename with current date
  tmElements_t currentTime;
  breakTime(now(), currentTime);
  String LogFileDir = "/" + String(DATA_DIR) + "/" +
                      String(currentTime.Year + 1970) + "-" + 
                      String(currentTime.Month, DEC) + "-" + 
                      String(currentTime.Day, DEC) + "_TemperatureLog" +
                      RECORD_FILE_EXT;

  Serial.println("Date: " + String(currentTime.Year + 1970)) + "_" + String(currentTime.Month) + "_" + String(currentTime.Day);
  Serial.println("LogFileDir: " + LogFileDir); // **Added for troubleshooting**

  if (SD.mkdir(DATA_DIR)) {
    Serial.println("Directory created");
  } else {
    Serial.println("Directory already exists");
  }

  // Verify SD card and file system
if (SD.exists(DATA_DIR)) {
  Serial.println("Directory exists");
} else {
  Serial.println("Directory not found");
}

  logFile = SD.open(LogFileDir, FILE_WRITE); // Open the log file
  if (logFile) {
    logFile.println("Timestamp, Temperature Thermistor (°C), Temperature DHT11 (°C), Humidity DHT11 (%)");
    Serial.print("Write header: ");
    Serial.println("Timestamp, Temperature Thermistor (°C), Temperature DHT11 (°C), Humidity DHT11 (%)");
    // Keep the file open for continuous writing
  } else {
    Serial.print("Error opening log file: ");
    Serial.println(LogFileDir);
    while (1); // Halt
  }
}

void logMeasurement(time_t t, float tempC, float temperature, float humidity) {
  tmElements_t currentTime;
  breakTime(t, currentTime);
  
  if (logFile) {
    String dataString = 
      String(currentTime.Year + 1970) + "-" + 
      String(currentTime.Month, DEC) + "-" + 
      String(currentTime.Day, DEC) + " " + 
      String(currentTime.Hour, DEC) + ":" + 
      String(currentTime.Minute, DEC) + ":" + 
      String(currentTime.Second, DEC) + "," + 
      String(tempC) + "," + 
      String(temperature) + "," + 
      String(humidity) + "\n";
    Serial.print("Datastring: ");
    Serial.println(dataString);
    logFile.println(dataString); // Using println to ensure newline
  } else {
    Serial.println("Error: Log file not accessible during measurement.");
  }
}

static bool measurement_environment(float *temperature, float *humidity) {
  static unsigned long measurement_timestamp = millis();

  /* Measure once every 10 seconds */
  if (millis() - measurement_timestamp > 10000ul) {
    if (dht_Sensor.measure(temperature, humidity) == true) {
      measurement_timestamp = millis();
      return (true);
    }
  }
  return (false);
}

void loop() {
  // Thermistor
  int tempReading = analogRead(tempPin);
  double tempK = log(10000.0 * ((1024.0 / tempReading - 1)));
  tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK)) * tempK); // Temp Kelvin
  float tempC = tempK - 273.15;
  float tempF = (tempC * 9.0) / 5.0 + 32.0; // Convert Celcius to Fahrenheit

  // DHT11
  float temperature;
  float humidity;
  if (measurement_environment(&temperature, &humidity) == true) {

    // Print to terminal with RTC timestamp
    time_t t = now();
    tmElements_t currentTime;
    breakTime(t, currentTime);
    Serial.print(currentTime.Year + 1970, DEC);
    Serial.print("-");
    Serial.print(currentTime.Month, DEC);
    Serial.print("-");
    Serial.print(currentTime.Day, DEC);
    Serial.print(" ");
    Serial.print(currentTime.Hour, DEC);
    Serial.print(":");
    if (currentTime.Minute < 10) Serial.print('0'); // leading zero
    Serial.print(currentTime.Minute, DEC);
    Serial.print(":");
    if (currentTime.Second < 10) Serial.print('0'); // leading zero
    Serial.print(currentTime.Second, DEC);
    Serial.print(" - DHT11 ");
    Serial.print(temperature, 1);
    Serial.print(" C, ");
    Serial.print(humidity, 1);
    Serial.print(" %; Therm ");
    Serial.print(tempC);
    Serial.print(" C, ");
    Serial.print(tempF);
    Serial.print(" F");

    // Display in LCD
    // Thermistor
    lcd.setCursor(0,0);
    lcd.print("Therm        C  ");
    lcd.setCursor(7,0);
    lcd.print(tempC);

    // DHT11
    lcd.setCursor(0,1);
    lcd.print("DH11     C     %");
    lcd.setCursor(5, 1);
    lcd.print(temperature,1);

    // Humidity
    lcd.setCursor(11,1);
    lcd.print(humidity,1);

    delay(500);
    // Log the measurement
    logMeasurement(now(), tempC, temperature, humidity);
  }
}

I've added outputs for the serial monitor to monitor what is going wrong: it seems to be the creation of the filename:

21:41:13.328 -> Wait 1000ms to boot SD

21:41:14.341 -> SD card initialized

21:41:14.342 -> Initializing RTC...RTC is running.

21:41:14.373 ->

21:41:14.373 ->

21:41:14.404 -> Directory already exists

21:41:14.404 -> Directory not found

21:41:14.437 -> Error opening log file:

I've tried using AI to figure out the problem (Nemotron via HuggingFace) but it does not seem to find an issue with the code and now hallucinates a colleague named "miranda" who I should ask and gives me an agenda to talk to her.

Wiring should not be an issue since I tested the exact same wiring for SD card module with another program that just writes random data to a file on the SD card. This works fine and therefore should also disqualify any card formatting/power/hw issues


Solution

  • It seems that RTC battery is empty. Need to replace it. I assumed that initialization of RTC would throw an error in this case. But apparently, RTC init can be succesful while RTC battery is empty. String for LogFileDirtherefore is not generated properly causing the error