Strano problema su ciclo millis

Concordo in pieno.

Guglielmo oramai azzerare il contatore millis è pratica comune (da non seguire). È incredibile come le cattive abitudini si diffondano più rapidamente di quelle buone.

Comunque, se dovete inizializzare una variabile con il contenuto di millis, scrivete così:

if (!myCounter) {
    myCounter = millis();     
}

Quando il contatore myCounter è scaduto e volete reinizializzarlo basta azzerare il suo valore:

myCounter = 0;

if (!myVar) funziona perché if (myVar) viene valutata true, se il valore di myVar è diverso da zero che significa minore o maggiore di 0. Il punto esclamativo inverte la valutazione così che se if (0) è valutato false, if (!0) viene valutato true. Quindi si entra nel blocco della if sono se myVar è uguale a 0.
Ovviamente si può scrivere in altri modi:

if (myVar == 0)
if (!(myVar != 0))

La seguente riga si trasforma quindi da:

if (timer_signal_1_1 == 0) timer_1_1 = millis(), timer_signal_1_1 = 1 ;

in:

if (!timer_1_1) {
   timer_1_1 = millis();
}

È evidente che si risparmia una variabili per ogni temporizzazione.
Il nome della variabile in cui salviamo il valore corrente di millis() dovrebbe essere più esplicativa, tanto che al posto di timer_1_1 potrei usare T1_1 o altro tanto non avrebbe un significato lampante.

La seguente if significa: Se il tempo trascorso dall'instante timer_1_1 è minore di 6000ms esegui il codice
che ulteriormente tradotto significa esegui il blocco per il tempo di 6000ms, è proprio questo che si voleva fare, si vuole che il microcontroller esegue sempre lo stesso codice per 6000ms, io non lo so, ma mi sembra tempo cpu sprecato.

if ((millis () - timer_1_1) < 6000)

Ciao.

MauroTec:
Guglielmo oramai azzerare il contatore millis è pratica comune (da non seguire). È incredibile come le cattive abitudini si diffondano più rapidamente di quelle buone.

Concordo ...
... ormai la rete è piena di tutorial zeppi di errori, collegamenti elettrici che se li fai rischi di bruciare qualche componete e ... chi più ne ha più ne metta !

Per questo io insito sempre ... XD

Guglielmo

Il problema e' che le virgole non ci andrebbero (e mi sembra che manchino anche un po di graffe, ma potrebbe essere una mia impressione :P)

Ad esempio ... la riga che scrivi cosi

if (timer_signal_1_1 == 0) timer_1_1 = millis(), timer_signal_1_1 = 1 ;

dovrebbe invece essere cosi, secondo i vari reference che ho letto:

if (timer_signal_1_1 == 0) {
    timer_1_1 = millis();
    timer_signal_1_1 = 1;
}

e cosi via ... correggetemi se sbaglio :stuck_out_tongue: ...

@eteme, purtroppo quella sintassi viene accettata dal compilatore. Fa schifo ma viene accettata.

Che poi si può scrivere anche su una linea sola usando le più adeguate graffe e punto e virgola:

if (timer_signal_1_1 == 0) { timer_1_1 = millis(); timer_signal_1_1 = 1 ; }

Viene accettata perché sta usando l'operatore virgola ma le istruzioni si terminano col punto e virgola, che è ben diverso.

@robpg:

SE lei legge questo post nello sketch avevo modificato le virgole come mi aveva suggerito,

il codice che ho quotato nel mio reply l'ho preso proprio dall'ultimo sketch che hai pubblicato, dove si vedono le virgole messe in ben 3 punti diversi.
Prima di rispondere sentendoti ingiustamente ripreso, pensa che forse ti hanno mosso un appunto del tutto giustificato. Il fatto che ti funzioni il codice non significa che quel codice sia corretto, significa solo che c'è una combinazione tale per cui per qualche strana alchimia del compilatore viene eseguito in una certa maniera.

SE poi dobbiamo darci del lei, basta che me lo dica. Saluti.

nid69ita:
@eteme, purtroppo quella sintassi viene accettata dal compilatore. Fa schifo ma viene accettata.

Non saprei, io non l'ho mai usata ... cioe'. anch'io a volte scrivo operazioni a riga singola, ma solo se hanno una sola azione ... ad esempio tipo

if (a == b) { a++; }

O simili ... se fra le graffe ci devo mettere piu di una operazione, preferisco separarle ... e comunque anche in queste le graffe le metto sempre (non ho mai provato a farne a meno, ma se le hanno previste, a qualcosa serviranno, immagino :P)

No assolutamente le davo del lei per una questione di rispetto.E ha pienamente ragione su quelle virgole che comunque ho corretto e il codice non funziona ugualmente.

if (timer_signal_1_1 == 0) timer_1_1 = millis(), timer_signal_1_1 = 1 ;

in

if (timer_signal_1_1 == 0) timer_1_1 = millis(); timer_signal_1_1 = 1 ;

La ringrazio anzi ti ringrazio.
saluti

Occhio @rob, hai corretto ma NON hai scritto la stessa cosa, ovvero hai inserito un errore.
Così la seconda che hai scritto è identica alla prima:

if (timer_signal_1_1 == 0) { timer_1_1 = millis(); timer_signal_1_1 = 1 ; }

Senza graffe solo la prima istruzione è nell'if, la seconda è eseguita sempre

@ robpg : ma prima di buttarsi a scrivere certi programmi ...
... imparare sufficientemente la sintassi del C (... studiandosi un buon libro) ed a scrivere il codice in modo decente no ??? ]:smiley:

Guglielmo

gpb01:
dare questo suggerimento fuorviante agli altri ... :slight_smile:

Guglielmo

mah... mica mi pagavano per fuorviare gli altri, ho solo cercato di dare una mano (nei limiti delle mie possibilità) a un utente su un qualcosa di non banale,

... no, così non dai una mano ... dai informazioni scorrette e insegni pessime abitudini ... ]:smiley: ]:smiley: ]:smiley:

Guglielmo

@elrospo

Volere aiutare gli altri ti fa onore, purtroppo consigliare di azzerare la variabile timer0_millis non è un aiuto.
Capisco che in questo modo tu hai risolto il problema dell'overflow, tuttavia leo72 ha scritto degli articoli che spiegano come si evita il problema del overflow del contatore, che devono essere letti e compresi per fare un passo avanti.

Capisco che i motivi per cui ti sconsigliamo di azzerare il contatore timer0_millis ti sembrano oscuri e proprio per questo devi al momento seguire il consiglio dei programmatori che conoscono il core di Arduino come le loro tasche.
Più in la, anzi già adesso hai le basi per comprendere gli oscuri consigli, devi solo prenderti il tempo per approfondire, dopo di che sconsiglierai anche tu tale cattiva pratica. Io non azzero mai il contatore anche se saprei come farlo in modo corretto, principalmente perché mi comporta lo studio del codice coinvolto, es codice di libreria che non ho scritto io al fine di verificare che l'azzeramento non comporti malfunzionamenti.

Capisci che studiare codice scritto da altri e analizzarlo nel dettaglio comporta tempo, tempo che possiamo considerare speso male se c'è già una soluzione studiata da altri per evitare l'owerflow, soluzione che non ha side effect (cioè la medaglia a sempre due lati). Io più che side effect lo chiamerei effetto farmaco, aggiusta una cosa e ne sfasci un altra.

Ciao.