ciao a tutti!
sto costruendo il word clock, ma non voglio scopiazzare il codice qua e la cercando di interpretare i ragionamenti altrui, voglio crearlo da me, sia perchè è più istruttivo e più gratificante, sia perchè voglio apportare delle migliorie(secondo me).
ho bisogno di un costrutto che effettui ciclicamente delle istruzioni al verificarsi di condizioni basate sia su ora che minuti che su secondi; mi spiego meglio: quando ("ora è compresa in un certo intervallo" && "minuti è compreso in certo intervallo" && "secondi è compreso in un certo intervallo" )|| ("ora < certo valore && minuti > certo valore && secondi compreso in un certo intrervallo) fai questa operazione; e via di seguito istruzioni simili.
poichè questi intervalli non si accavallano è inutile che vengano effettuati tutti e 12 gli if se tipo il quarto if è verificato, perciò vorrei un costrutto di istruzioni condizionali mutuamente esclusive: se una è vera le altre sono sicuramente false e perciò non le controllare.
il costrutto if - else if - else fa al caso mio?
avrei voluto usare lo switch-case, ma non credo che questo costrutto sopporti tante condizioni, o no?
Ciao,
lo switch case
si verifica solo una volta il resto non viene eseguito e se non trova lo switch indicato viene eseguito un case di default. Io personalmente uso spesso switch case quando ho molte variabili da controllare.
Cioa,
Gianni
ciao fvlgnn!
potresti per cortesia postare un esempio con questi range per esempio?
tipo: se siamo tra le 10:15:27 e le 11:22:00 fai questo;
se siamo tra le 11:22:01 e le 12:10:29 fai quest'altro
ecc ecc....
grazie
proncito:
tipo: se siamo tra le 10:15:27 e le 11:22:00 fai questo;
se siamo tra le 11:22:01 e le 12:10:29 fai quest'altro
Su due piedi la logica che userei è questa.
if ((ora > 10:15:27) && (ora < 11:22:00)) caso = 1;
if ((ora > 11:22:01) && (ora < 12:10:29)) caso = 2;
/* *** eccetera *** */
switch (caso) {
case 1:
Serial.println("caso 1");
break;
case 2:
Serial.println("caso 2");
break;
/* *** eccetera *** */
default:
Serial.println("caso di default");
}
Dal mio punto di vista è molto più chiara di una sequela di if else
. E' un mio pensiero sei liberissimo di condividerlo o meno
Cioa,
Gianni
Come suggerito tante volte, usate i timestamp per questo tipo di confronti.
I timestamp sono il numero di secondi trascorsi da un istante preso come "istante zero".
In questo modo al posto di fare un controllo del tipo:
if (ore == ... AND minuti == ... AND secondi == ....)
tutto diventa
if(timestamp == ...)
Inoltre col timestamp si gestisce molto meglio anche un evento a cavallo di 2 giorni perché usando l'orario classico si dovrebbe fare un ulteriore controllo per verificare se la fine cade nel giorno successivo. E la cosa si complica a fine mese perché il giorno successivo avrebbe un numero inferiore a quello del giorno precedente.
e la soluzione dei timestamp resta valida anche usando un RTC? prima di venir a conoscenza del RTC ho pensato anch'io ad una soluzione del genere, ma poi l'ho scartata
fvlgnn:
proncito:
tipo: se siamo tra le 10:15:27 e le 11:22:00 fai questo;
se siamo tra le 11:22:01 e le 12:10:29 fai quest'altroSu due piedi la logica che userei è questa.
if ((ora > 10:15:27) && (ora < 11:22:00)) caso = 1;
if ((ora > 11:22:01) && (ora < 12:10:29)) caso = 2;
/* *** eccetera *** /
switch (caso) {
case 1:
Serial.println("caso 1");
break;
case 2:
Serial.println("caso 2");
break;
/ *** eccetera *** */
default:
Serial.println("caso di default");
}
Dal mio punto di vista è molto più chiara di una *sequela* di `if else`. E' un mio pensiero sei liberissimo di condividerlo o meno ;) Cioa, Gianni
a questa soluzione non avevo pensato; francamente non so se è più chiara di una serie di if, ma sicuramente non vengono effettuati controlli impossibili per via della mutua esclusione. Grazie gianni
Nessuno vieta di fare:
if ((ora > 10:15:27) && (ora < 11:22:00))
caso = 1;
else if ((ora > 11:22:01) && (ora < 12:10:29))
caso = 2;
else
caso = 3;
/* *** eccetera *** */
switch (caso) {
case 1:
Serial.println("caso 1");
break;
case 2:
Serial.println("caso 2");
break;
/* *** eccetera *** */
default:
Serial.println("caso di default");
}
Rimane valido il discorso timestamp di leo.
Ma if ((ora > 10:15:27) && (ora < 11:22:00)) come fai a farlo?
Non mi risulta esistano in C i valori 10:15:27 !!!
Presumo che devi fare i confronti con le 3 parti dell'ora, su 3 variabili hh, min, sec
Un modo per lavorare con queste cifre (a parte usare timestamp che è meglio) sarebbe convertirle in una unica cifra long
hh=10;
mm=15;
ss=27; // 3 pezzi dell'ora potrebbero essere da un orologio RTC
unsigned long ora=hh*10000L+mm*100+ss; // ottieni 101527
if(ora>=120000 && ora<180000)
{ Serial.println("pomeriggio");
}
if(ora>=180000 && ora<220000)
{ Serial.println("sera");
}
penso che per
if ((ora > 10:15:27) && (ora < 11:22:00))
intenda m'inventerò un modo per fare quella if, in pseudocodice, spero
mi stavo giustappunto scervellando a cercare se fosse possibile o meno esprimere l'ora in hh:mm:ss! e ricordavo bene che non è possibile, infatti "adotterò un modo per fare quella if"!
hh=10;
mm=15;
ss=27; // 3 pezzi dell'ora potrebbero essere da un orologio RTC
ora=hh*10000+mm*100+ss;
if(ora>=120000 && ora<180000)
{ Serial.println("pomeriggio");
}
if(ora>=180000 && ora<220000)
{ Serial.println("sera");
}
questo mi sembra una buona soluzione a sto problema.
ancora non capisco però perchè sarebbe meglio il timestamp e sopratutto COME usarlo. dovrei aggiornarlo ogni secondo e azzerarlo ogni 12 ore(sarà un orologio AM/PM)?
inoltre timestamp è solo un nome qualsiasi assegnato ad un contatore? o è una funzione in particolare con relativa libreria?
erpomata:
penso che perif ((ora > 10:15:27) && (ora < 11:22:00))
intenda m'inventerò un modo per fare quella if
Se vi rivolgete a me quello che ho scritto è solo un esempio per chiarire solo il funzionamento dello switch case
è abbastanza chiaro che un if
non funzioni con i numeri 10:00:00 oltremodo senza le virgolette
Da quello che ho capito quei valori, proncito, credo che li abbia già calcolati e/o letti.
fvlgnn:
Da quello che ho capito quei valori, proncito, credo che li abbia già calcolati e/o letti.
Come non detto! Comunque rimane valido il fatto che il ciclo di if che avevo scritto era un esempio
per far comprendere meglio di come usare lo switch case a procinto.
Cioa,
Gianni
Qui puoi prendere un pò di spunto:
proncito:
mi stavo giustappunto scervellando a cercare se fosse possibile o meno esprimere l'ora in hh:mm:ss! e ricordavo bene che non è possibile, infatti "adotterò un modo per fare quella if"!ora=hh*10000+mm*100+ss;
ho editato il codice, avevo dimenticato di dichiarare la variabile unsigned long.
unsigned long ora=hh*10000L+mm*100+ss;
Inoltre è meglio usare 10000L per forzare i calcoli a long, 10000 è int e la macchina potrebbe facilmente forzare tutto il calcolo a int.
quel post mi ha fatto dubitare ancora di più sull' utilità del timestamp per il mio caso; il mio orologio non dovrà sopportare cambi di mesi, anni bisestili, ore legali nè essere sincronizzato con la nasa, non dovrà riportare date, ma solo orario in 12 ore. la soluzione suggerita da nid69ita mi alletta, e forse questo avviene solo perchè ancora non ho scritto manco una linea di codice, ma solo il flowchart.
Prevedo di settare l'orario la prima volta sincronizzando l' RTC(col ds1307) col mio pc con
RTC.adjust(DateTime(__DATE__, __TIME__))
,
e poi le successive volte con un tasto.
ho dimenticato di ringraziarvi finora! Grazie!
@Leo ti metteva sull'avviso.
Se non devi tenere conto del passaggio di ora tra un giorno e l'altro il timestamp non serve.
Cioè l'ora a un certo punto sarà:
23:59:59 => 235959
ma un secondo dopo:
00:00:00 => 0
alla mezzanotte si azzera. In alcuni casi può essere un problema.
proncito:
Prevedo di settare l'orario la prima volta sincronizzando l' RTC(col ds1307) col mio pc con
RTC.adjust(DateTime(__DATE__, __TIME__))
,
Questo codice NON sincronizza l'orario col PC ma dice al compilatore di salvare nella Flash il valore della data e dell'orario nel momento della compilazione.
Se compili ora, alle 22:49 del 7/4/2013, se accendi la scheda fra 2 anni, l'orario partirà alle 22:49 del 7/04/2013.
A meno che tu, ogni volta, non riflashi lo sketch sull'Arduino, cosa che farebbe risalvare i nuovi valori per data ed ora.
nid69ita:
Cioè l'ora a un certo punto sarà:
23:59:59 => 235959
ma un secondo dopo:
00:00:00 => 0
alla mezzanotte si azzera. In alcuni casi può essere un problema.
questo non è unp roblema, al passaggio tra le 12:59:59 e l' 01:00:00 farò un controllo doppio.
leo72:
proncito:
Prevedo di settare l'orario la prima volta sincronizzando l' RTC(col ds1307) col mio pc con
RTC.adjust(DateTime(__DATE__, __TIME__))
,Questo codice NON sincronizza l'orario col PC ma dice al compilatore di salvare nella Flash il valore della data e dell'orario nel momento della compilazione.
Se compili ora, alle 22:49 del 7/4/2013, se accendi la scheda fra 2 anni, l'orario partirà alle 22:49 del 7/04/2013.
A meno che tu, ogni volta, non riflashi lo sketch sull'Arduino, cosa che farebbe risalvare i nuovi valori per data ed ora.
e questo è risolvibile montanto una batteria tampone, vero? cioè fino a quando smanetto con prove e settaggi la batteria potrebbe non servire, ma dall'ultima compilazione in poi la lascio e mi terrà l'orario aggiornato.
Visto che siamo andati un pò offtopic aggiorno il titolo e ripropongo anche la questione:
ho fatto delle prove ieri e mi sembra di aver capito che il costrutto if-else if-else è mutuamente esclusivo a differenza di quanto pensavo, e credo che la soluzione proposta da fvlgnn
fvlgnn:
Su due piedi la logica che userei è questa.if ((ora > 10:15:27) && (ora < 11:22:00)) caso = 1;
if ((ora > 11:22:01) && (ora < 12:10:29)) caso = 2;
/* *** eccetera *** /
switch (caso) {
case 1:
Serial.println("caso 1");
break;
case 2:
Serial.println("caso 2");
break;
/ *** eccetera *** */
default:
Serial.println("caso di default");
}
Dal mio punto di vista è molto più chiara di una *sequela* di `if else`. E' un mio pensiero sei liberissimo di condividerlo o meno ;) Cioa, Gianni
non sia un alleggerimento del codice: dovendo comunque usare una sequela di if-else if metto direttamente le istruzioni li dentro anzichè usare pure lo switch case.
proncito:
e questo è risolvibile montanto una batteria tampone, vero? cioè fino a quando smanetto con prove e settaggi la batteria potrebbe non servire, ma dall'ultima compilazione in poi la lascio e mi terrà l'orario aggiornato.
Visto che siamo andati un pò offtopic aggiorno il titolo e ripropongo anche la questione:
ho fatto delle prove ieri e mi sembra di aver capito che il costrutto if-else if-else è mutuamente esclusivo a differenza di quanto pensavo, e credo che la soluzione proposta da fvlgnn
Esattamente.
L'ultima versione del codice che caricherai sul chip dovrà avere un semplice controllo per verificare che l'orologio stia andando oppure no. Con la batteria tampone, una volta avviato non si ferma più. Nel caso del DS1307 le librerie mettono spesso a disposizione una funzione detta isRunning() che controlla solo se un particolare flag del chip è impostato oppure no, per capire se l'RTC sta andando. In caso l'orologio sia fermo, basta far impostare l'orario dall'utente:
if (!rtc.isRunning()) {
impostaOrario();
}
Nei PCF8563 puoi invece controllare se il giorno e/o il mese sono a 0, nel caso l'orologio si è fermato ed è ripartito da zero.
X iscrizione