Keyes Data Logging Shield - problemi di scrittura file

ciao a tutti,
sto facendo delle prove con la shield in oggetto, visibile a questo link.
è impilata su un arduino UNO, con una SD da 1 GB inserita. lo sketch CardInfo funziona e mi rileva la SD correttamente.
ho regolato l'ora del RTC, con lo skethc fornito al link e funziona anche quello.
ho però dei problemi di scrittura. precisamente, ho caricato lo script seguente (che ho preso sempre dal link, ma ho semplificato, in modo da scrivere ogni 2 secondi, anzichè al rilevamento del movimento, come prevedeva lo script, per non attaccare alcun sensore e fare il tutto più velocemente):

#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()
// the digital pins that connect to the LEDs
RTC_DS1307 RTC; // define the Real Time Clock object\
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

  // red LED indicates error
  while (1);
}
void setup(void)
{
  Serial.begin(9600);
  Serial.println();

  // use debugging LEDs

#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START
  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");

  // create a new file
  char filename[] = "LOGGER00.txt";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break; // leave the loop!
    }
  }

  if (! logfile) {
    error("couldnt create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);
  // connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif //ECHO_TO_SERIAL
  }

  logfile.println("millis,stamp,datetime,status");
#if ECHO_TO_SERIAL
  Serial.println("millis,stamp,datetime,status");
#endif //ECHO_TO_SERIAL
}

void loop(void)
{
  delay(2000);
  logData();
}

void logData() {
  DateTime now;
  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m); // milliseconds since start
  logfile.print(", ");
#if ECHO_TO_SERIAL
  Serial.print(m); // milliseconds since start
  Serial.print(", ");
#endif
  now = RTC.now();
  // log time
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.println(now.second(), DEC);

#if ECHO_TO_SERIAL
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.println(now.second(), DEC);

#endif //ECHO_TO_SERIAL
}

sul terminale vedo correttamente i millisecondi e la data, ogni 2 secondi, ma sulla SD non scrive nulla.
o, meglio, scrive il file, che però rimane vuoto!
dove sto sbagliando?

grazie!

Da telefonino, quindi magari mi sbagli a leggere. Ma non vedo da nessuna parte dove chiudi il file
In generale a me non piace aprire il file in una funzione, usarlo in un'altra e magari chiuderlo in una terza. Prima legge di Nelson sui file: quando si apre/crea un file si scrive subito la riga di chiusura, così si evita di dimenticare di chiuderlo

centrato in pieno!
o quasi... nel senso che in effetti mancava la chiusura del file!
però ora mi scrive solo il primo record... il risultato, dopo diverse decine di righe visualizzate sul monitor seriale, è il seguente:

millis,stamp,datetime,status
2379, 2018/3/5 10:30:7

in pratica, nel file viene scritta sempre e solo la prima riga!

grazie!

Sketch grazie

ho semplicemente aggiunto una riga:

logfile.close();

dopo l'ultimo logfile.

credo di aver capito dove sta il problema, ovvero che il file viene chiuso dopo il primo loop, ma non vi è più un comando di apertura.
adesso sto modificando lo sketch, ma non riesco a farlo funzionare... vorrei inserire il comando di apertura e chiusura nella funzione logData, ma ho qualche problemino!

ecco lo sketch. adesso non scrive nemmeno la prima riga... :frowning:

#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()
// the digital pins that connect to the LEDs
RTC_DS1307 RTC; // define the Real Time Clock object\
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
char filename[13];
void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

  // red LED indicates error
  while (1);
}
void setup(void)
{
  Serial.begin(9600);
  Serial.println();

  // use debugging LEDs

#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START
  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");

  // create a new file
  char filename[] = "LOGGER00.txt";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break; // leave the loop!
    }
  }

  if (! logfile) {
    error("couldnt create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);
  // connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif //ECHO_TO_SERIAL
  }

  logfile.println("millis,date,time");
#if ECHO_TO_SERIAL
  Serial.println("millis,date,time");
#endif //ECHO_TO_SERIAL
}

void loop(void)
{
  delay(2000);
  logData(filename);
}

void logData(char) {
  DateTime now;
  // log milliseconds since starting
  uint32_t m = millis();

  logfile = SD.open(filename, FILE_WRITE);
  if (logfile) {
    logfile.print(m); // milliseconds since start
    logfile.print(", ");
#if ECHO_TO_SERIAL
    Serial.print(m); // milliseconds since start
    Serial.print(", ");
#endif
    now = RTC.now();
    // log time
    logfile.print(now.year(), DEC);
    logfile.print("/");
    logfile.print(now.month(), DEC);
    logfile.print("/");
    logfile.print(now.day(), DEC);
    logfile.print(" ");
    logfile.print(now.hour(), DEC);
    logfile.print(":");
    logfile.print(now.minute(), DEC);
    logfile.print(":");
    logfile.println(now.second(), DEC);
    logfile.close();
  }

#if ECHO_TO_SERIAL
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.println(now.second(), DEC);
#endif //ECHO_TO_SERIAL
}

Leva quel char da void logData(char) {
e visto che filename è globale levalo dalla chiamata

void loop(void)
{ delay(2000);
   logData();
}
...
void logData() {

Inoltre quando provi a creare il file, nel for, quando riesce, comunque usa la close()

Come dice nid69, lasci aperto il file, dopo averlo creato. Poi nella funzione di scrittura tenti di aprirlo di nuovo. Prima legge di Nelson sui file:

scrivere tante chiusure quante aperture

ok, risolto!
grazie ad entrambi!
ho aggiunto le chiusure come mi avete indicato ed o anche modificato lo script, in modo da fargli creare un nuovo file ogni giorno, con nome del file nel formato YYYYMMDD.txt.

metto il codice, per completezza!

grazie ancora!

#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC; // define the Real Time Clock object\
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
char filename[] = "00000000.txt";
uint8_t currentDay;

void setup(void)
{
  Serial.begin(9600);

  // initialize the SD card
  pinMode(10, OUTPUT);
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("SD FAIL");
  }
  Serial.println("card initialized.");

  Wire.begin();
  // create a new file
  getFileName();
  createFileName();

  logfile = SD.open(filename, FILE_WRITE);
  if (logfile) {
    Serial.print("Logging to: ");
    Serial.println(filename);
    // connect to RTC
    logfile.println("millis,date,time");
    Serial.println("millis,date,time");
  }
  logfile.close();
  DateTime now = RTC.now();
  currentDay = now.day();
}

void loop(void)
{
  delay(2000);
  DateTime now = RTC.now();
  if (now.day() != currentDay) {
    getFileName();
    createFileName();
    Serial.print("Creating new file: ");
    Serial.println(filename);
  }
  logData();
}

void logData() {
  DateTime now = RTC.now();
  // log milliseconds since starting
  uint32_t m = millis();

  logfile = SD.open(filename, FILE_WRITE);
  if (logfile) {
    logfile.print(m); // milliseconds since start
    logfile.print(", ");
    // log time
    logfile.print(now.year(), DEC);
    logfile.print("/");
    logfile.print(now.month(), DEC);
    logfile.print("/");
    logfile.print(now.day(), DEC);
    logfile.print(" ");
    logfile.print(now.hour(), DEC);
    logfile.print(":");
    logfile.print(now.minute(), DEC);
    logfile.print(":");
    logfile.println(now.second(), DEC);
    logfile.close();
  }
  Serial.print(m); // milliseconds since start
  Serial.print(", ");
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.println(now.second(), DEC);
}

void getFileName() {
  DateTime now = RTC.now();
  filename[0] = (now.year() / 1000) % 10 + '0'; //To get 1st digit from year()
  filename[1] = (now.year() / 100) % 10 + '0'; //To get 2nd digit from year()
  filename[2] = (now.year() / 10) % 10 + '0'; //To get 3rd digit from year()
  filename[3] = now.year() % 10 + '0'; //To get 4th digit from year()
  filename[4] = now.month() / 10 + '0'; //To get 1st digit from month()
  filename[5] = now.month() % 10 + '0'; //To get 2nd digit from month()
  filename[6] = now.day() / 10 + '0'; //To get 1st digit from day()
  filename[7] = now.day() % 10 + '0'; //To get 2nd digit from day()
  Serial.print(filename);
  currentDay = now.day();
}

void createFileName() {
  //Check file name exist?
  if (SD.exists(filename)) {
    Serial.println(" exists.");
  }
  else {
    Serial.println("doesn't exist.");
    Serial.print("Creating new file: ");
    Serial.println(filename);
    logfile = SD.open(filename, FILE_WRITE);
    logfile.close();
  }

}