Arduino mega 2560 con DS 1307

Mi sa che hai proprio ragione Luca, mi sa che mi dovrò armare di pazienza e rivedere connessioni e sketch!

In teoria dovrei avere risolto, per chi dovesse avere problemi consiglio il seguente link:

http://forums.adafruit.com/viewtopic.php?f=31&t=24867

Ho una domanda però ora... ho aggiunto una procedura che mi consenta di interrompere il logging dei dati.
Quando vado per ricominciare il logging mi da un errore "open root". Qualcuno sa dirmi se per caso centri col fatto che il file, nonostante mi salvi correttamente i dati, mi dia sempre data file 01/01/2000?

ciao

dovresti metterci la parte del tuo sketch che gestisce la SD...

Questo dell'open root era saltato fuori tempo fa. Mi pare che dipenda dal fatto che il file non può avere nel nome la parte per indicare le sottocartelle, quindi "cartella/nome.ext" non va bene.
Non mi ricordo però se è un limite della libreria SD allegata ad Arduino oppure anche di altre librerie.
No, forse è questo il problema:
http://arduino.cc/forum/index.php/topic,104109.0.html

Certo:

 // initialize the SD card
 if (!card.init()) error("card.init, Reformat card");
  
  // initialize a FAT volume
  if (!volume.init(card)) error("volume.init");
  
  // open root directory
  if (!root.openRoot(volume)) error("openRoot");
  
  // create a new file
  char name[] = "LOGGER00.CSV"; //File names will follow this format, and increment automatically
  for (uint8_t i = 0; i < 100; i++) {
    name[6] = i/10 + '0';
    name[7] = i%10 + '0';
    if (file.open(root, name, O_CREAT | O_EXCL | O_WRITE)) break;
  }
  if (!file.isOpen()) error ("file.create");
  lcd.clear();
  lcd.home();
  lcd.print("Logging to: ");
  lcd.setCursor(0,1);
  lcd.print(name);
  delay(1000);
  lcd.clear();

  // write header
  file.writeError = 0;

  if (!RTC.begin()) {
    file.println("RTC failed");
    lcd.clear();
    lcd.home();
    lcd.print("RTC failed");
    delay(250);
  }
  
  //Write the output file header row to our file so that we can identify the data later
  file.println("unixtime,datetime,pH (C)"); //VERIFICARE!!!
  if (file.writeError || !file.sync()) {
    error("write header");
  }  
  saveInterval = saveInt(); //call saveInt sub-function and return value
  menu.toRoot();
  }
//************************item1SubItem2**************************    
  else if( used.item == Item1SubItem2 ){
    abilitazioneLog = 0;
    lcd.clear();
    lcd.print("Logging stopped");
    delay(3000);
    menu.toRoot();
  }

La parte subItem2 l'ho messa perchè la uso per fermare il logging. Il problema è che si ferma si ma poi non posso più riprenderlo e non ne capisco il perchè. Sembra che tenga il file aperto ed inoltre non mi salva mai i file con la data di creazione, ma sempre e solo con 01/01/2000 00:00
L'RTC funziona perfettamente, lo visualizzo allo startup e la data e l'ora sono corretti.

Io però non cerco di riaprirlo, a me andrebbe bene anche se ne creasse un altro, infatti la pressione del tasto richiama la funzione che ho copiato per intera dall'inizio, ma niente, da errore.

Chiudilo, forse "troncare" così la connessione lascia l'accesso al filesystem aperto, per qualche motivo che non so.

Si credo anch'io, ho usato un modo "stupido" per chiudere la connessione ma purtroppo non ne conoscevo altri. C'è un comando che chiude il file e lo salva?

ciao

quindi tu riparti ogni volta da card.init()?
esiste il metodo close() per chiudere

Esatto Luca, ho creato un piccolo menu e quando si seleziona il logging riparte dall'inizializzazione della SD.
Quindi se non ho capito male alla fine del subItem2 dovrei mettere una specie di close(nomefile); ?

dovrebbe essere file.close()

Ciao Luca,
provato ma niente da fare. Da sempre errore open root. Cosa potrei cambiare nella procedura di inizializzazione o di terminazione per bypassare questo problema?

ciao

fai l'init solo una volta (nel setup()) e nel tuo loop gestisci solo il file (open e close)
così non mi ha mai dato problemi

Grande Luca, funziona! Ora devo solo capire perchè il file generato ha sempre data 01/01/2000
L'RTC funziona, la data che stampo a LCD è perfetta.

Nella libreria SDFile.cpp ho trovato la funzione:

uint8_t SdFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
         uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)

Non ho capito se questa viene chiamata automaticamente alla creazione del file oppure se occorre attribuire al file data e ora di creazione.
E comunque... come farebbe a sapere dove prendere data e ora?
Il fatto che appaia la data del 1.1.2000 mi fa supporre che manchi un passaggio da qualche parte.

EDIT:
Nella SDFat.h ho trovato:

/** Default date for file timestamps is 1 Jan 2000 */

Continuo a cercare di capire come funziona tutto l'accroccio della SD. :sweat_smile:

Ho trovato questa discussione in cui si utilizza la funzione timestamp --> http://forums.adafruit.com/viewtopic.php?f=31&t=20355

Grazie Paolo,
io intanto ho provato questo sketch e con questo il file viene salvato con la data giusta:

// A simple data logger for the Adafruit Data Logging shield on a mega
// You must edit SdFatConfig.h and set MEGA_SOFT_SPI nonzero
#include <SdFat.h>
#include <SdFatUtil.h>  // define FreeRam()
#include <I2cMaster.h>
#include <SoftRTClib.h>
#define CHIP_SELECT     10  // SD chip select pin
#define LOG_INTERVAL  1000  // mills between entries
#define SENSOR_COUNT     3  // number of analog pins to log
#define ECHO_TO_SERIAL   1  // echo data to serial port if nonzero
#define WAIT_TO_START    1  // Wait for serial input in setup()
#define ADC_DELAY       10  // ADC delay for high impedence sensors

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#if !MEGA_SOFT_SPI
#error set MEGA_SOFT_SPI nonzero in libraries/SdFat/SdFatConfig.h
#endif  // MEGA_SOFT_SPI
// Is a Mega use analog pins 4, 5 for software I2C
const uint8_t RTC_SCL_PIN = 59;
const uint8_t RTC_SDA_PIN = 58;
SoftI2cMaster i2c(RTC_SDA_PIN, RTC_SCL_PIN);
#else  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
// Not Mega use hardware I2C
// enable pull-ups on SDA/SCL
TwiMaster i2c(true);
#endif  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

RTC_DS1307 RTC(&i2c); // define the Real Time Clock object
// file system object
SdFat sd;

// text file for logging
ofstream logfile;

// Serial print stream
ArduinoOutStream cout(Serial);

// buffer to format data - makes it eaiser to echo to Serial
char buf[80];
//------------------------------------------------------------------------------
#if SENSOR_COUNT > 6
#error SENSOR_COUNT too large
#endif  // SENSOR_COUNT
//------------------------------------------------------------------------------
// store error strings in flash to save RAM
#define error(s) sd.errorHalt_P(PSTR(s))
//------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
    DateTime now = RTC.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}
//------------------------------------------------------------------------------
// format date/time
ostream& operator << (ostream& os, DateTime& dt) {
  os << dt.year() << '/' << int(dt.month()) << '/' << int(dt.day()) << ',';
  os << int(dt.hour()) << ':' << setfill('0') << setw(2) << int(dt.minute());
  os << ':' << setw(2) << int(dt.second()) << setfill(' ');
  return os;
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);

  // pstr stores strings in flash to save RAM
  cout << endl << pstr("FreeRam: ") << FreeRam() << endl;

#if WAIT_TO_START
  cout << pstr("Type any character to start\n");
  while (Serial.read() < 0) {}
#endif  // WAIT_TO_START

  // connect to RTC
  if (!RTC.begin()) error("RTC failed");

  // set date time callback function
  SdFile::dateTimeCallback(dateTime);
  DateTime now = RTC.now();
  cout  << now << endl;

  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  if (!sd.begin(CHIP_SELECT, SPI_HALF_SPEED)) sd.initErrorHalt();

  // create a new file in root, the current working directory
  char name[] = "LOGGER00.CSV";

  for (uint8_t i = 0; i < 100; i++) {
    name[6] = i/10 + '0';
    name[7] = i%10 + '0';
    if (sd.exists(name)) continue;
    logfile.open(name);
    break;
  }
  if (!logfile.is_open()) error("file.open");

  cout << pstr("Logging to: ") << name << endl;

  // format header in buffer
  obufstream bout(buf, sizeof(buf));

  bout << pstr("millis");

  bout << pstr(",date,time");

  for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
    bout << pstr(",sens") << int(i);
  }
  logfile << buf << endl;

#if ECHO_TO_SERIAL
  cout << buf << endl;
#endif  // ECHO_TO_SERIAL
}
//------------------------------------------------------------------------------
void loop() {
  uint32_t m;

  // wait for time to be a multiple of interval
  do {
    m = millis();
  } while (m % LOG_INTERVAL);

  // use buffer stream to format line
  obufstream bout(buf, sizeof(buf));

  // start with time in millis
  bout << m;

  DateTime now = RTC.now();
  bout << ',' << now;

  // read analog pins and format data
  for (uint8_t ia = 0; ia < SENSOR_COUNT; ia++) {
#if ADC_DELAY
    analogRead(ia);
    delay(ADC_DELAY);
#endif  // ADC_DELAY
    bout << ',' << analogRead(ia);
  }
  bout << endl;

  // log data and flush to SD
  logfile << buf << flush;

  // check for error
  if (!logfile) error("write data failed");

#if ECHO_TO_SERIAL
  cout << buf;
#endif  // ECHO_TO_SERIAL

  // don't log two points in the same millis
  if (m == millis()) delay(1);
}

L'ho trovato dentro a questo aggiornamento, modificato per poter installare direttamente la logger shield su Arduino Mega 2560.

http://code.google.com/p/beta-lib/downloads/detail?name=AdafruitMega20120329.zip&can=2&q=

Ho riprovato, confermo che con questo sketch va con l'altro no...

Molto bello quello sketch come stile di programmazione. E' vero C. Non quel pseudo-C B.A.S.I.C-style che scrivo io.
Mi metto a studiare!! :cold_sweat:

Io non c'ho capito molto :~ infatti non riesco a capire perché con questo programma mi scriva la data sui file e con l'altro no... tu hai qualche idea?