Pages: [1]   Go Down
Author Topic: Memorizzare file con data e ora corretti  (Read 817 times)
0 Members and 1 Guest are viewing this topic.
Padova
Offline Offline
Full Member
***
Karma: 0
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salve a tutti,
uso Arduino uno e una SD shield con RTC DS1307. Ho scritto un codice per salvare dei file csv dentro una SD ma i file hanno sempre la stessa data e ora 01/01/2000 00:00 nonostante all'interno del file i dati siano corretti. Qualcuno ha idea di che comando posso usare per far si che il file venga salvato con la data e l'ora giusti? Ho visto quest'esempio funzionante ma non capisco questo linguaggio di programmazione e quindi non so come gestirlo:
Code:
// A simple data logger for the Arduino analog pins with optional DS1307
// uses RTClib from https://github.com/adafruit/RTClib
#include <SdFat.h>
#include <SdFatUtil.h>  // define FreeRam()

#define CHIP_SELECT     SS  // SD chip select pin
#define USE_DS1307       0  // set nonzero to use DS1307 RTC
#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

// 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))
//------------------------------------------------------------------------------
#if USE_DS1307
// use RTClib from Adafruit
// https://github.com/adafruit/RTClib

// The Arduino IDE has a bug that causes Wire and RTClib to be loaded even
// if USE_DS1307 is false.

#error remove this line and uncomment the next two lines.
//#include <Wire.h>
//#include <RTClib.h>
RTC_DS1307 RTC;  // define the Real Time Clock object
//------------------------------------------------------------------------------
// 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;
}
#endif  // USE_DS1307
//------------------------------------------------------------------------------
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

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

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

  // 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");

#if USE_DS1307
  bout << pstr(",date,time");
#endif  // USE_DS1307

  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;

#if USE_DS1307
  DateTime now = RTC.now();
  bout << ',' << now;
#endif  // USE_DS1307

  // 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);
}
Grazie
Logged

Torino
Offline Offline
God Member
*****
Karma: 2
Posts: 753
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao ho dato un'occhiata ed anche io non capisco quel linguaggio mi unisco al tuo dolore......
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21607
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Questo problema è già venuto fuori 1 mese o 2 fa. Cerca nei vecchi thread, non mi ricordo se chi aveva aperto la discussione ha poi risolto in qualche maniera (mi pareva di sì)
Logged


Padova
Offline Offline
Full Member
***
Karma: 0
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Leo forse ti riferisci a questo sempre aperto da me:

http://arduino.cc/forum/index.php/topic,104381.30.html

però non ho mai risolto. Non riesco ad integrare la parte del programma che mi serve nel mio codice
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21607
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma in quella discussione ho trovato un link:
http://forums.adafruit.com/viewtopic.php?f=31&t=20355
a metà c'è uno sketch con l'uso del metodo timestamp della libreria SD per impostare il timestamp del file.
Logged


Padova
Offline Offline
Full Member
***
Karma: 0
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si ho letto però sembrano tutti controlli:

Code:
if (!file.timestamp(T_WRITE,now.year(),now.month(),now.day(),now.hour(),
now.minute(),now.second() )) {
error("write time");
}

Sto cercando di capire qual'è la parte in cui si va a memorizzare data e ora sul file  smiley-confuse
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21607
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non mi pare un controllo. Invochi la funzione di cambio timestamp e controlli che il valore che restituisce non sia un errore.

EDIT:
ossia è un sistema contratto per evitare l'assegnazione ad una variabile del codice restituito dalla funzione ed il successivo controllo del valore contenuto nella variabile.
« Last Edit: June 01, 2012, 01:44:41 am by leo72 » Logged


Padova
Offline Offline
Full Member
***
Karma: 0
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Io l'avevo interpretato come: "se non riesci ad eseguire la funzione timestamp allora dai messaggio d'errore"
Ora provo ad inserirlo nel mio codice, vediamo che combina.
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 102
Posts: 6548
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Io l'avevo interpretato come: "se non riesci ad eseguire la funzione timestamp allora dai messaggio d'errore"
Ora provo ad inserirlo nel mio codice, vediamo che combina.
Che vuol dire che lui esegue la funzione timestamp e controlla che non dia errore.
Ma la funzione la esegue e il timestamp lo scrive.

Per quanto riguarda <<, è un operatore di flusso.
cout è definito come seriale.
il comando:
Code:
DateTime now = RTC.now();
  cout  << now << endl;
corrisponde a:
Code:
DateTime now = RTC.now();
serial.print(now);
serial.println();

mentre
Code:
cout << endl << pstr("FreeRam: ") << FreeRam() << endl;
è
Code:
serial.print("FreeRam: ");
serial.print(FreeRam());
serial.println();

mentre bout è definito come una stringa (più o meno)
Code:
 // format header in buffer
  obufstream bout(buf, sizeof(buf));

  bout << pstr("millis");

#if USE_DS1307
  bout << pstr(",date,time");
#endif  // USE_DS1307

  for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
    bout << pstr(",sens") << int(i);
  }
  logfile << buf << endl;
questo diventerebbe:
Code:
buf =+ "millis";
#if USE_DS1307
 buf =+ ",date,time";
#endif  // USE_DS1307
 for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
    buf =+ ",sens";
    buf =+ int(i);
  }
file.print(buf);
file.println();
Una cosa del genere.  smiley-grin

Secondo me, l'operatore di flusso è molto intuitivo invece di scrivere un sacco di linee di codice per concatenare stringhe.
Guarda questo codice:
Code:
// 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;
}
Secondo te dentro lo "stream" os, cosa viene scritto?
 
« Last Edit: June 01, 2012, 04:52:09 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21607
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

E' molto intuitivo forse su un PC, dove so che se dirotto qualcosa su cout quel qualcosa mi esce sul terminale.
Ma qui sto programmando un microcontrollore.... già l'idea di usare il paradigma del terminale con cout mi sembra un controsenso.  smiley-sweat
Logged


Padova
Offline Offline
Full Member
***
Karma: 0
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Secondo te dentro lo "stream" os, cosa viene scritto?

Ad occhio scrive anno, mese, giorno... ora e minuti... però con che sintassi non ne ho la minima idea.
file.timestamp ?

Logged

Pages: [1]   Go Up
Jump to: