Go Down

Topic: Libreria DS3232RTC impostare data ora con pulsanti (Read 209 times) previous topic - next topic

milefori

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
https://github.com/JChristensen/DS3232RTC

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
Code: [Select]



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




paolo311

#1
Aug 12, 2019, 09:37 am Last Edit: Aug 12, 2019, 09:57 am by paolo311
questa e la libraria che sto usando
https://github.com/JChristensen/DS3232RTC

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..)

Code: [Select]

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.. :) )

Code: [Select]

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..


Federico66

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 :)

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.
"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

milefori

#3
Aug 12, 2019, 02:10 pm Last Edit: Aug 12, 2019, 02:23 pm by milefori
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,

Quote
Un'ultima cosa: usi la variabile day per incrementare sia il giorno che il mese..
hai ragione l'ho corretto,

Federico66
Quote
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,


Federico66

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  :smiley-confuse:

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ì:
Code: [Select]

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!


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 https://github.com/JChristensen/DS3232RTC ::) ::)

Code: [Select]

..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
"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

paolo311

Hai verificato mai se entra mai in questo if?

Code: [Select]

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

Federico66

"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

milefori

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
Code: [Select]
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
Quote
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
Quote
Clears the oscillator stop flag (OSF) bit in the control/status register.
secondo voi cosa significa?

mille grazie per il tempo che mi dedicate

Go Up