Libreria MsTimer2.h

Ciao a tutti,

ho implementato in un piccolo progettino la libreria in oggetto "MsTimer2.h" con il relativo codice di contorno:

#include <MsTimer2.h>           // Include files for MsTimer2 library 

unsigned long timer=3600000; // Log file is written every 60 minutes (3600000)
int writeLog=0;

void setup(void)  
{
  // Initialize timer 
  MsTimer2::set(timer, flushCounter); 
  MsTimer2::start(); 
}

void loop(){
// Write the log file if interrupt has been called 
  if (writeLog==1) 
  {     
    String logStr = ""; 
    
    logStr = String(RTC_TimeStamp) + ";";
    logStr += String(flash) +  ";";
    write_log(logStr); 

    writeLog=0; 
    flash=0;  
  } 
}

// Routine executed by the timer interrupt. This flush the  
// data to the log file 
void flushCounter(void) 
{ 
  Serial.println("flushCounter");
  writeLog = 1; 
}

tralasciando parti di codice già testato e funzionante (gestione bus I2C, uSD, ecc..), ho notato che il timestamp proveniente da RTC non è allineato con il periodo di "timer" (60min), esempio:

timestamp  |  watt  |	  data ora

1377129227	638	mercoledì 21/08/2013 23:53:47
1377132835	308	giovedì 22/08/2013 00:53:55
1377136443	211	giovedì 22/08/2013 01:54:03
1377140051	207	giovedì 22/08/2013 02:54:11
1377143659	195	giovedì 22/08/2013 03:54:19
1377147267	200	giovedì 22/08/2013 04:54:27
1377150875	188	giovedì 22/08/2013 05:54:35
1377154483	223	giovedì 22/08/2013 06:54:43
1377158090	953	giovedì 22/08/2013 07:54:50
1377161698	900	giovedì 22/08/2013 08:54:58
1377165306	366	giovedì 22/08/2013 09:55:06
1377168914	207	giovedì 22/08/2013 10:55:14
1377172522	177	giovedì 22/08/2013 11:55:22
1377176130	180	giovedì 22/08/2013 12:55:30
1377179738	204	giovedì 22/08/2013 13:55:38
1377183346	217	giovedì 22/08/2013 14:55:46
1377186954	341	giovedì 22/08/2013 15:55:54
1377190562	352	giovedì 22/08/2013 16:56:02
1377194170	334	giovedì 22/08/2013 17:56:10
1377197778	323	giovedì 22/08/2013 18:56:18
1377201386	334	giovedì 22/08/2013 19:56:26

io mi aspetterei una registrazione ogni ora, con un ragionevole ritardo dovuto alla composizione della stringa da scrivere su SD + la scrittura su SD... ed inoltre mi aspetterei che l'interrupt funzioni come tale... invece sembra che ritardi ogni volta che viene reinizializzato il timer...

facendo la differenza tra il primo timestamp ed il successivo e cosi via, ho un ritardo fisso di 3608ms di conseguenza lo slittamento delle registrazioni orarie come si vede dalla tabella qui sopra...

Hardware utilizzato:

  • ArduinoUno
  • Ethernet shield uSD
  • RTC DS1307

avete qualche idea?

saluti
kattivik76

p.s.: dimenticavo il link della libreria -> Arduino Playground - MsTimer2

Ma tu la registrazione la fai usando la libreria? La MsTimer2 se non ricordo male è una lib che permette di programmare dei compiti eseguibili a determinati orari. Ma questa lib l'orario lo prende dall'RTC anche per controllare quando eseguire i compiti oppure l'RTC lo usa solo per sincronizzarsi e l'orario lo scandisce internamente con il timer del chip?
In questo secondo caso il disallineamento è da imputare all'imprecisione del risuonatore ceramico usato sull'Arduino.

no no,

la MsTimer2 gestisce solo il timer di 60min impostato, tutto il resto è affidato ad altre librerie, di seguito gli sketch realizzati.

Enerduino.ino (modificato)

/*
Enerduino 
  
version 0.3 
  
 Internal revision:
 *** Enerduino.ino 16.08.2013 - improve functions from original Enerduino v0.2 (written by Cesare Pizzi), convert sketch from IDE 1.x
  
 Author: Alessandro Migliorini
  
 This simple Arduino application allow to monitor power consumpion by checking the flashing  
 light of the power meter. 
 There are 2 lights on italian ENEL power meters: RA (active) and RR (reactive). 
 Only RA led is computed for home contracts 
 One flash should be 1 w/h 
 
 SD scheme:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
*/

#include <stdlib.h> 
#include <SD.h>                 // include files for SD library
#include <Wire.h>               // include files for I2C bus
#include "RTClib.h"             // include files for I2C DS1307 RealTime Clock 
#include <MsTimer2.h>           // Include files for MsTimer2 library 
#include <LiquidCrystal_I2C.h>  // include files for I2C LCD

LiquidCrystal_I2C lcd(0x27,20,4);

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;

// The PIN to power the SD card shield 
#define MEM_PW    10 

// Analog input for photoresistor 
#define PHOTO_IN  0 

// Digital outpot for flash led
#define ledflash  2

// analog supply
#define analog_vcc A3
#define analog_gnd A2

unsigned long timer=3600000; // Log file is written every 60 minutes (3600000)  FIXME 
unsigned long flash=0; 
int threshold=500;     // If photoresistor read more than this value, it count a flash 
int writeLog=0; 

// create RTC object
RTC_DS1307 RTC;

// RTC Variables
int RTC_year = 0;
int RTC_month = 0;
int RTC_day = 0;
int RTC_hour = 0;
int RTC_minute = 0;
int RTC_second = 0;
int RTC_dayOfWeek = 0;
uint32_t RTC_TimeStamp = 0;

// Arduino setup routine 
void setup(void)  
{ 
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
    while (!Serial) {
      ; // wait for serial port to connect. Needed for Leonardo only
    }
    
  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(MEM_PW, OUTPUT);
  
  // define output for led
  pinMode(ledflash, OUTPUT);
  digitalWrite(ledflash,LOW);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  
  // powerup supply for I2C bus
  pinMode(analog_vcc, OUTPUT);
  pinMode(analog_gnd, OUTPUT);
  digitalWrite(analog_vcc,HIGH);
  digitalWrite(analog_gnd,LOW);
  delay(250);
  
  // initialize I2C bus
  Wire.begin();
  
  // initialize LDC  
  lcd.init(); 
  lcd.backlight();    // switch on backlight  
  // splash screen
  lcd.setCursor(0, 0);
  lcd.print("Controllo consumi KW");
  lcd.setCursor(0, 1);
  lcd.print("giornalieri con mem.");
  lcd.setCursor(0, 2);
  lcd.print("su uSD ogni ora.");  
  lcd.setCursor(0, 3);
  lcd.print("SW by A.Migliorini");
  delay(2000);
  
  // initialize RTC clock
  RTC.begin();
  
  // check RTC is alive
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  
  // Setup for photoresistor 
  pinMode(PHOTO_IN,INPUT); 

  // Initialize timer 
  MsTimer2::set(timer, flushCounter); 
  MsTimer2::start();  
} 

// Main 
void loop(void)  
{
  // make a string for assembling the data to log:
  String dataString = "";
  
  //Serial.println(analogRead(PHOTO_IN));  // FIXME 
    
  // Read the photo sensor value 
  if (analogRead(PHOTO_IN) > threshold) 
  { 
    // read and parse RTC data from DS1307
    read_RTC();
  
    digitalWrite(ledflash,HIGH);
    flash++;
    
    dataString = getDate(); 
    dataString += " ";
    dataString += getClock();
    
    lcd.setCursor(0, 1);
    lcd.print("T: " + dataString);
    
    lcd.setCursor(0, 2);
    lcd.print("Flash: " + flash);
    
    dataString = String(flash/1000);
    
    lcd.setCursor(0, 3);
    lcd.print("Energia: " + dataString + " KW" );
    
    Serial.print("Flash: ");       // FIXME
    Serial.println(flash);  
    while (analogRead(PHOTO_IN) > threshold) 
    { 
    // Just wait the flash to turn off (to avoid multiple counts)    
    }  
    digitalWrite(ledflash,LOW);
  } 

// Write the log file if interrupt has been called 
  if (writeLog==1) 
  {     
    String logStr = ""; 
    
    logStr = String(RTC_TimeStamp) + ";";
    logStr += String(flash) +  ";";
    write_log(logStr); 

    writeLog=0; 
    flash=0;  
  } 
}

functions.ino

void read_RTC(){
  char strDay[10];
  char strMonth[15];
  
  DateTime now = RTC.now();
  RTC_TimeStamp = now.unixtime();
  RTC_year = now.year();
  RTC_month = now.month();
  RTC_day = now.day();
  RTC_hour = now.hour();
  RTC_minute = now.minute();
  RTC_second = now.second();
  RTC_dayOfWeek = now.dayOfWeek();
  
  /*
  Serial.print(RTC_day);
  Serial.print('/');
  Serial.print(RTC_month);
  Serial.print('/');
  Serial.print(RTC_year);
  Serial.print(' ');
  Serial.print(RTC_hour);
  Serial.print(':');
  Serial.print(RTC_minute);
  Serial.print(':');
  Serial.print(RTC_second);
  Serial.println();
  */
  //string(int x1, int y1, int x2, int y2, int colour, uint8_t font, uint8_t fill, char text[]);
  switch(int(RTC_month)){
    case 1:
      sprintf(strMonth, "%s", "Gennaio");
      break;
    case 2:
      sprintf(strMonth, "%s", "Febbraio");
      break;
    case 3:
      sprintf(strMonth, "%s", "Marzo");
      break;
    case 4:
      sprintf(strMonth, "%s", "Aprile");
      break;
    case 5:
      sprintf(strMonth, "%s", "Maggio");
      break;
    case 6:
      sprintf(strMonth, "%s", "Giugno");
      break;
    case 7:
      sprintf(strMonth, "%s", "Luglio");
      break;
    case 8:
      sprintf(strMonth, "%s", "Agosto");
      break;
    case 9:
      sprintf(strMonth, "%s", "Settembre");
      break;
    case 10:
      sprintf(strMonth, "%s", "Ottobre");
      break;
    case 11:
      sprintf(strMonth, "%s", "Novembre");
      break;
    case 12:
      sprintf(strMonth, "%s", "Dicembre");
    break;
  }
  //Serial.println(strMonth);
  
  switch(RTC_dayOfWeek){
    case 1:
      //sprintf(strDay, "%s", "Lunedi'", " %d", RTC_day, strMonth, RTC_year );      // convert data from long to char
      sprintf(strDay, "Lunedi' %d", RTC_day, " %s", strMonth, "%d", RTC_year);
    break;
    case 2:
      sprintf(strDay, "%s", "Martedi'", RTC_day, " %s", strMonth, "%d", RTC_year);      // convert data from long to char
    break;
    case 3:
      sprintf(strDay, "%s", "Mercoledi'", RTC_day, " %s", strMonth, "%d", RTC_year);      // convert data from long to char
    break;
    case 4:
      //sprintf(strDay, "Giovedi' %d", RTC_day, " %s", strMonth, "%d", RTC_year );      // convert data from long to char
      sprintf(strDay, "Giovedi' %d", RTC_day, " %s", strMonth, "%d", RTC_year);
    break;
    case 5:
      sprintf(strDay, "%s", "Venerdi'", RTC_day, " %s", strMonth, "%d", RTC_year);      // convert data from long to char
    break;
    case 6:
      sprintf(strDay, "%s", "Sabato", RTC_day, " %s", strMonth, "%d", RTC_year);      // convert data from long to char
    break;
    case 7:
      sprintf(strDay, "%s", "Domenica", RTC_day, " %s", strMonth, "%d", RTC_year);      // convert data from long to char
    break;
    }
  //Serial.println(strDay);
}

// Get the time from the external clock 
char* getClock() 
{ 
  char buffer[5]=" "; 
  char timeStr[8] = " ";
  
  itoa(RTC_hour,buffer,10); 
  strcpy(timeStr,buffer); 
  strcat(timeStr,":"); 
  itoa(RTC_minute,buffer,10); 

  // Add 0 if a single digit minute has been returned 
  if (strlen(buffer)==1) 
  { 
    strcat(timeStr,"0");  
  }  
  strcat(timeStr,buffer); 

  // Seconds are not useful at this time. Commented out 
  strcat(timeStr,":"); 
  itoa(RTC_second,buffer,10); 
  strcat(timeStr,buffer); 

  return timeStr; 
} 

// Get the date from extrenal clock 
char* getDate() 
{ 
  char buffer[5]=" "; 
  char dateStr[10] = " ";
  
  itoa(RTC_day,buffer,10); 
  strcpy(dateStr,buffer); 
  strcat(dateStr,"/");  
  itoa(RTC_month,buffer,10); 
  strcat(dateStr,buffer); 
  strcat(dateStr,"/"); 
  itoa(RTC_year,buffer,10);  
  strcat(dateStr,buffer); 

  return dateStr; 
}

// Write data to log file named data.log 
void write_log(String msg) 
{
  // make a string for assembling the data to log:
  String dataString = "";
 
  dataString = msg;

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.csv");
  }
} 

// Routine executed by the timer interrupt. This flush the  
// data to the log file 
void flushCounter(void) 
{ 
  Serial.println("flushCounter");
  writeLog = 1; 
}

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

Handling_lcd.ino (non abilitato al momento)

// new version of function i2c_display2s(String a2, char* b2, String c2, char* d2)
// change data type String to pointer char* to external data
// old version: i2c_display2s(String a2, String b2, String c2, String d2)
// new version: i2c_display2s(String a2, char* b2, String c2, char* d2)
// String type as a costant data type
/*
void i2c_display2s(String a2, char* b2, String c2, char* d2){   
      int aLength = a2.length();
      int bLength = sizeof(b2);
      int cLength = c2.length();
      int dLength = sizeof(d2);
      
      int abSpace = 15 - (aLength + bLength);
      int cdSpace = 15 - (cLength + dLength);
      
      String ax = "";
      for (int i=0;i<abSpace;i++){
        ax += " ";
      }
      String cx = "";
      for (int i=0;i<cdSpace;i++){
        cx += " ";
      }      
      
      lcd.setCursor(0, 0);
      lcd.print(a2+ax+b2);

      lcd.setCursor(0, 1);
      lcd.print(c2+cx+d2);
      delay(1);    
}
*/

..cmq anche sul solito OpenEnergyMonitor trovi un esempio per la lettura della pulsazione della luce del contatore, basato su interrupt....
https://github.com/openenergymonitor/emonTxFirmware/blob/master/Guide/e_PulseCounting/e_PulseCounting.ino

kattivik76:
la MsTimer2 gestisce solo il timer di 60min impostato

Quindi mi confermi che i 60 minuti sono gestiti dalla MsTimer2, che allora si baserà sul risuonatore dell'Arduino
(premetto che non ho ancora guardato il codice).

si si, l'ho visto :slight_smile:

ma il mio problema è che si accumula un ritardo di 3608ms ogni volta che viene reinizializzato il timer dell'interrupt e non capisco perchè...

il ritardo di 3608ms non è imputabile al codice di formattazione e scrittura su uSD perchè il led di test che ho installato, ha un periodo di flash identico al led del contatore.

vedi il codice interessato dal marker "<<<<<<"

void loop(void)  
{
  // make a string for assembling the data to log:
  String dataString = "";
  
  //Serial.println(analogRead(PHOTO_IN));  // FIXME 
    
  // Read the photo sensor value 
  if (analogRead(PHOTO_IN) > threshold)  <<<<<< Lampeggio ricevuto da contatore enel
  { 
    // read and parse RTC data from DS1307
    read_RTC();
  
    digitalWrite(ledflash,HIGH);               <<<<<< Accendo il led di spia per Lampeggio ricevuto da contatore enel
    flash++;
    
    dataString = getDate(); 
    dataString += " ";
    dataString += getClock();
    
    lcd.setCursor(0, 1);
    lcd.print("T: " + dataString);
    
    lcd.setCursor(0, 2);
    lcd.print("Flash: " + flash);
    
    dataString = String(flash/1000);
    
    lcd.setCursor(0, 3);
    lcd.print("Energia: " + dataString + " KW" );
    
    Serial.print("Flash: ");       // FIXME
    Serial.println(flash);  
    while (analogRead(PHOTO_IN) > threshold) 
    { 
    // Just wait the flash to turn off (to avoid multiple counts)    
    }  
    digitalWrite(ledflash,LOW);                    <<<<<< Spengo il led spia per Lampeggio ricevuto da contatore enel
  }

essendo i consumi non uniformi per ovvi motivi di utilizzo, non posso pensare che sia un ritardo accumulato dovuto all'acquisizione del lampeggio in quando è costante su 3608ms indipendentemente dal numero di lampeggi totalizzati.

grazie :slight_smile:
kattivik76

leo72:

kattivik76:
la MsTimer2 gestisce solo il timer di 60min impostato

Quindi mi confermi che i 60 minuti sono gestiti dalla MsTimer2, che allora si baserà sul risuonatore dell'Arduino
(premetto che non ho ancora guardato il codice).

si esatto, ho dato un'occhiata alla libreria...
ho visto che effettua delle selezioni in base alla CPU utilizzata es ATmega328P che credo sia la CPU di ArduinoUno...
ma non ci ho capito molto :stuck_out_tongue:
se hai tempo e vuoi dargli un'occhiata ben venga :slight_smile: sicuramente sei più ferrato di me sui timer (LeOS) :wink:

grazie :slight_smile:
kattivik76

allego il file dei consumi di ieri per chiarezza.

saluti kattivik76

DATALOG 22.08.2013.xlsx (21 KB)

La MsTimer2 imposta un timer che usa come generatore di millisecondi. Ad ogni millisecondo incrementa un contatore interno. Quando il contatore raggiunge il valore che gli hai passato come parametri, richiama la funzione che vuoi tu. La tua funzione, una volta attivata, prende l'ora e va a scriverla sul file.
Io dico che la tolleranza del risuonatore introduce un ritardo di 8 secondi all'ora, ritardo che ogni volta che fai ripartire la lib si somma al ritardo precedente e così via.

Per avere un controllo più preciso, dovresti leggere l'ora dall'RTC. I tempi scanditi dal micro soffrono della precisione della fonte di quarzo usata. Sicuramente una 2009, con un quarzo esterno da 16 MHz, sarebbe un pochino più precisa.

ma anche la UNO ha il quarzo da 16Mhz esterno...

... non mi torna comunque, il ritardo che ho è di 3608ms/ora costante per ogni ora che passa...

la tensione di alimentazione può incidere? è alimentato con un cavo usb (5vdc carica batteria iphone)
una 2009 non l'ho, ho una mega2560 in alternativa :slight_smile:

grazie
kattivik76

posso anche togliere di mezzo la MsTimer2 ed implementare la tua LeOS, ho sbirciato nella lib ed ho visto che comunque supporta un periodo di 1 ora :wink:

vediamo cosa accade :stuck_out_tongue:

saluti
kattivik76

kattivik76:
ma anche la UNO ha il quarzo da 16Mhz esterno...

No, ha un risuonatore ceramico. Sono oggetti con tolleranze molto alte, possono perdere anche uno o due secondi al minuto. Ecco probabilmente da dove vengono gli 8 secondi/ora.

... non mi torna comunque, il ritardo che ho è di 3608ms/ora costante per ogni ora che passa...

Vedi sopra.
Per riprova potresti però prendere un'altra scheda Arduino. Il tempo deve essere differente perché ogni componente ha tolleranze diverse. Se invece vedi lo stesso ritardo, allora il ritardo viene dalle operazioni condotte oppure da qualche altro componente.

la tensione di alimentazione può incidere? è alimentato con un cavo usb (5vdc carica batteria iphone)

No, l'arduino ha un circuito di regolazione a cui si somma quello dell'alimentatore, non penso proprio.

una 2009 non l'ho, ho una mega2560 in alternativa :slight_smile:

grazie
kattivik76

Prova la Mega2560.

Per curiosita' ho controllato la frequenza del clock su ambedue le schede.

UNO 15.989 Khz ( errore 1 minuto al giorno )
2009 15.998 Khz ( errore <10 secondi al giorno )

kattivik76:
posso anche togliere di mezzo la MsTimer2 ed implementare la tua LeOS, ho sbirciato nella lib ed ho visto che comunque supporta un periodo di 1 ora :wink:

Avresti gli stessi problemi perché anche la leOS usa la fonte di clock della scheda.
Forse con la swRTC, che ha internamente un meccanismo di correzione dello scostamento del tempo calcolato da quello reale, potresti riuscire a migliorare qualcosa.

Io però farei in un'altra maniera.
Usi il DS1307, vero? Prova a portare fuori il segnale del clock dell'RTC con 1 Hz di frequenza e collega il pin SQW ad un pin dell'Arduino dove puoi agganciare un interrupt hardware. Scrivi poi una routine che conta il numero di secondi che vuoi far passare, e dopo che lo hai raggiunto, cambi lo stato alla tua variabile di controllo. A quel punto è passato esattamente il numero di secondi prescelto. Senza possibilità di errori.

oddio.... non e' che pure il DS1307 e' un mostro di precisione

leo72:

kattivik76:
posso anche togliere di mezzo la MsTimer2 ed implementare la tua LeOS, ho sbirciato nella lib ed ho visto che comunque supporta un periodo di 1 ora :wink:

Avresti gli stessi problemi perché anche la leOS usa la fonte di clock della scheda.
Forse con la swRTC, che ha internamente un meccanismo di correzione dello scostamento del tempo calcolato da quello reale, potresti riuscire a migliorare qualcosa.

Io però farei in un'altra maniera.
Usi il DS1307, vero? Prova a portare fuori il segnale del clock dell'RTC con 1 Hz di frequenza e collega il pin SQW ad un pin dell'Arduino dove puoi agganciare un interrupt hardware. Scrivi poi una routine che conta il numero di secondi che vuoi far passare, e dopo che lo hai raggiunto, cambi lo stato alla tua variabile di controllo. A quel punto è passato esattamente il numero di secondi prescelto. Senza possibilità di errori.

OTTIMO!!!! ora so anche che cosa è lo SQW :slight_smile: direi che è la soluzione migliore e precisa :slight_smile:

p.s.: farò anche delle prove con altre schede arduino, giusto per sfizio!!!

grazie ancora
saluti
kattivik76

Questa soluzione l'ho usata sul mio ultimo progetto pubblicato, il Led Clock. Anche se lì ho usato un PCF8563, il principio è comunque lo stesso.
Metti una pull-up da 10K sul pin (ho visto sul datasheet che è richiesta), e poi agganci un interrupt che scatta quando il segnale va basso.

ciao a tutti :slight_smile:

allora, come promesso ho modificato e testato il mio progetto in modo tale da utilizzare 2 Interrupt:

  • IRQ0 -> rilevamento fronte di discesa lampeggio (acquisito mediante fotoresistenza)
  • IRQ1 -> rilevamento fronte di discesa SQW di RTC (DS1307)

in più ho aggiunto un display LCD 20x4 su bus I2C + le funzioni che mi permettono di effettuare il log dei dati su scheda SD dello shield Ethernet.

il tutto funziona correttamente, ma ad un certo punto, circa dopo 8ore, arduino si frizza e non capisco perchè... necessita di una pressione sul tasto reset per ripartire...

se volete dare un'occhiata allo sketch, lo allego a questo post.

p.s.: la libreria MsTimer2.h non fa più parte di questo progetto :slight_smile:

grazie!!!

saluti
kattivik76

Enerduino_2_0.rar (4.36 KB)

Togli la stampa seriale dall'interrupt, potrebbe anche essere quello il problema.

Tu da dentro onRTCpulse chiami flushCounter che stampa su seriale.
Io metterei semplicemente l'attivazione di un flash, che controllerei da dentro il loop principale e poi da lì chiamerei flushCounter.

Funziona come no, anch'io ho fatto delle prove ed ho visto che la stampa seriale funziona (perché anch'essa viaggia con gli interrupt) ma è una cosa da non usare perché in un interrupt ci dovrebbero essere operazioni molto semplici.