Salve a tutto, ho un problema e chiedo aiuto a voi esperti.
Ho assemblato uno StandAlone con MCU ATMEGA1284P, monta un quarzo da 20MHz (con core adeguato) con margine di errore di +/- 20ppm e un RTC DS3231.
Ho bisogno di gestire dei cronometri accurati e mi aspettavo una accuratezza molto più alta sulla gestione del tempo da parte dell' MCU (tramite il millis()).
Facendo alcune prove mi trovo a perdere circa 15 secondi per ogni ora....credo sia tantissimo considerando il quarzo che sto usando.
Sto confrontando il tempo che passa con quello letto dall' RTC e mi ritrovo con questi valori:
Millis() / RTC
01:27:00 / 01:27:20
04:00:00 / 04:00:57
Vi posto il codice che sto usando, vorrei capire dove è il problema, magari mi sbaglio e quelle sono le tempistiche giuste, anche se come detto me lo sarei aspettato da un arduino che monta un risuonatore, ma non da uno StandAlone con quarzo 20ppm.
//------TEST PER VERIFICARE LA SINCRONIZZAZIONE DEI TEMPI TRA L' RTC E I TEMPI INTERNI VIA SOFTWARE ---------
#include <LiquidCrystal.h>
#include <DS3231.h> //Libreria per il RTC
#include <Wire.h> //Libreria per utilizzare la I2C, usata per il RTC e altro eventuale
//-------------------NOMENCLATURA PIN INPUT / OUTPUT--------------------------
const byte rs = 14, d4 = 0, d5 = 1, d6 = 2, d7 = 3; //Assegnazione pin per la gestione dei display
const byte enableDisplay1 = 29, enableDisplay2 = 28, enableDisplay3 = 27; //Pin utilizzati per gli Enable dei 3 Display
const byte contrastPin = 12; //è il pin dedicato alla gestione del costrasto, attraverso filtro RC : R=1K, C=100uF Elettrolitico
const byte lightPin = 13; //è il pin dedicato alla gestione della luminosità
//-------------------NOMENCLATURA PIN INPUT / OUTPUT--------------------------
//-------------------VARIABILI USATE DA RTC--------------------------
bool h12Flag = false; //Per settare il formato ora h12 o h24 (default)
bool pmFlag = false; //Nel caso di formato h12 per sapere se è AM o PM
bool century = false;
byte Anno = 0, Mese = 0, Giorno = 0, GiornoDellaSettimana = 0, Ore = 0, Minuti = 0, Secondi = 0; //Variabili di Data e Orario gestito dall' RTC HardWare
byte OreSW = 0, MinutiSW = 0, SecondiSW = 0, MillisecondiSW = 0; //Variabili di Orario gestito via Software
float TemperaturaInterna = 0; //Temperatura interna dell' RTC 3231
char Data[10]; //Stringa Stampabile che Rappresenta la Data completa
char Ora[10]; //Stringa Stampabile che Rappresenta l' Orario completo
char OraSW[10]; //Stringa Stampabile che Rappresenta l' Orario Software completo
//-------------------VARIABILI USATE DA RTC--------------------------
//-------------------VARIABILI DI GESTIONE --------------------------
word livelloContrasto = 0; //è il livello del contrasto, PWM da 0 = Massimo Contrasto a 255 = Minimo Contrasto
word livelloLuminosita = 255; //è il livello dela luminosità, PWM da 0 = Minima luminosità a 255 = Massima Luminosità
//-------------------VARIABILI DI GESTIONE --------------------------
//------------------- CREAZIONE OGGETTI --------------------------
DS3231 Clock; //Inizializza una procedura per il RTC
RTClib Clock2; //Inizializza un altra procedure, sempre per il RTC, con altre funzioni avanzate
DateTime Adesso; //Creo l' Oggetto "Adesso" con il formato di "DateTime" impostato nella libreria, conterrà la data e orario dalla funzione "now"
LiquidCrystal Display1(rs, enableDisplay1, d4, d5, d6, d7); //4 BIT SENZA ASSEGNAZIONE DEL PIN R/W (A GND GLI ALTRI 4)
LiquidCrystal Display2(rs, enableDisplay2, d4, d5, d6, d7); //4 BIT SENZA ASSEGNAZIONE DEL PIN R/W (A GND GLI ALTRI 4)
LiquidCrystal Display3(rs, enableDisplay3, d4, d5, d6, d7); //4 BIT SENZA ASSEGNAZIONE DEL PIN R/W (A GND GLI ALTRI 4)
//------------------- CREAZIONE OGGETTI --------------------------
void setup() { //------------ SETUP ------------ SETUP ------------ SETUP ------------ SETUP ------------ SETUP ------------ SETUP ----
//------------------- ASSEGNAZIONE PIN INPUT / OUTPUT --------------------------
pinMode(contrastPin, OUTPUT); //è il pin dedicato alla gestione del costrasto, attraverso filtro RC : R=1K, C=100uF Elettrolitico
pinMode(lightPin, OUTPUT); //è il pin dedicato alla gestione della luminosità, attraverso R330 e LS7407
//------------------- ASSEGNAZIONE PIN INPUT / OUTPUT --------------------------
Wire.begin(); //Inizializza la comunicazione I2C per il RTC ed altro eventuale
Display1.begin(8, 2);
Display2.begin(8, 2);
Display3.begin(8, 2);
analogWrite(contrastPin, livelloContrasto); //Setta il CONTRASTO
analogWrite(lightPin, livelloLuminosita); //Setta la LUMINOSITA'
//--------- SINCRONIZZAZIONE DELL' RTC CON IL TEMPO INTERNO SOFTWARE (LEGGERMENTE DISCOSTATO) ----------
Clock.setHour(0);
Clock.setMinute(0);
Clock.setSecond(millis() / 1000);
/*
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
*/
}
void loop() { //--------------- LOOP --------------- LOOP --------------- LOOP --------------- LOOP --------------- LOOP --------------- LOOP ----
long istante = millis(); //Legge l' orario Software
Adesso = Clock2.now(); //Legge l' orario Hardware
//--------------GESTIONE ORARIO SOFTWARE---------------------
long SecondiTemp = istante / 1000; //Rappresenta il numero TOTALE dei Secondi Passati
long MinutiTemp = SecondiTemp / 60; //Rappresenta il numero TOTALE dei Minuti Passati
long OreTemp = MinutiTemp / 60; //Rappresenta il numero TOTALE delle Ore Passate
MillisecondiSW = istante % 1000; //Millisecondi SW
SecondiSW = SecondiTemp % 60; //Secondi SW
MinutiSW = MinutiTemp % 60; //Minuti SW
OreSW = OreTemp % 24; //Ore SW
sprintf(OraSW, "%02d:%02d:%02d", OreSW, MinutiSW, SecondiSW); //Inserisce in una stringa l' orario per poi visualizzarlo
Display2.setCursor(0, 1);
Display2.print(OraSW);
//--------------GESTIONE ORARIO HARDWARE DA RTC---------------------
sprintf(Data, "%02d/%02d/%d", Adesso.day(), Adesso.month(), Adesso.year()); //Inserisce in una stringa la data per poi visualizzarla
sprintf(Ora, "%02d:%02d:%02d", Adesso.hour(), Adesso.minute(), Adesso.second()); //Inserisce in una stringa l' orario per poi visualizzarlo
Display3.setCursor(0, 0);
Display3.print( Data );
Display3.setCursor(0, 1);
Display3.print( Ora );
}