Libreria DS3231

Buona giornata a tutti,

sono in possesso di un modulo DS3231, ed ho scaricato la relativa libreria dal seguente link

https://www.arduinolibraries.info/libraries/ds3231

non riesco a capire come fare ad inserire data e ora con dei pulsanti,

provando i vari esempi sono solo riuscito ad stampare data e ora di default, che ovviamente non sono corrette, ora per comodità vorrei correggere data e ora tramite tre pulsanti, ma con varie prove che o fatto non ci riesco,

non riesco a capire quali funzioni usare per scrivere data e ora nei registri del RTC se qualche buona anima mi da delle dritte gli sarei molto grato

Metti il codice delle tue prove che hai fatto e vediamo dove sta l'errore, settare giorno,mese,anno,ore,minuti e secondi sono funzioni semlici da richiamare probabilmente l'errore sta nel codice che gestisce i pulsanti

Vedi anche questo

Flaviano

Mille grazie di avermi risposto,

il programma che sto provando e il seguente

/*******************************
 * PROVIAMO IL NOW
 **********************************/

#include <Wire.h>
#include <DS3231.h>
#include <LiquidCrystal_I2C.h>

#define SET  12 //A1
#define PIU  11 //A2
#define MENO 10 //A3

void setMode();

char buffer[10];
unsigned long time = 0;
unsigned long timeSet = 0;
//int  setModeTime=2000;
unsigned long setModeTime = 2000;

int _day; //Date = giorno
int _month; //mese
int _year; //anno
int DoW;
int _hour;
int _minute;
int _second;

RTClib RTC;

LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin,
                      D7_pin);

void setup () {
    Serial.begin(57600);
    Wire.begin();
    lcd.begin(20, 4, LCD_5x10DOTS);
    lcd.home();
    lcd.clear();

    pinMode(SET, INPUT_PULLUP);
    pinMode( PIU, INPUT_PULLUP );
    pinMode( MENO, INPUT_PULLUP );
}

void loop () {
  if (digitalRead(SET) == LOW) {setMode();}
  
    
  
    DateTime now = RTC.now();
    
    lcd.setCursor(0, 0);
    lcd.print(now.day(), DEC); //giorno
    lcd.setCursor(2, 0);
    lcd.print('/');
    lcd.setCursor(3, 0);
    lcd.print(now.month(), DEC); //mese
    lcd.setCursor(5, 0);
    lcd.print('/');
    lcd.setCursor(6, 0);
    lcd.print(now.year(), DEC); //anno

    lcd.setCursor(0, 1);
    lcd.print(now.hour(), DEC);
    lcd.setCursor(2, 1);
    lcd.print(':');
    lcd.setCursor(3, 0);    
    lcd.print(now.minute(), DEC);
    
//    Serial.print(':');
//    Serial.print(now.second(), DEC);
//    Serial.println();
//    
//    Serial.print(" since midnight 1/1/1970 = ");
//    Serial.print(now.unixtime());
//    Serial.print("s = ");
//    Serial.print(now.unixtime() / 86400L);
//    Serial.println("d");
  delay(1000);
}

/*************************************************/
void setMode() {
  boolean setMode = true;
  int setModeLevel = 0;
  
  lcd.clear();

  lcd.setCursor(0, 0);
  sprintf(buffer,  "%s: %02d", "Giorno", _day);
  delay( 1000 );
  timeSet = millis();

  while (setMode) {
    if ( digitalRead(SET) == LOW ) {lcd.clear(); setModeLevel++;}
    if ( setModeLevel > 5){setModeLevel = 0;}

    lcd.setCursor(0, 0);

    if ( digitalRead(SET) == LOW || digitalRead(PIU) == LOW || digitalRead(MENO) == LOW ) {timeSet = millis();}

    lcd.setCursor(0, 0);

    // Set giorno
    if ( setModeLevel == 0 ) {
      if ( digitalRead(PIU) == LOW && _day < 31) {_day++;}
      if ( digitalRead(MENO) == LOW && _day > 1) {_day--;}
      sprintf(buffer,  "%s:%02d", "Giorno", _day);
      }
      
    // Set mese
    if ( setModeLevel == 1 ) {
      if ( digitalRead(PIU) == LOW && _month < 12) {_month++;}
      if ( digitalRead(MENO) == LOW && _month > 1) {_month--;}
      sprintf(buffer,  "%s:%02d", "Mese", _month);
    }
    
    // Set anno
    if ( setModeLevel == 2 ) {
      if ( digitalRead(PIU) == LOW && _year < 9999) {_year++;}
      if ( digitalRead(MENO) == LOW && _year > 1900) {_year--;}
      sprintf(buffer,  "%s:%02d", "Anno", _year);
    }
    
    // Set ore
    if ( setModeLevel == 3 ) {
      if ( digitalRead(PIU) == LOW && _hour < 24) {_hour++;}
      if ( digitalRead(MENO) == LOW && _hour > 1) {_hour--;}
      sprintf(buffer,  "%s:%02d", "Ora", _hour);
    }
    
    // Set minuti
    if ( setModeLevel == 4 ) {
      if ( digitalRead(PIU) == LOW && _minute < 60) {_minute++;}
      if ( digitalRead(MENO) == LOW && _minute > 1) {_minute--;}
      sprintf(buffer,  "%s:%02d", "Minuti", _minute);
    }
    
    // Set secondi
    if ( setModeLevel == 5 ) {
      if ( digitalRead(PIU) == LOW && _second < 60) {_second++;}
      if ( digitalRead(MENO) == LOW && _second > 0) {_second--;}
      sprintf(buffer,  "%s:%02d", "Secondi", _second);
    }
    lcd.setCursor(0, 2);
    lcd.print( (buffer) );

    if (timeSet > 0 && (setModeTime * 2) < (millis() - timeSet) ) {
      DateTime now = RTC.now();
      _day = now.day();
      _month = now.month();
      _year = now.year();
      _hour = now.hour();
      _minute = now.minute();
      _second = now.second();
      setMode = false;
      lcd.clear();
    }
     
    delay(100);
  }//while
}

Flavi71
interessante il codice, anche se non usa la libreria lo provo poi so dirti,
però io volevo usare la libreria che mi da la possibilità di settare dei allarmi

Ti credo che non ti salva i valori che imposti nella funzione setMode fai tutto bene ma ti limiti a scrivere sul display, non usi mai i metodi della libreria per settare i vari valori se guardi tra gli esempi a corredo della libreria trovi anche quelli che settano gli orari, oppure nel link che tu hai messo nel tuo post c’è il link a github delle libreria, li guardi dentro gli esempi o meglio ancora nel file .h che dichiara tutte le funzioni disponibili.
Non ti resta che prendere le tue variabili (_day, _month, ecc.) e salvarle con gli appositi metodi della libreria.
Seguendo la logica con cui hai creato il programma lo farei nell’if che ti fa uscire dalla modalità di programmazione dell’orario subito prima dell’istruzione

DateTime now = RTC.now();

Se posso permettermi un suggerimento cambierei queste logiche (riporto le ore a titolo d’esempio ma lo dovresti fare su tutti i parametri):

if ( digitalRead(PIU) == LOW && _hour < 24) {_hour++;}
if ( digitalRead(MENO) == LOW && _hour > 1) {_hour--;}

in modo che i settaggi siano circolari (lo trovo più pratico)

if ( digitalRead(PIU) == LOW)
{
    _hour++;
    if(_hour >= 24)
    {
       _hour = 1;
    }
}
if ( digitalRead(MENO) == LOW)
{
    _hour--;
    if(_hour < 1)
    {
       _hour = 23;
    }
}

E’ solo un mio punto di vista a te la scelta, quello che invece ti consiglio veramente di fare è invertire la sequenza d’inserimenti in anno, mese, giorno questo perché l’if che fai sui giorni (<31) dipende dall’anno e dal mese impostato, se tu provassi a impostare sull’RTC una data del tipo 30/02/2019 avresti un bell’errore. La cosa corretta da fare è verificare il massimo giorno impostabile per il mese e anno selezioati durante l’impostazione del giorno e in caso di modifica dell’anno e/o del mese dovresti anche controllare che il giorno sia ancora valido, ad esempio imposti il 29/02/2020 che è valido, se poi vai a cambiare l’anno in 2019 devi per forza modificare il giorno (Es. 1 o 28) perché non essendo bisestile sarebbe una data non valida. Stessa cosa per i mesi se hai impostato 31/01/2019 e poi cambi il mese il 02 il giorno deve essere modificato di conseguenza.

fabpolli Grazie al tuo suggerimento ore i dati si salvano nel RTC,

La cosa corretta da fare è verificare il massimo giorno impostabile per il mese e anno selezionati durante l'impostazione del giorno

questo per me e un po complicato, non saprei dove incominciare, cortesemente puoi farmi un esempio

mille grazie per tutto

Allora se tu guardi il tuo codice sistemi il giorno se setModeLevel è zero, il mese se è uno e l’anno se è due, per far ciò che ti consiglio devi settare l’anno se setModeLevel è zero, il mese se è uno (quindi non cambia rispetto a quanto è ora sul tuo programma) e il giorno se setModeLevel vale due.
In questo modo l’utente prima imposta l’anno, poi il mese ed infine il giorno.
Nell’if che consente di impostare il giorno adesso tu fai

if ( digitalRead(PIU) == LOW && _day < 31)

Invece dovrai fare una serie di if che ti consentano di controllare se la variabile _day è inferiore a 31 per i mesi di 31 giorni, inferiore a 30 per i mesi di 30 giorni e inferiore a 28 se il mese inserito è febbraio.
Per non scombinare troppo il tuo programma puoi definire una nuova variabile che contenga il giorno massimo in mdoo che tu possa fare l’if in questo modo:

if ( digitalRead(PIU) == LOW && _day < _massimoGiornoValido)

Chiaramentri prima di questo if dovrai valorizzare la variabile _massimoGiornoValido in base al mese impostato dall’utente.

Ho volutamente tralasciato per ora la parte dell’anno bisestile per ciò che riguarda febbraio, intanto arriva all’obiettivo di 31,30 e 28 giorni poi ti verrà facile (spero) adeguare per gli anni bisestili

Ah per la cronaca potresti anche far inserire mese, anno e giorno invece che anno, mese e giorno tanto l'importante è avere anno e mese impostati prima di impostare i giorni.

fabpolli
Mille grazie adesso aggiusto il tutto