Formattare __DATE__ e __TIME__

Buongiorno, rifacendomi a questa discussione e a questa funzione:

void logname(char const *date, char *buff) {
  int month, day, year;
  static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
  sscanf(date, "%s %d %d", buff, &day, &year);
  month = (strstr(month_names, buff) - month_names) / 3 + 1;
  sprintf(buff, "%d%02d%02d", year, month, day);
}

Vorrei capire come mai mi da un nome diverso se messa in questo codice:

#include <SD.h>
#include <SPI.h>
#include <DHT.h>
#include <Wire.h>
#include <TimeLib.h>
//#include <DS1307RTC.h>
#include <Ethernet.h>

byte mac[] = {0xAA, 0xBB, 0xCC, 0x00, 0x00, 0x09};
byte ip[] = {10, 0, 0, 30};
byte subnet[] = {255, 0, 0, 0};
byte gateway[] = {10, 0, 0, 254};
EthernetServer server(80);

File myFile1, myFile2;

DHT dht;

char nomefile[16];

int TIMING, TEMP_MAX_ALARM, TEMP_MIN_ALARM;

void logname(char const *date, char *buff) {
  int month, day, year;
  static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
  sscanf(date, "%s %d %d", buff, &day, &year);
  month = (strstr(month_names, buff) - month_names) / 3 + 1;
  sprintf(buff, "%d%02d%02d.csv", year, month, day);
}

void setup() {
  Serial.begin(9600);
  while (!Serial)
  {
    ;
  }

  if (!SD.begin(4))
  {
    return;
  }

  myFile2 = SD.open("OPZIONI.txt");

  if (myFile2)
  {
    while (myFile2.available())
    {
      TIMING = myFile2.parseInt();
      Serial.println(TIMING);
      TEMP_MIN_ALARM = myFile2.parseInt();
      Serial.println(TEMP_MIN_ALARM);
      TEMP_MAX_ALARM = myFile2.parseInt();
      Serial.println(TEMP_MAX_ALARM);
    }
  } else {
    Serial.println("Errore in OPZIONI.txt");
  }
  myFile2.close();
  delay(200);
  logname(__DATE__,nomefile);
  Serial.println(nomefile);
  Serial.println("Stato\tUmidita  (%)\tTemperatura  (F)\t(C)");
  dht.setup(2);
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  float umidita = dht.getHumidity();
  float temperatura = dht.getTemperature();

  Serial.print(dht.getStatusString());
  Serial.print("\t\t");
  Serial.print(umidita);
  Serial.print("%");
  Serial.print("  \t\t");
  Serial.print(dht.toFahrenheit(temperatura));
  Serial.print("  \t");
  Serial.print(temperatura);
  if (temperatura < TEMP_MIN_ALARM)
  {
    Serial.print("\tTEMP<MIN");
  }
  if (temperatura > TEMP_MAX_ALARM)
  {
    Serial.print("\tTEMP>MAX");
  }
  Serial.println();
  delay(900);
  myFile1 = SD.open(nomefile, FILE_WRITE);
  if (myFile1)
  {
    Serial.println("Scrivendo/Delay");
    myFile1.print(__TIME__);
    myFile1.print(";");
    myFile1.print(dht.getStatusString());
    myFile1.print(";");
    myFile1.print(umidita);
    myFile1.print(";");
    myFile1.print(temperatura);
    myFile1.print(";");
    myFile1.print(dht.toFahrenheit(temperatura));
    if (temperatura > TEMP_MAX_ALARM)
    {
      myFile1.print(";");
      myFile1.print(">MAX");
    }
    if (temperatura < TEMP_MIN_ALARM)
    {
      myFile1.print(";");
      myFile1.print("<MIN");
    }
    myFile1.println();
  } else {
    Serial.println("Non sono riuscito a scrivere i dati.");
  }
  myFile1.close();
  delay(400);
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    boolean lineaVuota = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n' && lineaVuota) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-type: text/html");
          client.println("Connection: close");
          client.println("Refresh: 10");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<head>");
          client.println("<title>");
          client.println("Log temp. e umid.");
          client.println("</title>");
          client.println("</head>");
          client.println("<body>");
          client.println(dht.getStatusString());
          client.println("&nbsp");
          client.println(umidita);
          client.println("%");
          client.println("&nbsp");
          client.println(temperatura);
          client.println("</body>");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          lineaVuota = true;
        } else {
          if (c != '\r') {
            lineaVuota = false;
          }
        }
      }
    }
    delay(1);
    client.stop();
  }
  delay(TIMING);
}

È un progetto che sto facendo (sul quale avevo fatto anche altri post), e deve leggere un file 'OPZIONI.txt' dalla micro SD presente in questo ethernet shield, montato su un arduino UNO; successivamente andrà a creare un file con questa sintassi aaaammgg.csv, nel quale scriverà i valori ottenuti da questo sensore.
Grazie dell'attenzione.

P.S mi serve dare un nome di 8 + 3 caratteri al file creato, 8 per il nome (puo anche essere piu corto) + 3 per l'estensione del file, a causa delle restrizioni imposte dalla libreria SD.h.

EDIT: sbaglio o l'orario del post è sbagliato?

francesco01:
EDIT: sbaglio o l'orario del post è sbagliato?

Modifica il tuo "Profilo" ed imposta il Time Zone in cui ti trovi.

Guglielmo

Sei conscio che DATE e TIME somno delle costanti impostate sul valore della data e ora di compilazione e che NON variano (... se non quando ricompili il codice) ? Come pensi di usarle per ottenere un qualche cosa di utile per i tuoi scopi ? A te serve un RTC che ti dia data e ora da cui ricavare il "numero (YYYYMMGG)" per il nome file ... ::slight_smile:

Guglielmo

Ma il problema non è della funzione ma del fatto che DATE e _TIME sono delle costanti che indicano data ed ora di compilazione del programma, non giorno ed ora correnti!

Devi usare il metodo now(), vedi ad esempio QUI, e togliere quel "const" dalla tua funzione.

EDIT: In parallelo a Guglielmo :wink:

Grazie per la risposta, utilizzo DATE e TIME poiché ho l'ethernet shield montato sopra la scheda e l'RTC shield che ho a disposizione non è compatibile (link, almeno io non sono riuscito/non ho trovato le informazioni necessarie per renderlo funzionante anche sopra l'ethernet shield).
Si, sono conscio del fatto che DATE e TIME_ siano delle costanti generate al momento della compilazione, è che rifacendomi alla frase scritta qui sopra non potevo usare l RTC shield.
Provo a vedere la funzione now().
Grazie ancora per la vostra attenzione

Sì ma now() necessita di un qualche orologio. Se non riesci ad usare l'RTC (un modo c'è sicuramente), visto che hai un Ethernet shield, se sei collegato ad Internet, prendi l'ora da NTP.

DATE e TIME, forse non ti è ancora chiaro, non progrediscono col passare del tempo, sono fissate al momento della compilazione. Se questo può bastare ai tuoi scopi o meno lo devi decidere tu.

SukkoPera:
Sì ma now() necessita di un qualche orologio. Se non riesci ad usare l'RTC (un modo c'è sicuramente), visto che hai un Ethernet shield, se sei collegato ad Internet, prendi l'ora da NTP.

DATE e TIME, forse non ti è ancora chiaro, non progrediscono col passare del tempo, sono fissate al momento della compilazione. Se questo può bastare ai tuoi scopi o meno lo devi decidere tu.

Mi hai preceduto, mi sono informato un po' e now() utilizza l'RTC.
Provo a vedere l NTP.
Grazie :slight_smile:

EDIT: se doveste scoprire come mai l'RTCshield non funziona potete dirmelo? grazie :slight_smile:

francesco01:
Mi hai preceduto, mi sono informato un po' e now() utilizza l'RTC.

Hm, veramente non ho letto perché che non puoi/vuoi ad usare un RTC, anzi nel codice c'è persino la #include (ma commentata)... Per lo shield che hai bisognerebbe analizzare quali pin usa, e capire se possa andare in conflitto con la Ethernet.

Ovviamente potresti usare l'NTP per avere l'ora corrente, ma ne vale la pena visto che un RTC (non shield) è banalissimo ed economico? E che con NTP dovresti fare una interrogazione ogni volta che devi creare un nuovo file per avere giorno/ora sicuramente aggiornati vista la scarsa affidabilità di millis()?

EDIT: comunque QUI un esempio di utilizzo di quello shield, magari trovi altre informazioni per poterlo usare, ad iniziare dalle descrizioni complete dello shield e soprattutto dalla libreria usata (Jeelabs)!

Quello shield di Futura monta un DS1307 (uno degli RTC più banali da controllare anche senza alcuna libreria, basta la Wire per accedere al bus I2C e leggere/scrivere i pochi registri interni) e NON può andare in conflitto con uno shield Ethernet dato che questi usano il bus SPI.

Guglielmo

gpb01:
Quello shield di Futura monta un DS1307 (uno degli RTC più banali da controllare anche senza alcuna libreria, basta la Wire per accedere al bus I2C e leggere/scrivere i pochi registri interni) e NON può andare in conflitto con uno shield Ethernet dato che questi usano il bus SPI.

Guglielmo

Eppure, montando sopra l'ethernet shield l'RTC shield quest'ultimo non funziona. Facendo il contrario non posso scrivere sulla micro SD con l'ethernet shield.

Verifica che le schede non facciano contatto tra di loro, perché non c'è alcun motivo per cui la cosa avvenga ... ::slight_smile:


Guglielmo

gpb01:
Verifica che le schede non facciano contatto tra di loro, perché non c'è alcun motivo per cui la cosa avvenga ... ::slight_smile:


Guglielmo

I pin della scheda ethernet non sono sufficienti, quindi non tutti i pin dell'RTC shield sono collegati.
Mancano gli ultimi 2 della riga da 8 dalla parte del led, V10.
Manca l'ultimo della riga da 10, SCL.
Non so se centra e non so a cosa servano.

gpb01:
Quello shield di Futura monta un DS1307 (uno degli RTC più banali da controllare anche senza alcuna libreria, basta la Wire per accedere al bus I2C e leggere/scrivere i pochi registri interni)

Infatti nella pagina che avevo linkato è descritto tutto, proprio di QUEL chip e di QUELLO shield:

e NON può andare in conflitto con uno shield Ethernet dato che questi usano il bus SPI.

Esatto, comunque sia in quella pagina leggo alcune cose interessanti, che vanno verificate:

l connettore da 6 pin va in corrispondenza dei pin analogici, A0-A5, di Arduino; un connettore da 8 pin devi saldarlo in corrispondenza dei pin Vin, GND, GND, 5v, 3v3 e RST di Arduino ed un’altro connettore da 8 pin devi saldarlo in corrispondenza dei primi 8 pin digitali di arduino, 0-7.

I connettori da 8 e 10 sono alternativi, ossia dipende dalla scheda Arduino a cui devi collegare lo shield: se utilizzerai una Arduino Rev 3 devi usare il connettore da 10pin in corrispondenza dei pin digitali 8-13 e successivi GND, AREF, SDA ed SCL in quanto questa versione ha 2 pin in più corrispondenti proprio alle uscite SDA ed SCL che permettono alla shield di comunicare con Arduino mediante I2C collegati su questi pin. Nelle versioni precedenti alla Rev3 ( rev 2 o inferiore, duemilanove, ecc… ) questi 2 pin mancano e devi saldare il connettore da 8 pin in corrispondenza dei pin digitali 8-13 e successivi.

per iscrizione

francesco01:
I pin della scheda ethernet non sono sufficienti, quindi non tutti i pin dell'RTC shield sono collegati.
Mancano gli ultimi 2 della riga da 8 dalla parte del led, V10.
Manca l'ultimo della riga da 10, SCL.
Non so se centra e non so a cosa servano.

Non ho capito nulla ...
... sono shields SENZA tutti i pin ? ? ? :o :o :o ... o, per fare prima, non ce li hai montati tu ? Di che shield Ethernet stiamo parlando ?

Guglielmo

gpb01:
Non ho capito nulla ...
... sono shields SENZA tutti i pin ? ? ? :o :o :o ... o, per fare prima, non ce li hai montati tu ? Di che shield Ethernet stiamo parlando ?

Guglielmo

Non mi sono espresso bene, praticamente l'ethernet shield si collega a QUASI tutti i pin di arduino UNO, non si collega a gli ultimi 2 della riga dei pin analogici (IOREF e quello dopo), e dalla parte dei pin digitali non si collega agli ultimi 2 (senza nome, dopo AREF).

docdoc:
Infatti nella pagina che avevo linkato è descritto tutto, proprio di QUEL chip e di QUELLO shield:
Tutorial: RTC Shield con DS1307 - Mauro Alfieri Wearable Domotica Robotica

Esatto, comunque sia in quella pagina leggo alcune cose interessanti, che vanno verificate:

Si avevo letto quella pagina ancora prima di venire qui ma non avevo trovato soluzione. Inoltre non sono molto esperto sui circuiti, certo ho le basi che ho fatto a scuola ma molti dei simboli che usavamo noi sono diversi da quelli utilizzati e molti altri non li ho mai visti.

Ritornando all'inizio in cui parlavo dell'errore; l'ho trovato, ho tolto il ".....csv" dalla funzione e anche il const come mi ha suggerito sukkopera.

Però ora questo codice mi torna degli strani simboli (punti di domanda ?, quadratini vuoti, doppi apici ")

#include <SD.h>
#include <SPI.h>
#include <DHT.h>
#include <Wire.h>
#include <TimeLib.h>
//#include <DS1307RTC.h>
#include <Ethernet.h>

byte mac[] = {0xAA, 0xBB, 0xCC, 0x00, 0x00, 0x09};
byte ip[] = {10, 0, 0, 30};
byte subnet[] = {255, 0, 0, 0};
byte gateway[] = {10, 0, 0, 254};
EthernetServer server(80);

File myFile1, myFile2;

DHT dht;

char nomefile[16];
String nome;

int TIMING, TEMP_MAX_ALARM, TEMP_MIN_ALARM;

void logname(char const *date, char *buff) {
  int month, day, year;
  static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
  sscanf(date, "%s %d %d", buff, &day, &year);
  month = (strstr(month_names, buff) - month_names) / 3 + 1;
  sprintf(buff, "%d%02d%02d", year, month, day);
}

void setup() {
  Serial.begin(9600);
  while (!Serial)
  {
    ;
  }

  if (!SD.begin(4))
  {
    return;
  }

  myFile2 = SD.open("OPZIONI.txt");

  if (myFile2)
  {
    while (myFile2.available())
    {
      TIMING = myFile2.parseInt();
      Serial.println(TIMING);
      TEMP_MIN_ALARM = myFile2.parseInt();
      Serial.println(TEMP_MIN_ALARM);
      TEMP_MAX_ALARM = myFile2.parseInt();
      Serial.println(TEMP_MAX_ALARM);
    }
  } else {
    Serial.println("Errore in OPZIONI.txt");
  }
  myFile2.close();
  delay(600);
  logname(__DATE__, nomefile);
  nome = String(nomefile);
  Serial.println(nome);
  Serial.println("Stato\tUmidita  (%)\tTemperatura  (F)\t(C)");
  dht.setup(2);
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.println("Server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  float umidita = dht.getHumidity();
  float temperatura = dht.getTemperature();

  Serial.print(dht.getStatusString());
  Serial.print("\t\t");
  Serial.print(umidita);
  Serial.print("%");
  Serial.print("  \t\t");
  Serial.print(dht.toFahrenheit(temperatura));
  Serial.print("  \t");
  Serial.print(temperatura);
  if (temperatura < TEMP_MIN_ALARM)
  {
    Serial.print("\tTEMP<MIN");
  }
  if (temperatura > TEMP_MAX_ALARM)
  {
    Serial.print("\tTEMP>MAX");
  }
  Serial.println();
  delay(900);
  myFile1 = SD.open(nomefile, FILE_WRITE);
  if (myFile1)
  {
    Serial.println("Scrivendo/Delay");
    myFile1.print(__TIME__);
    myFile1.print(";");
    myFile1.print(dht.getStatusString());
    myFile1.print(";");
    myFile1.print(umidita);
    myFile1.print(";");
    myFile1.print(temperatura);
    myFile1.print(";");
    myFile1.print(dht.toFahrenheit(temperatura));
    if (temperatura > TEMP_MAX_ALARM)
    {
      myFile1.print(";");
      myFile1.print(">MAX");
    }
    if (temperatura < TEMP_MIN_ALARM) {
      myFile1.print(";");
      myFile1.print("<MIN");
    }
    myFile1.println();
  } else {
    Serial.println("Errore nella scrittura");
  }
  myFile1.close();
  delay(300);
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    boolean lineavuota = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n' && lineavuota) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-type: text/html");
          client.println("Connection: close");
          client.println("Refresh: 10");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<head>");
          client.println("<title>");
          client.println("Log temp. e umid.");
          client.println("</title>");
          client.println("</head>");
          client.println("<body>");
          client.println(dht.getStatusString());
          client.println("&nbsp");
          client.println(umidita);
          client.println("&nbsp");
          client.println(temperatura);
          client.println("</body>");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          lineavuota = true;
        } else {
          if (c != '\r') {
            lineavuota = false;
          }
        }
      }
    }
    delay(1);
    client.stop();
  }
  delay(TIMING);
}

E questo si verifica quando aggiungo questa parte:

myFile2 = SD.open("OPZIONI.txt");

  if (myFile2)
  {
    while (myFile2.available())
    {
      TIMING = myFile2.parseInt();
      Serial.println(TIMING);
      TEMP_MIN_ALARM = myFile2.parseInt();
      Serial.println(TEMP_MIN_ALARM);
      TEMP_MAX_ALARM = myFile2.parseInt();
      Serial.println(TEMP_MAX_ALARM);
    }
  } else {
    Serial.println("Errore in OPZIONI.txt");
  }
  myFile2.close();

francesco01:
Però ora questo codice mi torna degli strani simboli (punti di domanda ?, quadratini vuoti, doppi apici ")

Incolla l'output del monitor seriale e vediamo.

docdoc:
Incolla l'output del monitor seriale e vediamo.

Subito ecco qui:

"⸮⸮⸮⸮⸮
Stato Umidita  (%) Temperatura  (F) (C)
Server is at 
10.0.0.30
OK 43.30%   80.78   27.10 TEMP>MAX
Scrivendo/Delay
OK 43.80%   80.78   27.10 TEMP>MAX
Scrivendo/Delay
OK 43.80%   80.78   27.10 TEMP>MAX

Ovviamente non leggendo OPZIONI dirà sempre che la temperatura è maggiore di MAX poichè penso che il compilatore dia a MAX valore 0 automaticamente.

Quindi quei punti interrogativi sono sui valori letti nel setup() dal file OPZIONI.TXT, ma non capisco perché le tre variabili che dovrebbero essere degli interi vengano interpretate come se fossero solo byte, o sembra che il pareseInt() non funzioni.
Esattamente quale libreria SD stai usando?
E il file OPZIONI.TXT com'è fatto? Sicuro che non sia in un formato non corretto (ad esempio Unicode)? Se la scheda la metti nel PC e leggi il contenuto del file con un visualizzatore/editor esadecimale cosa vedi? Eventualmente potresti allegarlo qui (non dentro al messaggio, ma proprio come file allegato)?

docdoc:
Quindi quei punti interrogativi sono sui valori letti nel setup() dal file OPZIONI.TXT, ma non capisco perché le tre variabili che dovrebbero essere degli interi vengano interpretate come se fossero solo byte, o sembra che il pareseInt() non funzioni.
Esattamente quale libreria SD stai usando?
E il file OPZIONI.TXT com'è fatto? Sicuro che non sia in un formato non corretto (ad esempio Unicode)? Se la scheda la metti nel PC e leggi il contenuto del file con un visualizzatore/editor esadecimale cosa vedi? Eventualmente potresti allegarlo qui (non dentro al messaggio, ma proprio come file allegato)?

Sto usando SD.h, la libreria prederfinita.Il file è cosi:
10000
18
30
Non sono sicuro sia un un formato corretto, ve lo allego cosi potete vederlo.

OPZIONI.txt (13 Bytes)