problema con datalogging

salve a tutti,ho realizzato una stazione meteo con arduino uno che raccoglie un po' di dati (temperatura, umidita, pressione ecc) adesso vorrei però salvarli su una micro sd. A questo scopo ho una shield microSD della catalex e sto editando un po' di codice per provare a salvare i dati almeno su un file .txt
come modulo real time ho un ds1307, un bmp180 per la pressione, dht11 per la temperatura e un display lcd che mi mostra tutti i dati in real time.
la mia idea era utilizzare una flag inizianizzandola a false, e lanciare una if.. a 30 sec scrivi i dati e alla fine rimetti la flag a false.
non capisco però perchè non mi scriva il file pur inizializzando la sd con successo.
inoltre mi sapreste dire come mandare in stampa sulla sd anche i dati relativi a data e ora?
sono nuovo di arduino e purtroppo ho un po' di problemini..
in allegato cè il codice che ho scritto.
vi ringrazio in anticipo

stazione_meteo.ino (3.22 KB)

Non so quali usi di micro sd, io sto facendo pure una stazione meteo che ha anche la funzione di datalogger e uso l'sd messa nell'ethernet shield
Con un esempio simile già puoi capire :wink:

#include <SD.h>         //SD Card Library



  int CS_pin = 10; // pin sd


void setup()
{

  Serial.begin(9600);
  Serial.println("Initializing Card");
  //CS Pin is an output
  pinMode(CS_pin, OUTPUT);

  
  //Initialize Card
  if (!SD.begin(CS_pin))
  {
      Serial.println("Card Failure");
      return;
  }
  Serial.println("Card Ready");

  File logFile = SD.open("LOG.csv", FILE_WRITE);  // il nome del file che puoi mettere già in exel come scritto qui se vuoi
  if (logFile)
  {
    
    String header = "pressione, etc"; i nomi che vengono scritti sulle colonne di exel
    logFile.println(header);
    logFile.close();
    Serial.println(header);
  }
  else
  {
    Serial.println("Couldn't open log file");
  }
  
}

void loop()
{
  
  String dataString =  String(pressione) + ", " + String(dati che vuoi) ; // dati che metti, tipo barometer.getPressure e robe così e se vuoi mettere l'ora, basta che scrivi nel testo tra parentesi hour(), minute() etc
  
  //Open a file to write to
  //Only one file can be open at a time
  File logFile = SD.open("LOG.csv", FILE_WRITE);
  if (logFile)
  {
    logFile.println(dataString);
    logFile.close();
    Serial.println(dataString);
  }
  else
  {
    Serial.println("Couldn't open log file");
  }

}

Ogni 30 secondi non so come si faccia sinceramente, qualcuno più bravo di me lo saprà sicuro, ma penso devi usare millis :wink:

quindi in sostanza mi stai dicendo di copiare i dati dei sensori in una stringa e poi passare quelli alla sd?
scusa se faccio domande ovvie ma sto cercando più che altro di capire..

il codice che ho realizzato è questo, in pratica la mia idea era salvare ogni tot secondi i dati dei sensori

#include <Wire.h>                  
#include <LiquidCrystal.h>    
#include <Adafruit_BMP085.h> 
#include "RTClib.h"
#include "DHT.h"
#include <SPI.h> 
#include <SD.h>

#define DHTPIN 8 //Conectamos el Sensor al pin digital 9
#define DHTTYPE DHT11 

File myFile;
const int chipSelect=4;
DHT dht(DHTPIN, DHTTYPE);
RTC_Millis RTC;
char buffers[10];
long int time,Tempo;
Adafruit_BMP085 bmp;
LiquidCrystal lcd(2, 3, 5, 6, 7, 9);
float seaLevelPressure=103100;

boolean logSD = false;

void setup() {
Serial.begin(9600);
Wire.begin();
Tempo = millis();
RTC.begin(DateTime(__DATE__,__TIME__));  
lcd.begin(16,2);// Indicamos medidas de LCD
dht.begin();
bmp.begin();
Serial.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("card initialized.");
}

void loop() { 
delay(1000);
time=millis();
int h=dht.readHumidity();    // Lee la humedad
float t=dht.readTemperature();
float s=bmp.readTemperature();
delay(2500);
///////////////////////////////////////////////////
if(time > (Tempo + 1000))
    {
        DateTime now = RTC.now();
        sprintf(buffers,  "%02d/%02d/%d", now.day(), now.month(), now.year());
        String B = String(buffers);
        lcd.setCursor(0,0);
        lcd.print(B);
        sprintf(buffers,  "%02d:%02d:%02d", now.hour(), now.minute(),now.second());
        B = String(buffers);
        lcd.setCursor(0,1);
        lcd.print(B);
        Tempo = millis();

    }

delay(1500);
/////////////////////////////////////////////////// 
lcd.clear();//Elimina todos los simbolos del LCD
lcd.setCursor(0,0);//Posiciona la primera letra despues del segmento 5 en linea 1              
lcd.print("Umidita' relativa");
lcd.setCursor(6,1);
lcd.print(h);//Escribe la humedad
lcd.print(" %");                     
delay (2500);
///////////////////////////////////////////////////              
lcd.clear();
lcd.setCursor(3,0);
lcd.print("Temperatura "); 
lcd.setCursor(6,1);
lcd.print((t+s)/2);//Escribe la temperatura
lcd.print(" C'");                   
delay (2500);           
lcd.clear();                   
//////////////////////////////////////////////////

    lcd.setCursor(3,0);
    lcd.print("Pressione");
    lcd.setCursor(6,1);
    lcd.print(bmp.readPressure());
    lcd.print("Pa");
    delay(2500);
    lcd.clear();
    lcd.setCursor(3,0);
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1031.25 millibar = 103125 Pascal
    lcd.print("Altitudine");
    lcd.setCursor(6,1);
    lcd.print(bmp.readAltitude(seaLevelPressure));
    lcd.print("m");
    delay(2500);
    lcd.clear();
    ///////////////////////////////////////
   lcd.setCursor(0,0);
   lcd.print("press. liv. mare");
   lcd.setCursor(3,1);
   lcd.print(seaLevelPressure);
   lcd.print("Pa");
   delay(2000);
   lcd.clear();

  ////////////////////////////////////////////

  if(time==30000 && !logSD)
   {
    myFile = SD.open("log.txt",FILE_WRITE);
    if(myFile)
    {
     Serial.println("inizio scrittura");
     myFile.print(h);
     myFile.print((t+s)/2);
     myFile.print(bmp.readPressure());
     myFile.print(bmp.readAltitude(seaLevelPressure));

     myFile.close();
    }

    logSD=false;
   }
   else
   {
    Serial.println("errore apertura log.txt");
   }

}

Secondo me come mi è stato detto a me tante volte, meglio fare una cosa per volta e capirla :wink:
Con quel codice che ho postato, senza immischiarti in troppe robe, nella stringa mettici tipo così

#include <SD.h>         //SD Card Library



  int CS_pin = 10; // pin sd


void setup()
{

  Serial.begin(9600);
  Serial.println("Initializing Card");
  //CS Pin is an output
  pinMode(CS_pin, OUTPUT);

  
  //Initialize Card
  if (!SD.begin(CS_pin))
  {
      Serial.println("Card Failure");
      return;
  }
  Serial.println("Card Ready");

  File logFile = SD.open("LOG.csv", FILE_WRITE);  // il nome del file che puoi mettere già in exel come scritto qui se vuoi
  if (logFile)
  {
    
    String header = "ORA, Pressione"; i nomi che vengono scritti sulle colonne di exel
    logFile.println(header);
    logFile.close();
    Serial.println(header);
  }
  else
  {
    Serial.println("Couldn't open log file");
  }
  
}

void loop()
{
  
  String dataString =  String(hour()) + ":" + String(minute())+ ":" + String(second()) + ", " + String(il modo in cui leggi la pressione)  // dati che metti, tipo barometer.getPressure e robe così e se vuoi mettere l'ora, basta che scrivi nel testo tra parentesi hour(), minute() etc
  
  //Open a file to write to
  //Only one file can be open at a time
  File logFile = SD.open("LOG.csv", FILE_WRITE);
  if (logFile)
  {
    logFile.println(dataString);
    logFile.close();
    Serial.println(dataString);
  }
  else
  {
    Serial.println("Couldn't open log file");
  }

}

Per scrivere ogni 30 secondi secondo me si fa così, però non ne sono certo

metti nelle funzioni all'inizio

const unsigned int intervallo = 30*1000;
unsigned long Tempo=0;
unsigned long oraDiscrivere=0;

poi nel setup

oraDiscrivere= millis()+intervallo;

nel loop (toglilo dal setup)
metti Tempo= millis();

e poi fai

if (Tempo> oraDiscrivere)
String dataString =  String(hour()) + ":" + String(minute())+ ":" + String(second()) + ", " + String(il modo in cui leggi la pressione)  // dati che metti, tipo barometer.getPressure e robe così e se vuoi mettere l'ora, basta che scrivi nel testo tra parentesi hour(), minute() etc
  
  //Open a file to write to
  //Only one file can be open at a time
  File logFile = SD.open("LOG.csv", FILE_WRITE);
  if (logFile)
  {
    logFile.println(dataString);
    logFile.close();
    Serial.println(dataString);
  }
  else
  {
    Serial.println("Couldn't open log file");
  }

oraDiscrivere= Tempo+intervallo;

}

ho risolto, avevo dimenticato un'inizializzazione per la scrittura di data ed ora, adesso sto cercando di implementare la scrittura su file ogni tot secondi invece che alla fine di ogni ciclo.
Qui il codice completo di modifiche, è ancora da "sgrezzare" ma in linea di principio non mi pare malaccio.
se qualcuno riuscisse ad aiutarmi ad implementare tale funzione mi darebbe una grandissima mano :slight_smile:

#include <Wire.h>                  
#include <LiquidCrystal.h>    
#include <Adafruit_BMP085.h> 
#include "RTClib.h"
#include "DHT.h"
#include <SPI.h> 
#include <SD.h>

#define DHTPIN 8 //Conectamos el Sensor al pin digital 9
#define DHTTYPE DHT11 

const int chipSelect=4;
DHT dht(DHTPIN, DHTTYPE);
RTC_Millis RTC;
char buffers[10];
long int time,Tempo;
Adafruit_BMP085 bmp;
LiquidCrystal lcd(2, 3, 5, 6, 7, 9);
float seaLevelPressure=103100;


void setup() {
Serial.begin(9600);
Wire.begin();
Tempo = millis();
RTC.begin(DateTime(__DATE__,__TIME__));  
lcd.begin(16,2);// Indicamos medidas de LCD
dht.begin();
bmp.begin();
Serial.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("card initialized.");
}

void loop() { 
delay(1000);
time=millis();
DateTime now = RTC.now();
int h=dht.readHumidity();    // Lee la humedad
float t=dht.readTemperature();
float s=bmp.readTemperature();
float p=bmp.readPressure();
delay(2500);
/////////////////////////////////////////////////// 
lcd.clear();//Elimina todos los simbolos del LCD
lcd.setCursor(0,0);//Posiciona la primera letra despues del segmento 5 en linea 1              
lcd.print("Umidita' relativa");
lcd.setCursor(6,1);
lcd.print(h);//Escribe la humedad
lcd.print(" %");                     
delay (2500);
///////////////////////////////////////////////////              
lcd.clear();
lcd.setCursor(3,0);
lcd.print("Temperatura "); 
lcd.setCursor(6,1);
lcd.print((t+s)/2);//Escribe la temperatura
lcd.print(" C'");                   
delay (2500);           
lcd.clear();                   
//////////////////////////////////////////////////

    lcd.setCursor(3,0);
    lcd.print("Pressione");
    lcd.setCursor(6,1);
    lcd.print(bmp.readPressure());
    lcd.print("Pa");
    delay(2500);
    lcd.clear();
    lcd.setCursor(3,0);
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1031.25 millibar = 103125 Pascal
    lcd.print("Altitudine");
    lcd.setCursor(6,1);
    lcd.print(bmp.readAltitude(seaLevelPressure));
    lcd.print("m");
    delay(2500);
    lcd.clear();
    ///////////////////////////////////////
   lcd.setCursor(0,0);
   lcd.print("press. liv. mare");
   lcd.setCursor(3,1);
   lcd.print(seaLevelPressure);
   lcd.print("Pa");
   delay(2000);
   lcd.clear();

  ////////////////////////////////////////////

  if(time > (Tempo + 1000))
    {
        DateTime now = RTC.now();
        sprintf(buffers,  "%02d/%02d/%d", now.day(), now.month(), now.year());
        String B = String(buffers);
        lcd.setCursor(0,0);
        lcd.print(B);
        sprintf(buffers,  "%02d:%02d:%02d", now.hour(), now.minute(),now.second());
        B = String(buffers);
        lcd.setCursor(0,1);
        lcd.print(B);
        Tempo = millis();

    }
    delay(1500);
    lcd.clear();

    File dataFile = SD.open("datalog.csv", FILE_WRITE);

  //Scriviamo: TEMPERATURA - ORA:MINUTI:SECONDI
  if (dataFile) {
    dataFile.print("Temperatura ");
    dataFile.print((t+s)/2);
    dataFile.print("*C - ");
    dataFile.print("Umidita' ");
    dataFile.print(h);
    dataFile.print("% - ");
    dataFile.print("Pressione ");
    dataFile.print(p);
    dataFile.print("Pa - ");
    dataFile.print(now.hour(), DEC);
    dataFile.print(":");
    dataFile.print(now.minute(), DEC);
    dataFile.print(":");
    dataFile.println(now.second(), DEC);
    dataFile.print(" - ");
    dataFile.print(now.day(), DEC);
    dataFile.print("/");
    dataFile.print(now.month(), DEC);
    dataFile.print("/");
    dataFile.print(now.year(), DEC);
    //chiudiamo il file
    dataFile.close(); 
  }

    

}

Prova ad implentare quelle cose scritte sopra, forse riesci, prova :wink:
dichiara quelle cose e segui come ti ho detto e metti l if al posto giusto

Comunque con la stringa é tutto piu ordinato, adesso non so come visualizzi

purtroppo non vanno, sto provando altre soluzioni ma fino ad ora nulla...credo che la cosa che sbaglio sia la condizione...
al momento sto provando implementando il mio codice con una if del genere

tra le globali

long int oradiscrivere=30000;

e poi nel loop ho inserito la condizione

if(time>(Tempo+oradiscrivere))
{
        apri il file;
        scrivi;
        dai conferma e chiudi file;
}

ma nulla..non viene nemmeno aperto il file.
mi esegue sempre il ramo della else.

E "apri il file", "scrivi" etc a cosa corrispondono??

a questo

if(time>(Tempo+oradiscrivere))
{
 File dataFile = SD.open("datalogger.csv", FILE_WRITE);

  //Scriviamo: TEMPERATURA - ORA:MINUTI:SECONDI
  if (dataFile) {

    dataFile.print("Temperatura ");
    dataFile.print((t+s)/2);
    dataFile.print("*C - ");
    dataFile.print("Umidita' ");
    dataFile.print(h);
    dataFile.print("% - ");
    dataFile.print("Pressione ");
    dataFile.print(p);
    dataFile.print("Pa - ");
    dataFile.print(now.hour(), DEC);
    dataFile.print(":");
    dataFile.print(now.minute(), DEC);
    dataFile.print(":");
    dataFile.println(now.second(), DEC);
    dataFile.print(" - ");
    dataFile.print(now.day(), DEC);
    dataFile.print("/");
    dataFile.print(now.month(), DEC);
    dataFile.print("/");
    dataFile.print(now.year(), DEC);
    //chiudiamo il file
    dataFile.close(); 
    Serial.println("scritto");
  }
  else
  {
    Serial.println("Couldn't open log file");
  }
}
else
 {
  Serial.println("non ancora");
 }

Capito.
Non so se faccia ma prova a mettere una cosa simile nel setup:

 File dataFile = SD.open ("datalogger.csv",FILE_WRITE);
   if (dataFile)
 {
 String header = "Data, Temperatura, Umidita', Pressione";
  dataFile.println(header);
  dataFile.close();
  
 }

proverò in serata