Pages: [1]   Go Down
Author Topic: tempo max delay  (Read 911 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

volevo sapere se la funziuone delay ha un tempo massimo oltre il quale non si puo andare, o potrebbe dare problemi,
es si potrebbe tenere acceso un led per 30 minuti o un ora o piu?
Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Offline Offline
Sr. Member
****
Karma: 0
Posts: 381
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

More knowledgeable programmers usually avoid the use of delay() for timing of events longer than 10's of milliseconds unless the Arduino sketch is very simple.
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 103
Posts: 6579
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si, 4'294'967'295 millisecondi, ovvero il limite dell'unsigned long. Più o meno 50 giorni.
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si, 4'294'967'295 millisecondi, ovvero il limite dell'unsigned long. Più o meno 50 giorni.

grazie mille sei stato molto chiaro,  comprensibile anche ad uno che ne sa poco  di programmazione
« Last Edit: May 28, 2012, 08:24:57 am by GINGARDU » Logged


Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Il discorso non è così semplice. Non è che ad ogni utilizzo, il contatore su cui si basa la funzione delay si riazzera per cui ogni 30 minuti puoi  usare delay senza problemi.
Delay è agganciata ad un timer interno del micro che incrementa una variabile di tipo unsigned int a 32 bit, il cui valore max è 2^32-1, ossia appunto quello pubblicato da Paolo. Però questa variabile viene incrementata sempre, quindi dopo 49,7 giorni per l'esattezza essa va in overflow e riparte da zero. Ciò significa che se il tuo controllo si trova a cavallo dell'overflow potresti avere un salto di un intervallo (quindi un delay di 1 ora invece che di 30 minuti) oppure un tempo molto più lungo, a seconda di come hai implementato il controllo.

Se ti servono intervalli così lunghi, guarda qui
http://arduino.cc/forum/index.php/topic,101938.0.html
Trovi la mia secTimer che introduce un contasecondi che va in overflow dopo 136 anni! E' disponibile sia come libreria che usa il timer 2 sia come modifica al core dell'Arduino per non "rubare" un timer (ed i relativi 2 pin PWM).
Logged


Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 103
Posts: 6579
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Il discorso non è così semplice. Non è che ad ogni utilizzo, il contatore su cui si basa la funzione delay si riazzera per cui ogni 30 minuti puoi  usare delay senza problemi.
Delay è agganciata ad un timer interno del micro che incrementa una variabile di tipo unsigned int a 32 bit, il cui valore max è 2^32-1, ossia appunto quello pubblicato da Paolo. Però questa variabile viene incrementata sempre, quindi dopo 49,7 giorni per l'esattezza essa va in overflow e riparte da zero. Ciò significa che se il tuo controllo si trova a cavallo dell'overflow potresti avere un salto di un intervallo (quindi un delay di 1 ora invece che di 30 minuti) oppure un tempo molto più lungo, a seconda di come hai implementato il controllo.

Se ti servono intervalli così lunghi, guarda qui
http://arduino.cc/forum/index.php/topic,101938.0.html
Trovi la mia secTimer che introduce un contasecondi che va in overflow dopo 136 anni! E' disponibile sia come libreria che usa il timer 2 sia come modifica al core dell'Arduino per non "rubare" un timer (ed i relativi 2 pin PWM).

il codice della funzione delay() è nel core di Arduino nel file wiring.c
Code:
void delay(unsigned long ms)
{
uint16_t start = (uint16_t)micros();

while (ms > 0) {
if (((uint16_t)micros() - start) >= 1000) {
ms--;
start += 1000;
}
}
}
(versione IDE 1.0)

La variabile ms che è quella impostata per il delay viene decrementata ogni 1000 microsecondi, ovvero ogni millisecondo.
Quando arriva a 0 esce dal ciclo while. smiley-wink
Il problema che indica Leo è nella funzione micros() che utilizza un contatore a 16 bit. (valore massimo 65536)
Che si resetta ogni 65 millesecondi procurandoti un ritardo poco inferiore al millisecondo.
Diciamo che se imposti un delay di 49 giorni forse dopo 48 e mezzo smette.  smiley-mr-green smiley-mr-green

Leo -1  smiley-twist
« Last Edit: May 28, 2012, 11:41:27 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
Full Member
***
Karma: 3
Posts: 113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

e se si modificasse il prescaler ?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So che è OT ma non puoi fare a meno di utilizzare il delay()?
Alla fine blocca il programma, e anche se per un progetto semplice può andare bene, se si amplia può rallentare( e non poco)

Puoi implementare una logica del tipo tick/tock e il limite di tempo è sempre quello della funzione millis() prima che essa vada in overflow, quindi circa 49 giorni. Così hai lo steffo funzionamento senza bloccare il processore.
« Last Edit: May 28, 2012, 02:19:54 pm by Tr3nT » Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@pablos:
tu hai esaminato delay ma non hai guardato tutto il resto.
delay sfrutta, come dici, micros(), che è un contatore aggiornato nell'ISR che intercetta l'overflow del contatore del timer 0. Essendo una variabile di tipo unsigned long (quindi a 32 bit, non a 16  smiley-wink ), anch'essa andrà in overflow, prima o poi. E si presenta lo stesso problema con il delay che ti ho descritto.
Inoltre il timer 0 è impostato per andare in overflow ogni 0,001024s se non ho fatto male i conti.
Logged


Offline Offline
Full Member
***
Karma: 3
Posts: 113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma scusate ditemi almeno se sbaglio consigliando di settare il prescaler, non si moltiplicherebbe esponenzialmente il limite massimo di delay ? so che rallenterebbe tutto ma non ho capito bene a cosa gli serva scusate.
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho pubblicato un link ad una discussione in cui presentavo una libreria contasecondi. Con quella ha un'autonomia di 136 anni circa con risoluzione di 1 secondo. Visto che deve misurare un tempo di 30 minuti, credo che gli basti ed avanzi. Inoltre non è bloccante perché può usare la funzione seconds() per avere i secondi passati, creando dei cicli di controllo come quelli che si fanno basati su millis() per non bloccare il micro in attese con delay.
Logged


Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 103
Posts: 6579
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@pablos:
tu hai esaminato delay ma non hai guardato tutto il resto.
delay sfrutta, come dici, micros(), che è un contatore aggiornato nell'ISR che intercetta l'overflow del contatore del timer 0. Essendo una variabile di tipo unsigned long (quindi a 32 bit, non a 16  smiley-wink ), anch'essa andrà in overflow, prima o poi. E si presenta lo stesso problema con il delay che ti ho descritto.
Inoltre il timer 0 è impostato per andare in overflow ogni 0,001024s se non ho fatto male i conti.

PaoloP e non Pablos.  smiley-grin
Nel codice del Delay(), nel post precedente, l'output della funzione micros() viene forzatamente convertito in 16bit
Code:
(uint16_t)micros();
anche se non so il perché.
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Lo fanno per prendere la parte bassa del contatore, inserendo un dato a 32 bit in una variabile a 16, scarti i 2 byte più alti, tanto per la conta dei microsecondi ti interessa solo la parte comporta dai 2 byte più bassi.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ma scusate ditemi almeno se sbaglio consigliando di settare il prescaler,

Il limite massimo della delay è poco meno di 50 giorni, sempre e comunque perché non ha nulla a che vedere con la millis, ovvero anche se inizializzi la delay 1 secondo prima che la millis vada in overflow la sua durata massima possibile è sempre la stessa.
Unico fattore d'errore è dato solo dall'overflow della micros(), circa ogni 12 ore, il massimo effetto negativo è perdere non più di 1 ms ogni volta che la micros va in overflow, la delay continua comunque a fare il suo count down.
Logged

Pages: [1]   Go Up
Jump to: