SD data logger SD.open() fails

Hi everyone,

Arduino drives me a bit crazy these days. I have built a thing which can measure temperature, humidity of air and of soil and air pressure. I added a I2C Display and it connects via wifi to my router to catch time via NTP. It works fine. I wanted to add a data logger function for my measurements to save them to a SD-card. The simple Arduino example sketch works fine to me. However my own sketch works too, but nothing was saved to my SD-card and it says: “error opening datalog.txt”. So this means the “SD.open” function fails. But why?

#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <SD.h>
#include <DHT.h>
#include <Wire.h>
//Pressure Sensor
#include <Adafruit_BMP085.h>
#include <WiFi101.h>
#include “arduino_secrets.h”
//modified library
#include <NTPClient.h>
#include <WiFiUdp.h>

#define DHTPIN 8
#define DHTTYPE DHT22
#define SHUMSENSOR A0

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x3F, 20, 4);
Adafruit_BMP085 bmp;
WiFiClient Client;

const int chipSelect = 4;
int status = WL_IDLE_STATUS;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

void setup() {
bmp.begin();
dht.begin();
Serial.begin(9600);
lcd.init();
lcd.backlight();
analogReadResolution(12);
while(status != WL_CONNECTED) {
Serial.print("Verbinde zu SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
Serial.println(“Verbunden!”);

timeClient.begin();
// Set offset time in seconds to adjust for your timezone, for example:
// GMT +1 = 3600
// GMT +8 = 28800
// GMT -1 = -3600
// GMT 0 = 0
timeClient.setTimeOffset(7200);

while (!Serial);
Serial.print(“Initializing SD card…”);
if (!SD.begin(chipSelect)) {
Serial.println(“initialization failed. Things to check:”);
Serial.println(“1. is a card inserted?”);
Serial.println(“2. is your wiring correct?”);
Serial.println(“3. did you change the chipSelect pin to match your shield or module?”);
Serial.println(“Note: press reset or reopen this serial monitor after fixing your issue!”);
while (true);
}
Serial.println(“initialization done.”);
}

void loop() {
delay(2000);
//functions for LCD
readTempHum();
readPress();
readSHum();
writeSD();

while(!timeClient.update()) {
timeClient.forceUpdate();
}

Serial.print(timeClient.getFormattedDate());
Serial.print(", “);
Serial.print(timeClient.getFormattedTime());
Serial.print(”, “);
Serial.print(dht.readTemperature(), 1);
Serial.print(” °C, “);
Serial.print(dht.readHumidity(), 1);
Serial.print(” hPa, ");
Serial.println(analogRead(SHUMSENSOR));
}

void readTempHum() {
lcd.setCursor(0, 0);
lcd.print("Temperatur: ");
lcd.setCursor(0, 1);
lcd.print(“Luftfeuchte: “);
lcd.setCursor(13, 0);
lcd.print(dht.readTemperature(), 1);
lcd.setCursor(18, 0);
lcd.write(0xDF);
lcd.print(“C”);
lcd.setCursor(13, 1);
lcd.print(dht.readHumidity(), 1);
lcd.setCursor(17, 1);
lcd.print(”%”);
}

void readPress() {
lcd.setCursor(0, 2);
lcd.print(“Luftdruck: “);
lcd.setCursor(13, 2);
lcd.print(bmp.readPressure() / 100);
lcd.print(” hPa”);
}

void readSHum() {
lcd.setCursor(0, 3);
lcd.print("Bodenfeuchte: ");
lcd.setCursor(14, 3);
int bodenFeuchte = analogRead(SHUMSENSOR);
lcd.print(bodenFeuchte);
}

void writeSD() {
File dataFile = SD.open(“datalog.txt”, FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.print(timeClient.getFormattedDate());
dataFile.print(", “);
dataFile.print(timeClient.getFormattedTime());
dataFile.print(”, “);
dataFile.print(dht.readTemperature(), 1);
dataFile.print(” °C, “);
dataFile.print(dht.readHumidity(), 1);
dataFile.print(” hPa, ");
dataFile.println(analogRead(SHUMSENSOR));
dataFile.close();
}
// if the file isn’t open, pop up an error:
else {
Serial.println(“error opening datalog.txt”);
}
}

Here a nicer view: #include <LiquidCrystal_I2C.h>#include <SPI.h>#include <SD.h>#include <DHT - Pastebin.com

Please help me, I tried many things, but nothing worked. :pleading_face:

The easier you make it to read and copy the code the more likely it is that you will get help

Please follow the advice given in the link below when posting code

Try changing

"datalog.txt"

to

"/datalog.txt"
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <SD.h>
#include <DHT.h>
#include <Wire.h>
//Pressure Sensor
#include <Adafruit_BMP085.h>
#include <WiFi101.h>
#include "arduino_secrets.h"
//modified library
#include <NTPClient.h>
#include <WiFiUdp.h>

#define DHTPIN 8
#define DHTTYPE DHT22
#define SHUMSENSOR A0

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x3F, 20, 4);
Adafruit_BMP085 bmp;
WiFiClient Client;

const int chipSelect = 4;
int status = WL_IDLE_STATUS;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

void setup() {
  bmp.begin();
  dht.begin();
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  analogReadResolution(12);
  while(status != WL_CONNECTED) {
    Serial.print("Verbinde zu SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
    delay(10000);
  }
  Serial.println("Verbunden!");

  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(7200);

  while (!Serial);
    Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("1. is a card inserted?");
    Serial.println("2. is your wiring correct?");
    Serial.println("3. did you change the chipSelect pin to match your shield or module?");
    Serial.println("Note: press reset or reopen this serial monitor after fixing your issue!");
    while (true);
  }
  Serial.println("initialization done.");
}

void loop() {
  delay(2000);
  //functions for LCD
  readTempHum();
  readPress();
  readSHum();
  writeSD();
  
  while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
  
  Serial.print(timeClient.getFormattedDate());
  Serial.print(", ");
  Serial.print(timeClient.getFormattedTime());
  Serial.print(", ");
  Serial.print(dht.readTemperature(), 1);
  Serial.print(" °C, ");
  Serial.print(dht.readHumidity(), 1);
  Serial.print(" hPa, ");
  Serial.println(analogRead(SHUMSENSOR));
}

void readTempHum() {
  lcd.setCursor(0, 0);
  lcd.print("Temperatur: ");
  lcd.setCursor(0, 1);
  lcd.print("Luftfeuchte: ");
  lcd.setCursor(13, 0);
  lcd.print(dht.readTemperature(), 1);
  lcd.setCursor(18, 0);
  lcd.write(0xDF);
  lcd.print("C");
  lcd.setCursor(13, 1);
  lcd.print(dht.readHumidity(), 1);
  lcd.setCursor(17, 1);
  lcd.print("%"); 
}

void readPress() {
  lcd.setCursor(0, 2);
  lcd.print("Luftdruck: ");
  lcd.setCursor(13, 2);
  lcd.print(bmp.readPressure() / 100);
  lcd.print(" hPa");
}

void readSHum() {
  lcd.setCursor(0, 3);
  lcd.print("Bodenfeuchte: ");
  lcd.setCursor(14, 3);
  int bodenFeuchte = analogRead(SHUMSENSOR);
  lcd.print(bodenFeuchte); 
}

void writeSD() {
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  // if the file is available, write to it:
  if (dataFile) {
    dataFile.print(timeClient.getFormattedDate());
    dataFile.print(", ");
    dataFile.print(timeClient.getFormattedTime());
    dataFile.print(", ");
    dataFile.print(dht.readTemperature(), 1);
    dataFile.print(" °C, ");
    dataFile.print(dht.readHumidity(), 1);
    dataFile.print(" hPa, ");
    dataFile.println(analogRead(SHUMSENSOR));
    dataFile.close();
  }
    // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

No effect, but thanks for your answer!

Also, when troubleshooting a problem with one device, the SD card in this case, strip back the program so that all it does is test the SD card.

So in this case remove all the DHT, Display, WiFi etc.

Then test the SD again.

Opening and closing the SD each time you go round the loop is bad practice. It may be OK to start with, but usually gives you grief in the long run. I don’t know if this is your problem, but you may have done something that makes it effect you sooner rather than later.

I figured out that the DHT22-Sensor is responsible with the trouble.
As soon I stripped everything out off the code which has to do with the DHT, it works.
But why? I want to see temperature and humidity on my LCD and write it to my SD-card.

Okay, I can open the file in the void setup(), but when do I have to call the close() function?
I want that the SD-card became written since the measurements are done.

Wow the problem solved! I changed the DHT-pin from pin 6 to pin 8. I stored the solution of the measurement globally in a float and that’s it. It works fine.