save log - please Help :(

Hello :slight_smile:

good morning

i do project to get temperature and humidity with DHT11 and i wont to save the log in EEPROM OR SD card
to i can check it another times
What are the modifications and additions I make to my code?

this my cade

#include <SimpleDHT.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>

const int pinDHT11 = 6;
SimpleDHT11 dht11;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {

lcd.begin(16, 2);

lcd.print("Startup OK!");
delay(1000);

lcd.clear();
}

void loop() {
byte temperature = 0;
byte humidity = 0;
int x , y ;

dht11.read(pinDHT11, &temperature, &humidity, NULL);

Serial.begin(9600);

Serial.println ("temperature");
Serial.println (temperature);
Serial.println ("humidity");
Serial.println ( humidity);

lcd.setCursor(0,0);
lcd.print("Temp: ");
lcd.print(round(temperature));
lcd.print("C / ");

lcd.print(round(temperature * 1.8 + 32));
lcd.print("F ");
lcd.setCursor(0,1);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print("% ");

delay(20000);

}

Please use code tags to post code, as described in the "How to use this forum" post.

To save the data to an SD card, you will need an SD card module. Google "arduino sd card" for tutorials.

What are the modifications and additions I make to my code?

Seems to me there's not much use saving DHT11 data without a timestamp, else when you look at a line of data in a week's time you won't know what the data refer to... So I'd consider adding a real time clock.

Inspired by this thread, I updated a 3y old dht/lcd sketch I had knocking around to write T & H to the SD card, and it's given below.

Notes:

  • The datalogging part is based on the datalogger example with the SD library, broken out into functions
  • My lcd and dht libraries are not the same as OP's, but nevertheless the code should be easily adaptable
  • There's a proof of life pulse moving dot on the lcd: everything is delay()-less
  • RTC enhancement to follow...DONE see next post

Sample serial output:

dht with sd logging
Created: 12:49:44, Jul 26 2019
C:\Users\xxx\Documents\Arduino\dht11_lcd_v5_minmax_pulse_rtc_sd\dht11_lcd_v5_minmax_pulse_rtc_sd.ino
Initializing SD card...card initialized.
setup() complete
 
Writing to SD: 17,36
Writing to SD: 17,36
Writing to SD: 18,36
Writing to SD: 18,36
Writing to SD: 20,35
Writing to SD: 21,35

Sample output from SD card once taken to pc:

18,36
17,36
17,36
17,36
18,36
18,36

Here's the sketch:

// dht11 with lcd
// v1 26 march 2017
//
//this version diplays min and max T since power up
//lcd backlight is operated by a button
//with pulse, and no delay on the dht read

//v5 with rtc and sd log inspired by https://forum.arduino.cc/index.php?topic=627958
// todo... rtc, so far only sd log of dht
//26 july 2019

//dht stuff
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 2

//wire and lcd stuff
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
//todo... rtc stuff to go here

//sd card stuff
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
String dataString;

byte minTemp = 99;
byte maxTemp = 0;
byte currTemp;

byte lightPin = 6;

//pulse stuff
int heartbeatInterval = 1000;
bool showHeart = true;
unsigned long previousMillis_heartbeat = 0;

//delayless dht read
int dhtInterval = 5000;
unsigned long previousMillis_dht = 0;

//delayless sd write
int sdInterval = 5000;
unsigned long previousMillis_sd = 0;

void setup()
{
  //print some file details
  Serial.begin(9600);
  Serial.println("dht with sd logging");
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  //turn off l13
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);

  //splash screen
  pinMode(lightPin, INPUT_PULLUP);
  lcd.begin();
  lcd.backlight();
  lcd.print("     DHT11");
  lcd.setCursor(0, 1);//along, down
  lcd.print("   station v5");
  delay(1000);
  //lcd.noBacklight();
  //lcd.clear();

  //initialise sd card
  Serial.print("Initializing SD card...");
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect))
  {
    Serial.println("Card failed, or not present");
    lcd.setCursor(0, 1);//along, down
    lcd.print("  ** SD fail **");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
  lcd.clear();

  //need to read once to get some proper data before the delayless reads
  DHT.read(DHT11_PIN);    // READ DATA

  Serial.println("setup() complete"); Serial.println(" ");
}

void loop()
{
  if (millis() - previousMillis_heartbeat > heartbeatInterval)
  {
    doPulse();
  }

  //read dht without delay
  if (millis() - previousMillis_dht > dhtInterval)
  {
    DHT.read(DHT11_PIN);    // READ DATA
    previousMillis_dht = millis();
  }

  //display dht on lcd
  doLCD();

  //update sd without delay
  if (millis() - previousMillis_sd > sdInterval)
  {
    //fakeUpdateSD();
    createStringForSD();
    writeStringToSD();
    previousMillis_sd = millis();
  }

  if (!digitalRead(lightPin))
  {
    lcd.backlight();
  }
  else
  {
    lcd.noBacklight();
  }

}//loop

void writeStringToSD()
{
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datablah.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile)
  {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.print("Writing to SD: ");
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datablah.txt");
  }
}


void createStringForSD()
{
  // make a string for assembling the data to log:
  dataString = "";

  // get T & H and append to string:
  dataString += String(DHT.temperature);
  dataString += ",";
  dataString += String(DHT.humidity);
  //Serial.println(dataString);

  //todo... rtc date and time
}//createStringForSD

void fakeUpdateSD()
{
  Serial.println("fake write to SD to test timing");
}

void doLCD()
{
  currTemp = DHT.temperature;
  lcd.setCursor(0, 0); //along, down
  lcd.print("Temp:");
  if (currTemp < 10) lcd.print(" ");
  lcd.print(currTemp);
  lcd.print((char)223); //degree symbol
  lcd.print("C RH:");
  lcd.print(DHT.humidity);
  lcd.print("%");

  if (currTemp < minTemp) minTemp = currTemp;
  if (currTemp > maxTemp) maxTemp = currTemp;
  lcd.setCursor(0, 1);//along, down
  lcd.print("Min:");
  if (minTemp < 10) lcd.print(" ");
  lcd.print(minTemp);
  lcd.print((char)223);
  lcd.setCursor(9, 1);//along, down //jump over pulse indicator
  lcd.print("Max:");
  if (maxTemp < 10) lcd.print(" ");
  lcd.print(maxTemp);
  lcd.print((char)223);
}//doLCD

void doPulse()
{
  showHeart = !showHeart;
  previousMillis_heartbeat = millis();

  lcd.setCursor(7, 1);
  if (showHeart)
  {
    lcd.print(". ");
  }
  else
  {
    lcd.print(" .");
  }
} //doPulse

Here's the updated code with a unixtime stamp...

Serial output:

dht with sd rtc logging
Created: 14:17:20, Jul 26 2019
C:\Users\xxx\Documents\Arduino\dht11_lcd_v5_minmax_pulse_rtc_sd\dht11_lcd_v5_minmax_pulse_rtc_sd.ino
Initializing SD card...card initialized.
setup() complete
 
Writing to SD: 1564150659,16,37
Writing to SD: 1564150662,17,37
Writing to SD: 1564150667,17,36

SD card on PC:

1564150653,16,38
1564150659,16,37
1564150662,17,37
1564150667,17,36

SD card opened in Excel and with Excel converting unixtime to humantime (here's how):

1564150653	14:17:33	26-07-19	16	38
1564150659	14:17:39	26-07-19	16	37
1564150662	14:17:42	26-07-19	17	37
1564150667	14:17:47	26-07-19	17	36

Updated sketch:

// dht11 with lcd
// v1 26 march 2017
//
//this version diplays min and max T since power up
//lcd backlight is operated by a button
//with pulse, and no delay on the dht read

//v5 with rtc and sd log inspired by https://forum.arduino.cc/index.php?topic=627958
// todo... rtc, so far only sd log of dht... DONE
//26 july 2019

//dht stuff
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 2

//wire and lcd and rtc stuff
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <DS3231.h>
RTClib RTC;
DateTime now;

//sd card stuff
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
String dataString;

byte minTemp = 99;
byte maxTemp = 0;
byte currTemp;

byte lightPin = 6;

//pulse stuff
int heartbeatInterval = 1000;
bool showHeart = true;
unsigned long previousMillis_heartbeat = 0;

//delayless dht read
int dhtInterval = 5000;
unsigned long previousMillis_dht = 0;

//delayless sd write
int sdInterval = 5000;
unsigned long previousMillis_sd = 0;

void setup()
{
  //print some file details
  Serial.begin(9600);
  Serial.println("dht with sd rtc logging");
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  //turn off l13
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);

  //splash screen
  pinMode(lightPin, INPUT_PULLUP);
  lcd.begin();
  lcd.backlight();
  lcd.print("     DHT11");
  lcd.setCursor(0, 1);//along, down
  lcd.print("   station v5");
  delay(1000);
  //lcd.noBacklight();
  //lcd.clear();

  //initialise sd card
  Serial.print("Initializing SD card...");
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect))
  {
    Serial.println("Card failed, or not present");
    lcd.setCursor(0, 1);//along, down
    lcd.print("  ** SD fail **");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
  lcd.clear();

  //need to read once to get some proper data before the delayless reads
  DHT.read(DHT11_PIN);    // READ DATA
  now = RTC.now();

  Serial.println("setup() complete"); Serial.println(" ");
}

void loop()
{
  if (millis() - previousMillis_heartbeat > heartbeatInterval)
  {
    doPulse();
  }

  //read dht without delay
  if (millis() - previousMillis_dht > dhtInterval)
  {
    DHT.read(DHT11_PIN);    // READ DATA
    now = RTC.now();
    previousMillis_dht = millis();
  }

  //display dht on lcd
  doLCD();

  //update sd without delay
  if (millis() - previousMillis_sd > sdInterval)
  {
    //fakeUpdateSD();
    createStringForSD();
    writeStringToSD();
    previousMillis_sd = millis();
  }

  if (!digitalRead(lightPin))
  {
    lcd.backlight();
  }
  else
  {
    lcd.noBacklight();
  }

}//loop

void writeStringToSD()
{
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("databla3.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile)
  {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.print("Writing to SD: ");
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening databla3.txt");
  }
}


void createStringForSD()
{
  // make a string for assembling the data to log:
  dataString = "";

  //get unixtime and append to string
  //    could use now.year() etc etc
  dataString += String(now.unixtime());
  dataString += ",";
  // get T & H and append to string:
  dataString += String(DHT.temperature);
  dataString += ",";
  dataString += String(DHT.humidity);
  //Serial.println(dataString);

}//createStringForSD

void fakeUpdateSD()
{
  Serial.println("fake write to SD to test timing");
}

void doLCD()
{
  currTemp = DHT.temperature;
  lcd.setCursor(0, 0); //along, down
  lcd.print("Temp:");
  if (currTemp < 10) lcd.print(" ");
  lcd.print(currTemp);
  lcd.print((char)223); //degree symbol
  lcd.print("C RH:");
  lcd.print(DHT.humidity);
  lcd.print("%");

  if (currTemp < minTemp) minTemp = currTemp;
  if (currTemp > maxTemp) maxTemp = currTemp;
  lcd.setCursor(0, 1);//along, down
  lcd.print("Min:");
  if (minTemp < 10) lcd.print(" ");
  lcd.print(minTemp);
  lcd.print((char)223);
  lcd.setCursor(9, 1);//along, down //jump over pulse indicator
  lcd.print("Max:");
  if (maxTemp < 10) lcd.print(" ");
  lcd.print(maxTemp);
  lcd.print((char)223);
}//doLCD

void doPulse()
{
  showHeart = !showHeart;
  previousMillis_heartbeat = millis();

  lcd.setCursor(7, 1);
  if (showHeart)
  {
    lcd.print(". ");
  }
  else
  {
    lcd.print(" .");
  }
} //doPulse