Librerie e Timer1

Come ho scritto prima, il codice del solo interrupt funziona.

E' un codice semplice, metto il Timer1 a conteggiare e faccio scattare l'interrupt all'overflow, dopo poco più di 4 secondi. Nel codice di prova nella routine cambiavo lo stato del piedino digitale 13 facendo così accendere e spegnere il led corrispondente.

Una volta messo il tutto nel programma più complesso ho notato che l'interrupt non partiva mai. Il resto funzionava. Poiché l'SD fa uso dello stesso piedino 13 ho cambiato piedino e adesso curiosamente il programma si inchioda nel mezzo della stampa su seriale di una stringa fissa, stampa che dovrebbe avvenire prima dell'avvio della routine che abilita l'interrupt. Non ci sono altri interrupt se non quelli usati dalle librerie.
Ho anche aggiunto questa routine presa dal Playground

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

per controllare se non ci fossero problemi di RAM ma sembra che non ce ne sono. Fra l'altro tutti i print a stringa fissa hanno l'(F("") in modo che la stringa non venga ricopiata in RAM.

Prima di arrendermi e chiedere aiuto però vorrei provare a scovare l'errore o gli errori. Solo che la documentazione è un po' carente.

La routine con interrupt che funziona è quella in fondo. Il progetto è quello di un Datalogger con menù dove l'acquisizione viene fatta su interrupt in modo che vada per i fatti suoi e sia sempre possibile accedere al Datalogger via seriale. Poiché il DS1307 non ha allarmi allora sto usando il Timer1 controllando che non sia l'ora dell'acquisizione, nell'esempio 5 minuti. Le acquisizioni devono essere fatte non ogni 5 minuti ma a 0, 5, 10, 15 ecc. minuti dell'ora, in modo da poter essere confrontate con misure prese da altri datalogger. Per cui quando scatta il timer controllo che i minuti non siano un multiplo di 5. Se invece del DS1307 usassi il PCF8563 metterei un allarme li e farei dormire il datalogger per il resto del tempo in modo da consumare poco.
Questo codice di prova è un po' sporco, non usa ancora il DS1307 ma la swRTC di leo72, però funziona perfettamente. Se abilito l'interrupt, ogni 5 minuti (circa, perde qualche secondo ma non ha importanza) stampa l'orario.

Il codice lo metto nel post seguente altrimenti supero il limite di 9500 caratteri.

#include <Arduino.h>

#include <swRTC.h>

// avr-libc library includes
//http://arduinodiy.wordpress.com/2012/02/28/timer-interrupts/
#include <avr/io.h>
#include <avr/interrupt.h>

/*
Programma di test per provare la libreria swRTC e il modo di campionare ogni 5 minuti
a partire da 00. Il campionamento avviene via interrupt e quindi contemporaneamente si
gestisce un menu.
Aggiungiamo il settaggio della data e dell'ora.
Aggiungiamo lo start e stop dell'acquisizione
*/

//***************
//http://www.velocityreviews.com/forums/t316565-convert-__date__-to-unsigned-int.html
//read corrections!!!!!!
//http://lists.gnu.org/archive/html/avr-gcc-list/2009-01/msg00159.html
#define YEAR ((((__DATE__ [7] - '0') * 10 + (__DATE__ [8] - '0')) * 10 \
+ (__DATE__ [9] - '0')) * 10 + (__DATE__ [10] - '0'))

/* Month: 0 - 11 */
#define MONTH (__DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 0 : 5) \
: __DATE__ [2] == 'b' ? 1 \
: __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? 2 : 3) \
: __DATE__ [2] == 'y' ? 4 \
: __DATE__ [2] == 'l' ? 6 \
: __DATE__ [2] == 'g' ? 7 \
: __DATE__ [2] == 'p' ? 8 \
: __DATE__ [2] == 't' ? 9 \
: __DATE__ [2] == 'v' ? 10 : 11)

#define DAY ((__DATE__ [4] == ' ' ? 0 : __DATE__ [4] - '0') * 10 \
+ (__DATE__ [5] - '0'))
//*******************


#define INLENGTH 5          //Needed for input with termination
#define INTERMINATOR 13     //Needed for input with termination
char inString[INLENGTH+1];  //Needed for input with termination
int inCount;                //Needed for input with termination

#define LEDPIN 13

int ore,minuti,secondi;
//String MyString;
char Stringa2[2];
swRTC rtc;
boolean AcqDone = false;  //It's time to acquisition!
boolean InAcq = false;    //If true=Acquisition is made during intterrupt
char comm;

void GetCharFromSerial(){
    Serial.flush(); //flush all previous received and transmitted data
    inCount = 0;
          do
          {
            while (!Serial.available());             // wait for input
            inString[inCount] = Serial.read();       // get it
            //++inCount;
            if (inString [inCount] == INTERMINATOR) break;
          } while(++inCount < INLENGTH);
          inString[inCount] = 0;                     // null terminate the string
          //ch=inString;
    Serial.print("Ricevuto->");
    Serial.println(inString);
    comm=inString[0];
}

void GetTime(){
    Serial.println("Get Time");
    Serial.print(rtc.getHours(), DEC);
    Serial.print(":");
    Serial.print(rtc.getMinutes(), DEC);
    Serial.print(":");
    Serial.print(rtc.getSeconds(), DEC);
    Serial.print(" -- ");
    Serial.print(rtc.getDay(), DEC);
    Serial.print("/");
    Serial.print(rtc.getMonth(), DEC);
    Serial.print("/");
    Serial.println(rtc.getYear(), DEC);

}
void SetTime(){
    Serial.println("Set Time");
    //digitalWrite(13, LOW);
    Serial.print("Year");
    GetCharFromSerial();
    ore=atoi(inString); //Use the same variables for Year..
    Serial.print("Month");
    GetCharFromSerial();
    minuti=atoi(inString);
    Serial.print("Day");
    GetCharFromSerial();
    secondi=atoi(inString);

    rtc.stopRTC();
    rtc.setDate(ore,minuti,secondi);
    rtc.startRTC();

    Serial.print("Hour");
    GetCharFromSerial();
    ore=atoi(inString); //Use the same variables for Year..
    Serial.print("Minutes");
    GetCharFromSerial();
    minuti=atoi(inString);
    Serial.print("Seconds");
    GetCharFromSerial();
    secondi=atoi(inString);

    rtc.stopRTC();
    rtc.setTime(ore, minuti, secondi);
    rtc.startRTC();

    Serial.print("RTC changed->");
    GetTime();
}

void StartAcq(){
    Serial.println("Start Acquisition");
    if (InAcq==true) return;
    // initialize Timer1
    cli();         // disable global interrupts
    TCCR1A = 0;    // set entire TCCR1A register to 0
    TCCR1B = 0;

    // enable Timer1 overflow interrupt:
    TIMSK1 = (1 << TOIE1);

    // Set CS10 bit so timer runs at clock speed:
    TCCR1B |= (1 << CS10);
    TCCR2B &= ~(1 << CS11);
    TCCR1B |= (1 << CS12);
    //Serial.println(TCCR1B);
    // enable global interrupts:
    sei();
    InAcq=true;

}
void Download(){
    Serial.println("Download Data");
}
void StopAcq(){
    Serial.println("Stop Acquisition");
    cli();         // disable global interrupts
    TCCR1A = 0;    // set entire TCCR1A register to 0
    TCCR1B = 0;
    sei();
    InAcq=false;

}

void PrintMenu(){
    Serial.println("1 Start Acquisition");
    Serial.println("3 Stop Acquisition");
    Serial.println("8 Info");
    Serial.println("T Get Time");
    Serial.println("t Set Time");
    Serial.println("--------------------");
    Serial.println("Type the number and press enter");
}

void ParseMenu(char Stringa){
    Serial.println("Parse Menu");
    switch (Stringa) {
    case '1':
      StartAcq();
      break;
    case '2':
      Download();
      break;
    case '3':
      StopAcq();
      break;
    case '8':
      Serial.print("Acquisition->");
      Serial.println(InAcq,DEC);
      break;
    case 'T':
      GetTime();
      break;
    case 't':
      SetTime();
      break;
    default:
      Serial.print("Command Unknown! ->");
      Serial.println(Stringa,HEX);
    }
}
void setup()
{
	Serial.begin(9600);

	// initialize the digital pin as an output.
	// Pin 13 has an LED connected on most Arduino boards:
	pinMode(13, OUTPUT);

	//Initialize swRTC
	rtc.stopRTC();
	//rtc.setClockWithTimestamp(__TIMESTAMP__);
	rtc.setDate(DAY,MONTH+1,YEAR);
	//MyString=__TIMESTAMP__;
	Stringa2[0]=__TIMESTAMP__[11];
	Stringa2[1]=__TIMESTAMP__[12];
	Stringa2[2]=0;
	ore = atoi(Stringa2);

	Stringa2[0]=__TIMESTAMP__[14];
	Stringa2[1]=__TIMESTAMP__[15];
	minuti = atoi(Stringa2);

	Stringa2[0]=__TIMESTAMP__[17];
	Stringa2[1]=__TIMESTAMP__[18];
	secondi = atoi(Stringa2);
/*
	Serial.print(ore);
	Serial.print(":");
	Serial.print(minuti);
	Serial.print(":");
	Serial.println(secondi);
*/
	rtc.setTime(ore, minuti, secondi);

	rtc.startRTC();
	GetTime();

	// initialize Timer1
    cli();         // disable global interrupts
    TCCR1A = 0;    // set entire TCCR1A register to 0
    TCCR1B = 0;

    // enable Timer1 overflow interrupt:
    TIMSK1 = (1 << TOIE1);

    // Set CS10 bit so timer runs at clock speed:
    TCCR1B |= (1 << CS10);
    TCCR2B &= ~(1 << CS11);
    TCCR1B |= (1 << CS12);
    //Serial.println(TCCR1B);
    // enable global interrupts:
    sei();
    InAcq=true;

}

void loop()
{
    PrintMenu();
    GetCharFromSerial();

    ParseMenu(comm);
    //Serial.println(__TIMESTAMP__);


}

ISR(TIMER1_OVF_vect)
{
digitalWrite(LEDPIN, !digitalRead(LEDPIN));
 if (rtc.getMinutes()%5==0) {  //Se il resto è zero i minuti finiscono per zero o 5
            if (AcqDone==false){  //Siccome il controllo viene fatto ogni 30 secondi evita
                GetTime();        //che la routine scatti 2 volte ad es a 05 e 35 secondi
                //Serial.println(); //usando la boolean AcqDone
                AcqDone=true;
            }
            /*
            else {
            Serial.println(AcqDone);
            */
            }

    else
    {
        AcqDone=false;
    }
}

Con la swRTC non hai problemi perché essa usa il timer 2.

Infatti, la tua libreria è ben documentata, sapevo che usava un altro Timer.

Nel programma il blocco avviene in questa routine, presente anche nell'esempio messo sopra.

void GetCharFromSerial(){
   //Get string from serial and put in inString
   //first letter in comm
    Serial.flush(); //flush all previous received and transmitted data
    inCount = 0;
          do
          {
            while (!Serial.available());             // wait for input
            inString[inCount] = Serial.read();       // get it
            //++inCount;
            if (inString [inCount] == INTERMINATOR) break;
          } while(++inCount < INLENGTH);
          inString[inCount] = 0;                     // null terminate the string
          //ch=inString;
    Serial.print(F("Ricevuto->"));
    Serial.println(inString);
    comm=inString[0];
}

Si pianta dopo aver stampato il "Ri" di "Ricevuto". In questa fase ancora l'interrupt non è stato avviato. Mi chiedo se non sia un problema di questa routine, magari diverso da quello dell'interrupt, anche se nell'esempio per il timer che ho postato sopra e in altri sketch non mi ha dato problemi. La stringa che riceve è di un solo carattere terminata con il CR (ASCII 13).

Ho copiato il tuo sketch. Compila, ma l'IDE (formattazione automatica) mi dice che c'è una parentesi chiusa di troppo.
Boh!

Anche a me!

CodeBlock invece non si lamenta.

Il codice della routine seriale non è farina del mio sacco ma l'ho preso qui
http://forums.adafruit.com/viewtopic.php?f=8&t=9918
anche se poi l'ho trovato in diversi forum. L'alternativa scritta sotto dall'utente PockyBum522 non mi funziona, mi ritrovo sempre con una stringa vuota, sebbene questo codice l'ho trovato in diversi post di questo forum. Però io l'ho adattata, ora provo l'esempio così com'è scritto.

Edit:
non funziona neanche quella originale che sarebbe questa

    void setup() {
      pinMode(13, OUTPUT);
      Serial.begin(9600); // Initialize serial port
    }

    void loop()
    {
      serialReader();
    }

    void serialReader(){
      int makeSerialStringPosition;
      int inByte;
      char serialReadString[50];
      const int terminatingChar = 13; //Terminate lines with CR

      inByte = Serial.read();
      makeSerialStringPosition=0;

      if (inByte > 0 && inByte != terminatingChar) { //If we see data (inByte > 0) and that data isn't a carriage return
        delay(100); //Allow serial data time to collect (I think. All I know is it doesn't work without this.)

        while (inByte != terminatingChar && Serial.available() > 0){ // As long as EOL not found and there's more to read, keep reading
          serialReadString[makeSerialStringPosition] = inByte; // Save the data in a character array
          makeSerialStringPosition++; //Increment position in array
          //if (inByte > 0) Serial.println(inByte); // Debug line that prints the charcodes one per line for everything recieved over serial
          inByte = Serial.read(); // Read next byte
        }

        if (inByte == terminatingChar) //If we terminated properly
        {
          serialReadString[makeSerialStringPosition] = 0; //Null terminate the serialReadString (Overwrites last position char (terminating char) with 0
          Serial.println(serialReadString);
          if (strcmp(serialReadString, "LEDOn") == 0) digitalWrite(13, HIGH);
          if (strcmp(serialReadString, "LEDOff") == 0) digitalWrite(13, LOW);
        }
      }
    }

non stampa nulla e il led non si accende mai!

Affinché funzioni devi selezionare nel serial monitor il carattere CR "ritorno a capo" come fine riga nel menu a tendina accanto al baudrate.

Sul perché non funzioni, la funzione strcmp non restituisce quello che deve, ho fatto un Serial.print e quando serialReadString è uguale a "LEDon" o "LEDoff" la funzione restituisce 32 come valore invece di 0, non so il perché.

Ho riscritto tutto per usare l'oggetto String e funziona perfettamente.

void setup() {
    pinMode(13, OUTPUT);
    Serial.begin(19200); // Initialize serial port
    delay(2000);
}

void loop() {
    serialReader();
}

void serialReader() {
    char inByte;
    String serialReadString = "";
    const char terminatingChar = 13; //Terminate lines with CR

    inByte = Serial.read();

    if (inByte > 0 && inByte != terminatingChar) { //If we see data (inByte > 0) and that data isn't a carriage return
        delay(100); //Allow serial data time to collect (I think. All I know is it doesn't work without this.)

        while (inByte != terminatingChar && Serial.available() > 0) { // As long as EOL not found and there's more to read, keep reading
            serialReadString += String(inByte); // Save the data in a character array
            //if (inByte > 0) Serial.println(inByte); // Debug line that prints the charcodes one per line for everything recieved over serial
            inByte = Serial.read(); // Read next byte
        }

        if (inByte == terminatingChar) {//If we terminated properly
            Serial.println(serialReadString);
            if (serialReadString == "LEDOn") {
                digitalWrite(13, HIGH);
            }
            if (serialReadString == "LEDOff") {
                digitalWrite(13, LOW);
            }
        }
    }
}

Ti ringrazio!

Io non usavo il monitor incluso nell'IDE ma usandolo ho scoperto che funziona. La cosa curiosa è che se nel programma monitor che ho uso lo stesso meccanismo di quello dell'IDE, cioè metto la stringa in una casella e poi premo SEND, allora funziona, mentre se uso la casella dove i caratteri vengono mandati immediatamente, non funziona nonostante vedo che i caratteri vengono mandati come posso vedere dal led che lampeggia.

Sembra che la routine non funzioni correttamente, non attenda cioè il CR se i caratteri non vengono mandati tutti in una volta, come se avesse un timeout che la facesse uscire.
Quella precedente invece aspetta il CR, anche indefinitivamente, ma curiosamente nello sketch più completo si inchioda in un Serial.println, dopo che la stringa è stata ricevuta e dopo aver stampato solo due lettere. Poiché si inchioda sempre alla stessa maniera significa che la causa non è random e ho speranze di trovarla.

In questa routine, invece, non credo sia un problema di strcmp perché il Serial.println che lo precede dovrebbe in ogni caso stampare qualcosa e invece non stampa nulla.

Cobeblock ha un simulatore comodo ma gli interrupt non funzionano e la seriale viene simulata collegandosi alla seriale del PC, per cui mi serve un altro dispositivo. Ci sarebbe un programmino che simula una coppia di seriali collegate fra loro ma sul Seven a 64 bit a che ricordi io non funziona.

Nel tuo sketch originale a me il Serial.print stampava quello che riceveva, bastava mettere CR come carattere per l'invio.

A me non funziona neanche con l'Hyperterminal.

Sembra proprio che se i caratteri vengono mandati uno alla volta, digitandoli da tastiera, non funzioni anche se i caratteri arrivano all'Arduino come posso vedere dal LED. Inoltre ho l'eco locale per cui vedo che il return c'è, in Hyperterminal infatti ritorna all'inizio della riga perché non c'è il LineFeed.

Funziona solo se metto la stringa in una casella e questa viene sparata tutta in una volta, sia nell'IDE sia nel programma terminale che uso.

Edit: sono tornato alla routine precedente (che invece funziona perfettamente) e ho scoperto il motivo dell'inchiodamento. Nella routine dell'interrupt era presente un Serial.Print che, una volta commentato, non inchioda più l'Arduino. Non me ne spiego il motivo visto che tale routine dovrebbe essere inattiva e l'inchiodamento avviene prima dell'attivazione. Provo un'idea che mi è venuta....

Ma lo sketch che ti ho passato a te funziona oppure no?

Si, ma solo se mando le stringa come nell'IDE Arduino, cioè viene mandata tutta in una volta. Se invece digito il comando da tastiera, e ogni tasto che premo viene mandato immediatamente, allora non funziona, sembra che non aspetti il CR. La routine precedente invece funziona in entrambi i modi, aspetta il CR a tempo indefinito.

Frattanto dopo aver scoperto che il Serial.println presente nella routine di interrupt inchiodava Arduino ho provato ad azzerare i registri del Timer1 ma il tutto continua a non funzionare, il dannato led non si accende.

zoomx:
il dannato led non si accende

Se non va neanche così... è il led! :grin:

const byte led = 13;

void setup() {                
   pinMode(led, OUTPUT);     
}

void loop() {
  digitalWrite(led, HIGH);   
  delay(1000);               
  digitalWrite(led, LOW);    
  delay(1000);               
}

Il led funziona.

Nel programma ho messo un'istruzione che esplicitamente accende e spegne il led e funziona.

Edit: forse ho scoperto perché l'IDE segnalava un problema con le parentesi: conta una delle parentesi commentate.
Questa qui

/*
            else {
            Serial.println(AcqDone);
            */

Però correttamente il compilatore non la considera.

... guarda che quel commento, messo così E' SBAGLIATO !!!

Tu commenti un "else {" il che significa che hai commentato una apertura di graffa, ma ... da qualche parte, nel codice, c'è una chiusura di graffa che rimane appesa e che può creare grossi problemi !

Se commenti la prima DEVI commentare anche la seconda :wink:

Guglielmo

gpb, questo è un vero rompicapo.
Se commento la parentesi chiusa dopo l'else il compilatore ri inca@@a :fearful:
Ma se la lasco, compila, ma l'IDE segnala un errore nel conteggio delle parentesi.
Adesso mi stampo lo sketch e le depenno a mano. :grin: :grin:

@Paolo : Bé ... probabilmente perché comunque resta della roba messa li così ... per fare una cosa fatta bene dovresti mettere l'inizio commento (/) dove è adesso, ovvero prima dell'else e il fine commento (/) dopo la parentesi graffa di chiusura dell'else così da eliminare TUTTO quello che è compreso nell'else. :wink:

Poi ... se nell'IDE ti posizioni su una graffa, lui ti evidenzia la corrispondente di chiusura, quindi ... fai presto a fare il match :slight_smile:

Guglielmo

L'IDE faceva il match con una delle parentesi dentro il commento, non so perché ma è evidentemente un errore. Eliminando la parte commentata, che non serviva, l'IDE non ha più avuto problemi e ha accoppiato correttamente le parentesi. La formattazione automatica non si inceppa più.
Può essere che il commento sia stato fatto parzialmente perché poi ho riciclato la parentesi, ormai non ricordo più. Il codice è parzialmente copiato, l'originale non ricordo dove l'ho preso ma si trova facilmente nei forum, probabilmente anche in questo.

Sto meditando se arrendermi e postare tutto il codice in un altro argomento. Non mi funziona la scrittura su SD ma gli esempi funzionano. A proposito, negli esempi sembra che si faccia un po' di confusione sulla linea CS, diversa a seconda se si usi la SD della Ethernet shield (4) oppure lo shield apposito (10). Apro il file ma quando sto per scrivere mi va in reset.
Inoltre non funziona più la scrittura sul DS1307 del tempo corretto, lo leggo ma non riesco più a correggerlo, sebbene non abbia toccato una sola riga.
In altre parole singolarmente gli algoritmi funzionano ma quando metto tutto assieme no. Il programma è sotto i 22.000 byte, di RAM sembra ne rimanga un po' meno di 700 per cui non si dovrebbe trattare di un problema di memoria. Non dovrebbe essere un problema di lunghezza dei fili di collegamento, sono sui 20cm e con le routine singole non ho avuto problemi.

Adesso stacco e magari preparo per domani un post pulito con la versione precedente che funziona, almeno così mi sembrava.

Il problema è qui

/* Month: 0 - 11 */
#define MONTH (__DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 0 : 5) \
: __DATE__ [2] == 'b' ? 1 \
: __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? 2 : 3) \
: __DATE__ [2] == 'y' ? 4 \
: __DATE__ [2] == 'l' ? 6 \
: __DATE__ [2] == 'g' ? 7 \
: __DATE__ [2] == 'p' ? 8 \
: __DATE__ [2] == 't' ? 9 \
: __DATE__ [2] == 'v' ? 10 : 11)

Se si mette tutto su una sola riga compila e l'IDE non da errori. Credo sia un bug.

// #include <Arduino.h>
#include <swRTC.h>
// #include <avr/io.h>
// #include <avr/interrupt.h>

#define YEAR ((((__DATE__ [7] - '0') * 10 + (__DATE__ [8] - '0')) * 10 + (__DATE__ [9] - '0')) * 10 + (__DATE__ [10] - '0'))

//* Month: 0 - 11 */
#define MONTH (__DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 0 : 5) : __DATE__ [2] == 'b' ? 1 : __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? 2 : 3) : __DATE__ [2] == 'y' ? 4 : __DATE__ [2] == 'l' ? 6 : __DATE__ [2] == 'g' ? 7 : __DATE__ [2] == 'p' ? 8 : __DATE__ [2] == 't' ? 9 : __DATE__ [2] == 'v' ? 10 : 11)
#define DAY ((__DATE__ [4] == ' ' ? 0 : __DATE__ [4] - '0') * 10 + (__DATE__ [5] - '0'))
//*******************

#define INLENGTH 5          //Needed for input with termination
#define INTERMINATOR 13     //Needed for input with termination

char inString[INLENGTH+1];  //Needed for input with termination
int inCount;                //Needed for input with termination

#define LEDPIN 13

int ore,minuti,secondi;
//String MyString;
char Stringa2[2];
swRTC rtc;
boolean AcqDone = false;  //It's time to acquisition!
boolean InAcq = false;    //If true=Acquisition is made during intterrupt
char comm;

void GetCharFromSerial() {
  Serial.flush(); //flush all previous received and transmitted data
  inCount = 0;
  do
  {
    while (!Serial.available());             // wait for input
    inString[inCount] = Serial.read();       // get it
    //++inCount;
    if (inString [inCount] == INTERMINATOR) break;
  } 
  while(++inCount < INLENGTH);
  inString[inCount] = 0;                     // null terminate the string
  //ch=inString;
  Serial.print("Ricevuto->");
  Serial.println(inString);
  comm=inString[0];
}

void GetTime() {
  Serial.println("Get Time");
  Serial.print(rtc.getHours(), DEC);
  Serial.print(":");
  Serial.print(rtc.getMinutes(), DEC);
  Serial.print(":");
  Serial.print(rtc.getSeconds(), DEC);
  Serial.print(" -- ");
  Serial.print(rtc.getDay(), DEC);
  Serial.print("/");
  Serial.print(rtc.getMonth(), DEC);
  Serial.print("/");
  Serial.println(rtc.getYear(), DEC);
}

void SetTime() {
  Serial.println("Set Time");
  //digitalWrite(13, LOW);
  Serial.print("Year");
  GetCharFromSerial();
  ore=atoi(inString); //Use the same variables for Year..
  Serial.print("Month");
  GetCharFromSerial();
  minuti=atoi(inString);
  Serial.print("Day");
  GetCharFromSerial();
  secondi=atoi(inString);
  rtc.stopRTC();
  rtc.setDate(ore,minuti,secondi);
  rtc.startRTC();
  Serial.print("Hour");
  GetCharFromSerial();
  ore=atoi(inString); //Use the same variables for Year..
  Serial.print("Minutes");
  GetCharFromSerial();
  minuti=atoi(inString);
  Serial.print("Seconds");
  GetCharFromSerial();
  secondi=atoi(inString);
  rtc.stopRTC();
  rtc.setTime(ore, minuti, secondi);
  rtc.startRTC();
  Serial.print("RTC changed->");
  GetTime();
}

void StartAcq() {
  Serial.println("Start Acquisition");
  if (InAcq==true) return;
  // initialize Timer1
  cli();         // disable global interrupts
  TCCR1A = 0;    // set entire TCCR1A register to 0
  TCCR1B = 0;

  // enable Timer1 overflow interrupt:
  TIMSK1 = (1 << TOIE1);

  // Set CS10 bit so timer runs at clock speed:
  TCCR1B |= (1 << CS10);
  TCCR2B &= ~(1 << CS11);
  TCCR1B |= (1 << CS12);
  //Serial.println(TCCR1B);
  // enable global interrupts:
  sei();
  InAcq = true;
}

void Download() {
  Serial.println("Download Data");
}

void StopAcq() {
  Serial.println("Stop Acquisition");
  cli();         // disable global interrupts
  TCCR1A = 0;    // set entire TCCR1A register to 0
  TCCR1B = 0;
  sei();
  InAcq=false;
}

void PrintMenu() {
  Serial.println("1 Start Acquisition");
  Serial.println("3 Stop Acquisition");
  Serial.println("8 Info");
  Serial.println("T Get Time");
  Serial.println("t Set Time");
  Serial.println("--------------------");
  Serial.println("Type the number and press enter");
}

void ParseMenu(char Stringa) {
  Serial.println("Parse Menu");
  switch (Stringa) {
  case '1':
    StartAcq();
    break;
  case '2':
    Download();
    break;
  case '3':
    StopAcq();
    break;
  case '8':
    Serial.print("Acquisition->");
    Serial.println(InAcq,DEC);
    break;
  case 'T':
    GetTime();
    break;
  case 't':
    SetTime();
    break;
  default:
    Serial.print("Command Unknown! ->");
    Serial.println(Stringa,HEX);
  }
}

void setup() {
  Serial.begin(9600);
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(13, OUTPUT);
  //Initialize swRTC
  rtc.stopRTC();
  //rtc.setClockWithTimestamp(__TIMESTAMP__);
  rtc.setDate(DAY,MONTH+1,YEAR);
  //MyString=__TIMESTAMP__;
  Stringa2[0]=__TIMESTAMP__[11];
  Stringa2[1]=__TIMESTAMP__[12];
  Stringa2[2]=0;
  ore = atoi(Stringa2);

  Stringa2[0]=__TIMESTAMP__[14];
  Stringa2[1]=__TIMESTAMP__[15];
  minuti = atoi(Stringa2);

  Stringa2[0]=__TIMESTAMP__[17];
  Stringa2[1]=__TIMESTAMP__[18];
  secondi = atoi(Stringa2);
  ///*
  //	Serial.print(ore);
  //	Serial.print(":");
  //	Serial.print(minuti);
  //	Serial.print(":");
  //	Serial.println(secondi);
  //*/
  rtc.setTime(ore, minuti, secondi);
  rtc.startRTC();
  GetTime();

  // initialize Timer1
  cli();         // disable global interrupts
  TCCR1A = 0;    // set entire TCCR1A register to 0
  TCCR1B = 0;

  // enable Timer1 overflow interrupt:
  TIMSK1 = (1 << TOIE1);

  // Set CS10 bit so timer runs at clock speed:
  TCCR1B |= (1 << CS10);
  TCCR2B &= ~(1 << CS11);
  TCCR1B |= (1 << CS12);
  //Serial.println(TCCR1B);
  // enable global interrupts:
  sei();
  InAcq = true;
}

void loop()
{
  PrintMenu();
  GetCharFromSerial();
  ParseMenu(comm);
  //Serial.println(__TIMESTAMP__);
}

ISR(TIMER1_OVF_vect) {
  digitalWrite(LEDPIN, !digitalRead(LEDPIN));
  if ( rtc.getMinutes()%5==0 )  //Se il resto è zero i minuti finiscono per zero o 5
  { 
    if (AcqDone == false)
    {  //Siccome il controllo viene fatto ogni 30 secondi evita
      GetTime();        //che la routine scatti 2 volte ad es a 05 e 35 secondi
      //Serial.println(); //usando la boolean AcqDone
      AcqDone = true;
    }
    /*
    else {
     Serial.println(AcqDone);
     }
     */
  }
  else
  {
    AcqDone=false;
  }
}

NO, il problema è che nell'ultima funzione ( ISR(TIMER1_OVF_vect) ) hai fatto un casino con le parentesi XD XD XD

#include <Arduino.h>

#include <swRTC.h>

// avr-libc library includes
//http://arduinodiy.wordpress.com/2012/02/28/timer-interrupts/
#include <avr/io.h>
#include <avr/interrupt.h>

/*
Programma di test per provare la libreria swRTC e il modo di campionare ogni 5 minuti
a partire da 00. Il campionamento avviene via interrupt e quindi contemporaneamente si
gestisce un menu.
Aggiungiamo il settaggio della data e dell'ora.
Aggiungiamo lo start e stop dell'acquisizione
*/

//***************
//http://www.velocityreviews.com/forums/t316565-convert-__date__-to-unsigned-int.html
//read corrections!!!!!!
//http://lists.gnu.org/archive/html/avr-gcc-list/2009-01/msg00159.html
#define YEAR ((((__DATE__ [7] - '0') * 10 + (__DATE__ [8] - '0')) * 10 \
+ (__DATE__ [9] - '0')) * 10 + (__DATE__ [10] - '0'))

/* Month: 0 - 11 */
#define MONTH (__DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 0 : 5) \
: __DATE__ [2] == 'b' ? 1 \
: __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? 2 : 3) \
: __DATE__ [2] == 'y' ? 4 \
: __DATE__ [2] == 'l' ? 6 \
: __DATE__ [2] == 'g' ? 7 \
: __DATE__ [2] == 'p' ? 8 \
: __DATE__ [2] == 't' ? 9 \
: __DATE__ [2] == 'v' ? 10 : 11)

#define DAY ((__DATE__ [4] == ' ' ? 0 : __DATE__ [4] - '0') * 10 \
+ (__DATE__ [5] - '0'))
//*******************


#define INLENGTH 5          //Needed for input with termination
#define INTERMINATOR 13     //Needed for input with termination
char inString[INLENGTH+1];  //Needed for input with termination
int inCount;                //Needed for input with termination

#define LEDPIN 13

int ore,minuti,secondi;
//String MyString;
char Stringa2[2];
swRTC rtc;
boolean AcqDone = false;  //It's time to acquisition!
boolean InAcq = false;    //If true=Acquisition is made during intterrupt
char comm;

void GetCharFromSerial()
{
    Serial.flush(); //flush all previous received and transmitted data
    inCount = 0;
          do
          {
            while (!Serial.available());             // wait for input
            inString[inCount] = Serial.read();       // get it
            //++inCount;
            if (inString [inCount] == INTERMINATOR) break;
          } while(++inCount < INLENGTH);
          inString[inCount] = 0;                     // null terminate the string
          //ch=inString;
    Serial.print("Ricevuto->");
    Serial.println(inString);
    comm=inString[0];
}

void GetTime()
{
    Serial.println("Get Time");
    Serial.print(rtc.getHours(), DEC);
    Serial.print(":");
    Serial.print(rtc.getMinutes(), DEC);
    Serial.print(":");
    Serial.print(rtc.getSeconds(), DEC);
    Serial.print(" -- ");
    Serial.print(rtc.getDay(), DEC);
    Serial.print("/");
    Serial.print(rtc.getMonth(), DEC);
    Serial.print("/");
    Serial.println(rtc.getYear(), DEC);

}

void SetTime()
{
    Serial.println("Set Time");
    //digitalWrite(13, LOW);
    Serial.print("Year");
    GetCharFromSerial();
    ore=atoi(inString); //Use the same variables for Year..
    Serial.print("Month");
    GetCharFromSerial();
    minuti=atoi(inString);
    Serial.print("Day");
    GetCharFromSerial();
    secondi=atoi(inString);

    rtc.stopRTC();
    rtc.setDate(ore,minuti,secondi);
    rtc.startRTC();

    Serial.print("Hour");
    GetCharFromSerial();
    ore=atoi(inString); //Use the same variables for Year..
    Serial.print("Minutes");
    GetCharFromSerial();
    minuti=atoi(inString);
    Serial.print("Seconds");
    GetCharFromSerial();
    secondi=atoi(inString);

    rtc.stopRTC();
    rtc.setTime(ore, minuti, secondi);
    rtc.startRTC();

    Serial.print("RTC changed->");
    GetTime();
}

void StartAcq()
{
    Serial.println("Start Acquisition");
    if (InAcq==true) return;
    // initialize Timer1
    cli();         // disable global interrupts
    TCCR1A = 0;    // set entire TCCR1A register to 0
    TCCR1B = 0;

    // enable Timer1 overflow interrupt:
    TIMSK1 = (1 << TOIE1);

    // Set CS10 bit so timer runs at clock speed:
    TCCR1B |= (1 << CS10);
    TCCR2B &= ~(1 << CS11);
    TCCR1B |= (1 << CS12);
    //Serial.println(TCCR1B);
    // enable global interrupts:
    sei();
    InAcq=true;

}

void Download()
{
    Serial.println("Download Data");
}

void StopAcq()
{
    Serial.println("Stop Acquisition");
    cli();         // disable global interrupts
    TCCR1A = 0;    // set entire TCCR1A register to 0
    TCCR1B = 0;
    sei();
    InAcq=false;

}

void PrintMenu()
{
    Serial.println("1 Start Acquisition");
    Serial.println("3 Stop Acquisition");
    Serial.println("8 Info");
    Serial.println("T Get Time");
    Serial.println("t Set Time");
    Serial.println("--------------------");
    Serial.println("Type the number and press enter");
}

void ParseMenu(char Stringa)
{
    Serial.println("Parse Menu");
    switch (Stringa) {
    case '1':
      StartAcq();
      break;
    case '2':
      Download();
      break;
    case '3':
      StopAcq();
      break;
    case '8':
      Serial.print("Acquisition->");
      Serial.println(InAcq,DEC);
      break;
    case 'T':
      GetTime();
      break;
    case 't':
      SetTime();
      break;
    default:
      Serial.print("Command Unknown! ->");
      Serial.println(Stringa,HEX);
    }
}

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

	// initialize the digital pin as an output.
	// Pin 13 has an LED connected on most Arduino boards:
	pinMode(13, OUTPUT);

	//Initialize swRTC
	rtc.stopRTC();
	//rtc.setClockWithTimestamp(__TIMESTAMP__);
	rtc.setDate(DAY,MONTH+1,YEAR);
	//MyString=__TIMESTAMP__;
	Stringa2[0]=__TIMESTAMP__[11];
	Stringa2[1]=__TIMESTAMP__[12];
	Stringa2[2]=0;
	ore = atoi(Stringa2);

	Stringa2[0]=__TIMESTAMP__[14];
	Stringa2[1]=__TIMESTAMP__[15];
	minuti = atoi(Stringa2);

	Stringa2[0]=__TIMESTAMP__[17];
	Stringa2[1]=__TIMESTAMP__[18];
	secondi = atoi(Stringa2);
/*
	Serial.print(ore);
	Serial.print(":");
	Serial.print(minuti);
	Serial.print(":");
	Serial.println(secondi);
*/
	rtc.setTime(ore, minuti, secondi);

	rtc.startRTC();
	GetTime();

	// initialize Timer1
    cli();         // disable global interrupts
    TCCR1A = 0;    // set entire TCCR1A register to 0
    TCCR1B = 0;

    // enable Timer1 overflow interrupt:
    TIMSK1 = (1 << TOIE1);

    // Set CS10 bit so timer runs at clock speed:
    TCCR1B |= (1 << CS10);
    TCCR2B &= ~(1 << CS11);
    TCCR1B |= (1 << CS12);
    //Serial.println(TCCR1B);
    // enable global interrupts:
    sei();
    InAcq=true;

}

void loop()
{
    PrintMenu();
    GetCharFromSerial();

    ParseMenu(comm);
    //Serial.println(__TIMESTAMP__);


}

ISR(TIMER1_OVF_vect)
{
  digitalWrite(LEDPIN, !digitalRead(LEDPIN));
  
  if (rtc.getMinutes()%5 == 0) {
  
    if (AcqDone == false) {  //Siccome il controllo viene fatto ogni 30 secondi evita
      GetTime();        //che la routine scatti 2 volte ad es a 05 e 35 secondi
      //Serial.println(); //usando la boolean AcqDone
      AcqDone=true;
    }
    else {
      /*
      Serial.println(AcqDone);
      */
    }
  } 
  else
  {
    AcqDone=false;
  }
}

Toh ... questo lo compila correttamente :wink:

Guglielmo