Libreria DS3232RTC impostare data ora con pulsanti

Buona giornata
son tre giorni che provo ma non ci riesco,
ho cercato in rete delle informazioni non ho trovato niente,
spero che qui qualcuno mi possa aiutare,

questa e la libraria che sto usando

spiego cosa vorrei fare:
impostare data e ora tramite 3 pulsanti,
(all'interno della libreria c'è un esempio di come impostare data e ora tramite monitor seriale)

ok questo l'ho fatto e imposta correttamente,

posto il programma

void setMode() {
	int _day;    //giorno
	int _month; //mese
	int _year; //anno
	int _hour;
	int _minute;
	int _second;
	
	char buffer[10];

	boolean setMode = true;
	int setModeLivel = 0;

	u8g.setPrintPos(0, 0);
	sprintf(buffer, "%s: %02d", "Giorno", _day);
	delay(1000);
	Timeset = millis();

	while (setMode) {
		if (digitalRead(enter) == LOW || digitalRead(piu) == LOW
				|| digitalRead(meno) == LOW) {
			Timeset = millis();
		}
		Serial.println("OK");

		u8g.setPrintPos(0, 0);

		//Set giorno
		if (setModeLivel == 0) {
			if (digitalRead(piu) == LOW && _day < 31) {
				_day++;
				Serial.println("OK1");
			}
			if (digitalRead(meno) == LOW && _day > 1) {
				_day--;
			}
			sprintf(buffer, "%s: %02d", "Giorno", _day);
			Serial.println(setModeLivel);
		}

		//set mese
		if (setModeLivel == 1) {
			if (digitalRead(piu) == LOW && _month < 12) {
				_day++;
			}
			if (digitalRead(meno) == LOW && _month > 1) {
				_day--;
			}
			sprintf(buffer, "%s: %02d", "Mese", _month);
		}

		//Set anno
		if (setModeLivel == 2) {
			if (digitalRead(piu) == LOW && _year < 9999) {
				_year++;
			}
			if (digitalRead(meno) == LOW && _year > 1900) {
				_year--;
			}
			sprintf(buffer, "%s: %02d", "Anno", _year);
		}

		//set ore
		if (setModeLivel == 3) {
			if (digitalRead(piu) == LOW && _hour < 24) {
				_hour++;
			}
			if (digitalRead(meno) == LOW && _hour > 1) {
				_hour--;
			}
			sprintf(buffer, "%s: %02d", "Ora", _hour);
		}

		//Set minuti
		if (setModeLivel == 4) {
			if (digitalRead(piu) == LOW && _minute < 60) {
				_minute++;
			}
			if (digitalRead(meno) == LOW && _minute > 1) {
				_minute--;
			}
			sprintf(buffer, "%s: %02d", "Minuti", _minute);
		}

		//Set secondi
		if (setModeLivel == 5) {
			if (digitalRead(piu) == LOW && _second < 60) {
				_second++;
			}
			if (digitalRead(meno) == LOW && _second > 0) {
				_second--;
			}
			sprintf(buffer, "%s: %02d", "Secondi", _second);
		}

		u8g.firstPage();
		do {
			u8g.setFont(u8g_font_helvB08);
			u8g.setPrintPos(15, 28);
			u8g.print((buffer));
		} while (u8g.nextPage());

		if (digitalRead(enter) == LOW) {
			setModeLivel++;
		}
		if (setModeLivel > 5) {
			setModeLivel = 0;
		}

		if (Timeset > 0 && (setModeTime * 2) < (millis() - Timeset)) {
			 _day = day();
			 _month = month();
			 _year = year();
			 _hour = hour();
			 _minute = minute();
			 _second = second();

			 
			setMode = false;
		}

		delay(200);
	}

}

programma troppo lungo non mi permette di postarlo tutto,

posto colo parte incriminata e la funzione setMode(),
prima di uscire (dalla funzione) dovrei aggiornare l'orologio, non va

non riesco a trovare il modo corretto per aggiornare l'orologio,

qualcuno mi può dare qualche dritta su come fare?

mille grazie a chi mi può aiutare

milefori:
questa e la libraria che sto usando
GitHub - JChristensen/DS3232RTC: Arduino Library for Maxim Integrated DS3232 and DS3231 Real-Time Clocks

spiego cosa vorrei fare:
impostare data e ora tramite 3 pulsanti,
(all'interno della libreria c'è un esempio di come impostare data e ora tramite monitor seriale)

qualcuno mi può dare qualche dritta su come fare?

Ciao, ho guardato il link alla libreria che hai postato.
Secondo me, nel tuo codice manca qualcosa simile a questo:

(l'ho preso dall'esempio "da seriale" della libreria che utilizzi..)

time_t t;
tmElements_t tm;

tm.Year = y2kYearToTm(y);
tm.Month = Serial.parseInt();
tm.Day = Serial.parseInt();
tm.Hour = Serial.parseInt();
tm.Minute = Serial.parseInt();
tm.Second = Serial.parseInt();

t = makeTime(tm);

RTC.set(t);        // use the time_t value to ensure correct weekday is set
setTime(t);

E' il punto in cui il codice di esempio prende i valori letti da seriale e li utilizza per impostare la nuova data\ora: questo dovrebbe essere il tuo punto di arrivo, strutturando un po' potresti farne una funzione:
(l'ho scritta alla cieca, non so se compila.. :slight_smile: )

void setDateTime(int _year, int _month, int _day, int _hour, int _minute, int _second)
{
 time_t t;
 tmElements_t tm;

 tm.Year = _year;
 tm.Month = _month;
 tm.Day = _day;
 tm.Hour = _hour;
 tm.Minute = _minute;
 tm.Second = _second;

 t = makeTime(tm);

 RTC.set(t);        // use the time_t value to ensure correct weekday is set
 setTime(t);
}

Questa la puoi provare anche con setup() al volo settando a manella una data e ora qualsiasi (possibilmente diversa da quella attuale) e stampandola subito dopo per verificare se è impostata correttamente.

In questo modo puoi testare anche i casi limite, per capire come li gestisce la libreria RTC e verificare quali validazioni devi inserire nel tuo codice per evitare errori.

Un'ultima cosa: usi la variabile day per incrementare sia il giorno che il mese..

paolo311:
Secondo me, nel tuo codice manca qualcosa simile a questo:

Mi hai anticipato di qualche secondo, quindi confermo quello che hai detto e modifico la mia risposta :slight_smile:

Per aggiornare l'RTC devi usare RTC.set(time_t t) (leggere sempre il reference e non fermarsi agli esempi), e poi, se stai usando la libreria Time.h, devi sincronizzarla setSyncProvider(RTC.get);

Federico

PS
Anche io, come esercizio, ho appena realizzato un orologio oled con rtc, con aggiunta di funzionalità timer, ma ho scelto la strada della programmazione a stati in modo da evitare di bloccare il loop. Pensaci, potrebbe essere un buon esercizio di programmazione.

Buona giornata ragazzi
un grande grazie a voi che mi avete risposto,

vi prego di pazientare io non sono un informatico, cerco di fare del mio meglio per imparare con tutti i miei limiti,
detto questo il programma che sto modificando l'ho trovato in rete,

paolo311
ho provato la funzione che mi hai postato,
cosi come l'hai scritta non va, crea problemi,
provato a nidificarla ma niente,

Un'ultima cosa: usi la variabile day per incrementare sia il giorno che il mese..

hai ragione l'ho corretto,

Federico66

leggere sempre il reference e non fermarsi agli esempi

ho letto un po tutto quello che o trovato,
ma il reference non so dove si trova,
se per favore me lo dici ti sarei grato,

ho provato RTC.set(time_t t) mi da errore di sintassi,

per la programmazione a stati, spero di arrivarci anch'io,

allego il programma completo, credo sia la cosa migliore per dare dei suggerimenti,

Mi_Orologio.h (9.36 KB)

milefori:
detto questo il programma che sto modificando l'ho trovato in rete,

Abbi pazienza, prima di modificare un programma funzionante bisogna capirlo in ogni sua parte, e non andare a tentativi :confused:

milefori:
ho provato la funzione che mi hai postato,
cosi come l'hai scritta non va, crea problemi,
provato a nidificarla ma niente,

appunto, non devi andare a tentativi, magari ci eri anche riuscito, ma se non aggiorni lo schermo è chiaro che non funziona!

Non ho modo di verificare tutto il codice, ma prova così:

if (Timeset > 0 && (setModeTime * 2) < (millis() - Timeset)) {
  time_t t;
  tmElements_t tm;

  tm.Year = _year;
  tm.Month = _month;
  tm.Day = _day;
  tm.Hour = _hour;
  tm.Minute = _minute;
  tm.Second = _second;

  t = makeTime(tm);
  RTC.set(t);
  setTime(t);
  
  //AGGIORNA LO SCHERMO
  printDateTime(t);

  setMode = false;
}

ed elimina la parte che hai aggiunto all'inizio di setDataTime!

milefori:
ho letto un po tutto quello che o trovato,
ma il reference non so dove si trova,
se per favore me lo dici ti sarei grato,

ho provato RTC.set(time_t t) mi da errore di sintassi,

L'hai postato tu GitHub - JChristensen/DS3232RTC: Arduino Library for Maxim Integrated DS3232 and DS3231 Real-Time Clocks ::slight_smile: ::slight_smile:

..omissis..
set(time_t t)
Description
Sets the RTC date and time to the given time_t value. Clears the oscillator stop flag (OSF) bit in the control/status register. See the oscStopped() function and also the DS323x datasheet for more information on the OSF bit.

Syntax
RTC.set(t);

Parameters
t: The date and time to set the RTC to (time_t)

..omissis..

Federico

Hai verificato mai se entra mai in questo if?

		if (Timeset > 0 && (setModeTime * 2) < (millis() - Timeset)) 
                {

			tm.Year = _year;
			tm.Month = _month;
	    	        tm.Day = _day;
			tm.Hour = _hour;
			tm.Minute = _minute;
			tm.Second = _second;
			
			t = makeTime(tm);
			RTC.set(t);
			setTime(t);

			setMode = false;
		}

ciao

paolo311:
Hai verificato mai se entra mai in questo if?

Vero anche questo :slight_smile:

Federico

Allora ho provato la modifica proposta da Federico66,
viene compilata ma non aggiorna RTC,

verificato se entra in quella parte di codice sia prima che dopo la modifica entra,

questo punto (dovevo farlo subito) seguo il consiglio di Federico66 di leggere il reference,
dove o trovato la funzione set(time_t t)
e l'esempio di come aggiornare RTC,
posto il pezzo di programma modificato che ora aggiorna RTC

if (Timeset > 0 && (setModeTime * 2) < (millis() - Timeset)) {

 time_t t;
 tmElements_t tm;

 tm.Year = _year;
 tm.Month = _month;
 tm.Day = _day;
 tm.Hour = _hour;
 tm.Minute = _minute;
 tm.Second = _second;

 setTime(tm.Hour, tm.Minute, tm.Second, tm.Day, tm.Month, tm.Year);
 RTC.set(now());

 setMode = false;
 }

l'unica cosa che non capisco dalla descrizione

Sets the RTC date and time to the given time_t value. Clears the oscillator stop flag (OSF) bit in the control/status register. See the oscStopped() function and also the DS323x datasheet for more information on the OSF bit.

e la seguente

Clears the oscillator stop flag (OSF) bit in the control/status register.

secondo voi cosa significa?

mille grazie per il tempo che mi dedicate