Creare un file sul SD,in formato hhmmDDMM (ore minuti giorno mese)

Salve avrei la necessita' si scrivere su sd dei file giornalieri.So usando la libreria SD FAT e un RTC DS1307,con libreria RTClib.Vorrei fare in modo che il file scritto su SD sia nel formato hhmmDDMM,per ottenere ogni giorno un file diverso.Vorrei usare i dati provenienti da RTC che sono:

/ SCRITTURA ORA E DATA SU SD
   Dati.print(now.day(), DEC);
   Dati.print('/');
   Dati.print(now.month(), DEC);
   Dati.print('/');
   Dati.print(now.year(), DEC);
   Dati.print(' ');
   Dati.print(now.hour(), DEC);
   Dati.print(':');
   Dati.print(now.minute(), DEC);
   Dati.print(':');
   Dati.print(now.second(), DEC);
   Dati.println();

Cosa dovrei inserire al posto di datalog.txt?

if (Dati.open("datalog.txt", O_RDWR | O_CREAT | O_AT_END))

Grazie.

"datalog.txt" è un array di char quindi te ne devi costruire uno con i parametri prelevati dalla data e sostituirlo

definisci la variabile char

char nomefile[] = "xxxxxxxx.txt";

poi vai a modificare i singoli char

    nomefile[0] = '2';
    nomefile[1] = '1';
    nomefile[2] = '0';
    nomefile[3] = '5';
    nomefile[4] = '2';
    nomefile[5] = '0';
    nomefile[6] = '1';
    nomefile[7] = '4';

 myFile = SD.open(nomefile, FILE_WRITE);

ora il file sulla SD si chiamerà 21052014.txt (preso da 21/05/2014)

ciao

pablos: "datalog.txt" è un array di char quindi te ne devi costruire uno con i parametri prelevati dalla data e sostituirlo

definisci la variabile char

char nomefile[] = "xxxxxxxx.txt";

poi vai a modificare i singoli char

    nomefile[0] = '2';
    nomefile[1] = '1';
    nomefile[2] = '0';
    nomefile[3] = '5';
    nomefile[4] = '2';
    nomefile[5] = '0';
    nomefile[6] = '1';
    nomefile[7] = '4';

myFile = SD.open(nomefile, FILE_WRITE);




ora il file sulla SD si chiamerà 21052014.txt (preso da 21/05/2014)

ciao

Ciao Pablos,grazie anzitutto per la risposta.Quello che non mi e' chiaro e' come faccio ad associare i dati GIA estistenti,creati dal rtc (quindi now.day(),now.month ecc )all'array di caratteri.Mi spiego,qui al posto di '2' o '1' dovrei mettere cio' che proviene da now.month() giusto?Come dovrei fare

nomefile[0] = '2'; nomefile[1] = '1'; nomefile[2] = '0'; nomefile[3] = '5'; nomefile[4] = '2'; nomefile[5] = '0'; nomefile[6] = '1'; nomefile[7] = '4';

Devi usare le funzioni per le manipolazioni di stringhe di caratteri (char array) che trovi nella <string.h> che fa parte di AVR libc (… inclusa automaticamente dall’IDE).

Se te la studi troverai funzioni per inizializzare stringhe di char (strcpy() ), appenderci pezzi di testo (strcat() ) e così via.

Se i dati che hai sono degli interi numerici, allora puoi usare le funzioni che trovi nella <stdlib.h> per la loro conversione in stringa (es. itoa() converte un integer in stringa di char).

Con pochi passaggi ti crei il nome come vuoi tu :wink:

Guglielmo

chi cerca trova dai un occhiata qui http://forum.arduino.cc/index.php?topic=71223.0

come fai Guglielmo a mettere solo QUI con il link nascosto che non me lo ricordo? :)

grazie ciao

pablos:
chi cerca trova
dai un occhiata qui http://forum.arduino.cc/index.php?topic=71223.0

come fai Guglielmo a mettere solo QUI con il link nascosto che non me lo ricordo? :slight_smile:

grazie ciao

Ecco,sto impazzendo da 3 giorni,cercando in tutti i modi possibili! :* Grazie mille davvero,era quello che cercavo!!

Io userei snprintf() http://www.cplusplus.com/reference/cstdio/snprintf/

char nomefile[] = "YYYYMMGG.txt";
snprintf(nomefile,sizeof(nomefile),"%04d%02d%02d.txt",now.year(),now.month(),now.day());

In pratica "scrivi" dentro a nomefile, come se usassi la print(), i vari %d sono il "segnaposto" e 04 o 02 dice almeno 4 o 2 caratteri fillati con 0 (se cifra minore di 2, mette gli 0)

Esempio:

void setup() {
  delay(1000);
  Serial.begin(9600);
  char nomefile[] = "YYYYMMGG.txt";
  snprintf(nomefile,sizeof(nomefile),"%04d%02d%02d.txt",1969,3,9);
  Serial.println(nomefile);
}

void loop() {}

Ottieni: 19690309.txt

pablos: come fai Guglielmo a mettere solo QUI con il link nascosto che non me lo ricordo? :)

... semplice, così : XD

[url=http://metti_qui_il_vero_link]QUI[/url]

Guglielmo

grassie :blush:

nid69ita: Io userei snprintf() http://www.cplusplus.com/reference/cstdio/snprintf/

char nomefile[] = "YYYYMMGG.txt";
snprintf(nomefile,sizeof(nomefile),"%04d%02d%02d.txt",now.year(),now.month(),now.day());

In pratica "scrivi" dentro a nomefile, come se usassi la print(), i vari %d sono il "segnaposto" e 04 o 02 dice almeno 4 o 2 caratteri fillati con 0 (se cifra minore di 2, mette gli 0)

Esempio:

void setup() {
  delay(1000);
  Serial.begin(9600);
  char nomefile[] = "YYYYMMGG.txt";
  snprintf(nomefile,sizeof(nomefile),"%04d%02d%02d.txt",1969,3,9);
  Serial.println(nomefile);
}

void loop() {}



Ottieni: 19690309.txt

Visto che sto realizzando un "Fast",dataloger, non e' che poi la funzione snprint ,prendere troppa memoria e mi rallenta l'acquisizione?

mooger: Visto che sto realizzando un "Fast",dataloger, non e' che poi la funzione snprint ,prendere troppa memoria e mi rallenta l'acquisizione?

Potrebbe, ma non saprei darti una risposta certa su quanto rallenta. Magari nulla. Di sicuro la snprintf() usa passaggio di parametri particolari e l'hanno già alleggerita (non supporta i float e quindi il %f).

Grazie,faccio un po' di prove! :)

Salve,riapro questo vecchio post,visto che solo oggi mi sto accingendo a risolvere il problema!
Dunque,come ho scritto all’inizio del post,ho necessita’ di salvare il file scritto su sd con la data corrente.
Ho il seguente codice,ma non funziona. Nel monitor seriale dovrei ottenere il messaggio:
“Type any character to start”,ma non succede nulla.Cosa puo’ essere?

const int chipSelect = 53;

#include <SdFat.h>
SdFat sd;
SdFile myFile;

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;


void setup() {
  Serial.begin(9600);
  Wire.begin(); // inizializziamo la libreria WIRE per usare
  RTC.begin(); //il Real Time clock basato su ds1307
  
  if (! RTC.isrunning()) 
  
  {
    Serial.println("RTC NON STA FUNZIONANDO");
   //  RTC.adjust (DateTime(__DATE__, __TIME__)); //imposta ora e data
    }
  while (!Serial) {}  // wait for Leonardo
  Serial.println("Type any character to start");
  while (Serial.read() <= 0) {}
  delay(400);  // catch Due reset problem
  
    DateTime now = RTC.now(); // leggiamo l'ora
    int year = now.year(); 
    int month = now.month();
    int day = now.day();
    int hour = now.hour();
    char nomefile[] = "xxxxxxxx.txt";
    nomefile[0] = (year-2000)/10 + '0';
    nomefile[1] = year%10 + '0';
    nomefile[2] = month/10 + '0'; 
    nomefile[3] = month%10 + '0';
    nomefile[4] = day/10 + '0';
    nomefile[5] = day%10 + '0';
    nomefile[6] = hour/10 + '0';
    nomefile[7] = hour%10 + '0';
    nomefile[8] = '.';
    nomefile[9] = 'C';
    nomefile[10] = 'S';
    nomefile[11] = 'V';
  
    if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // open the file for write at end like the Native SD library
  if (!myFile.open(nomefile, O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening test.txt for write failed");
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to test.txt...");
  myFile.println("testing 1, 2, 3.");

  // close the file:
  myFile.close();
  Serial.println("done.");

  // re-open the file for reading:
  if (!myFile.open("test.txt", O_READ)) {
    sd.errorHalt("opening test.txt for read failed");
  }
  Serial.println("test.txt:");

  // read from the file until there's nothing else in it:
  int data;
  while ((data = myFile.read()) >= 0) Serial.write(data);
  // close the file:
  myFile.close();
}

void loop() {
  // nothing happens after setup
}

Questo qui invece funziona,quindi il problema forse e’ dato dall’acquisizione dei dati dal RTC

const int chipSelect = 53;

#include <SdFat.h>
SdFat sd;
SdFile myFile;

void setup() {
  Serial.begin(9600);
  char nomefile[] = "xxxxxxxx.txt";
 nomefile[0] = '2';
 nomefile[1] = '4';
 nomefile[2] = '0';
 nomefile[3] = '9';
 nomefile[4] = '2';
 nomefile[5] = '0';
 nomefile[6] = '1';
 nomefile[7] = '4';
  
  
  while (!Serial) {}  // wait for Leonardo
  Serial.println("Type any character to start");
  while (Serial.read() <= 0) {}
  delay(400);  // catch Due reset problem
  
 
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // open the file for write at end like the Native SD library
  if (!myFile.open(nomefile, O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening test.txt for write failed");
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to test.txt...");
  myFile.println("testing 1, 2, 3.");

  // close the file:
  myFile.close();
  Serial.println("done.");

  // re-open the file for reading:
  if (!myFile.open("test.txt", O_READ)) {
    sd.errorHalt("opening test.txt for read failed");
  }
  Serial.println("test.txt:");

  // read from the file until there's nothing else in it:
  int data;
  while ((data = myFile.read()) >= 0) Serial.write(data);
  // close the file:
  myFile.close();
}

void loop() {
  // nothing happens after setup
}

Questo qui invece funziona,quindi il problema forse e’ dato dall’acquisizione dei dati dal RTC

probabile

while (!Serial) {}  // wait for Leonardo

hai un arduino leonardo?

nomefile[0] = (year-2000)/10 + '0';
    nomefile[1] = year%10 + '0';
    nomefile[2] = month/10 + '0'; 
    nomefile[3] = month%10 + '0';
    nomefile[4] = day/10 + '0';
    nomefile[5] = day%10 + '0';
    nomefile[6] = hour/10 + '0';
    nomefile[7] = hour%10 + '0';

nomefile[0] = (year-2000)/10 + ‘0’; su una variabile che contiene un carattere solo vuoi caricare 4 numeri?

Serial.println("Type any character to start");
while (Serial.read() <= 0) {}

lo sketch ti chiede di inserire un carattere nel serial per continuare il programma … lo hai fatto?

Ho provato cosi! Non ho arduino LEONARDO,infatti ho eliminato la riga di codice relativa,e poi ho eliminato la parte in cui devo inviare un carattere per poter scrivere…a me serve semplicemente scrivere nel formato (YYMMDDHH.) ad esempio:
14092500 .

const int chipSelect = 53;

#include <SdFat.h>
SdFat sd;
SdFile myFile;

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;


void setup() {
  Serial.begin(9600);
  Wire.begin(); // inizializziamo la libreria WIRE per usare
  RTC.begin(); //il Real Time clock basato su ds1307
  
  if (! RTC.isrunning()) 
  
  {
    Serial.println("RTC NON STA FUNZIONANDO");
   //  RTC.adjust (DateTime(__DATE__, __TIME__)); //imposta ora e data
    }
  //while (!Serial) {}  // wait for Leonardo
 // Serial.println("Type any character to start");
  //while (Serial.read() <= 0) {}
  //delay(400);  // catch Due reset problem
  
    DateTime now = RTC.now(); // leggiamo l'ora
    int year = now.year(); 
    int month = now.month();
    int day = now.day();
    int hour = now.hour();
    char nomefile[] = "xxxxxxxx.txt";
    nomefile[0] = '1';
    nomefile[1] = year%10 + '0';
    nomefile[2] = month/10 + '0'; 
    nomefile[3] = month%10 + '0';
    nomefile[4] = day/10 + '0';
    nomefile[5] = day%10 + '0';
    nomefile[6] = hour/10 + '0';
    nomefile[7] = hour%10 + '0';
    nomefile[8] = '.';
    nomefile[9] = 'C';
    nomefile[10] = 'S';
    nomefile[11] = 'V';
  
    if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // open the file for write at end like the Native SD library
  if (!myFile.open(nomefile, O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening test.txt for write failed");
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to test.txt...");
  myFile.println("testing 1, 2, 3.");

  // close the file:
  myFile.close();
  Serial.println("done.");

  // re-open the file for reading:
  if (!myFile.open("test.txt", O_READ)) {
    sd.errorHalt("opening test.txt for read failed");
  }
  Serial.println("test.txt:");

  // read from the file until there's nothing else in it:
  int data;
  while ((data = myFile.read()) >= 0) Serial.write(data);
  // close the file:
  myFile.close();
}

void loop() {
  // nothing happens after setup
}

pablos: nomefile[0] = (year-2000)/10 + '0'; su una variabile che contiene un carattere solo vuoi caricare 4 numeri?

Se la now.year() ritorna l'anno nel formato 2014 sembra giusto. 2014-2000=> 14/10=> 1 La documentazione dice che l'anno dovrebbe essere YYYY 4 cifre, magari meglio controllare, stampando a video, su serial monitor , il valore. Se invece year ritorna solo 2 cifre tipo 14 il calcolo è errato 14-2000=> -1986/10 => -198 + 48 => -150 e chissà che carattere è (pure illegale per un nome di file)

  DateTime now = RTC.now(); // leggiamo l'ora
  int year = now.year(); 
  Serial.print("anno="); Serial.println(year);  // solo per debug

Ho provato anche cosi’! ma niente!

const int chipSelect = 53;

#include <SdFat.h>
SdFat sd;
SdFile myFile;

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;


void setup() {
  Serial.begin(9600);
  Wire.begin(); // inizializziamo la libreria WIRE per usare
  RTC.begin(); //il Real Time clock basato su ds1307
  
  if (! RTC.isrunning()) 
  
  {
    Serial.println("RTC NON STA FUNZIONANDO");
   //  RTC.adjust (DateTime(__DATE__, __TIME__)); //imposta ora e data
    }
  //while (!Serial) {}  // wait for Leonardo
 // Serial.println("Type any character to start");
  //while (Serial.read() <= 0) {}
  //delay(400);  // catch Due reset problem
  
    DateTime now = RTC.now(); // leggiamo l'ora
   
    char nomefile[] = "00000000.csv";
 
    
    nomefile[0] = (now.year()/1000)%10 + '0'; //To get 1st digit from year()
    nomefile[1] = (now.year()/100)%10 + '0'; //To get 2nd digit from year()
    nomefile[2] = (now.year()/10)%10 + '0'; //To get 3rd digit from year()
    nomefile[3] = now.year()%10 + '0'; //To get 4th digit from year()
    nomefile[4] = now.month()/10 + '0'; //To get 1st digit from month()
    nomefile[5] = now.month()%10 + '0'; //To get 2nd digit from month()
    nomefile[6] = now.day()/10 + '0'; //To get 1st digit from day()
    nomefile[7] = now.day()%10 + '0'; //To get 2nd digit from day()
    //nomefile[8] = nomefile + ".csv";
    
    if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // open the file for write at end like the Native SD library
  if (!myFile.open(nomefile, O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening test.txt for write failed");
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to test.txt...");
  myFile.println("testing 1, 2, 3.");

  // close the file:
  myFile.close();
  Serial.println("done.");

  // re-open the file for reading:
  if (!myFile.open("test.txt", O_READ)) {
    sd.errorHalt("opening test.txt for read failed");
  }
  Serial.println("test.txt:");

  // read from the file until there's nothing else in it:
  int data;
  while ((data = myFile.read()) >= 0) Serial.write(data);
  // close the file:
  myFile.close();
}

void loop() {
  // nothing happens after setup
}

Subito dopo aver calcolato il nome del file, stampalo per verificare se è corretto:

//nomefile[8] = nomefile + ".csv";
Serial.print("file #"); Serial.print(nomefile); Serial.println("#"); // per debug

Poi, non mi è chiaro il cosa vuol dire… “ho provato così, ma niente.”
Cioè quando non funziona non stampa nulla-nulla su serial monitor ?
Neppure “opening test.txt for write failed” ?

Ma non capisco,il serial non da proprio segni di vita!

Allora,quando apro il serial,non succede nulla,nessun messaggio...niente di niente,ho inserito anche il codice di debug da te suggerito.Cosi',ho pensato fosse un problema hardware,ho caricato lo sketch CARDINFO,della libreria SDFAT e funziona perfettamente!Riassumendo i problemi sono: Non scrive nulla su sd,e non stampa nulla sul monitor seriale.