tempo max delay

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?

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.

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

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

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

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

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

Leo -1 ]:smiley:

e se si modificasse il prescaler ?

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.

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

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.

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.

leo72:
@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 :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:
Nel codice del Delay(), nel post precedente, l'output della funzione micros() viene forzatamente convertito in 16bit

(uint16_t)micros();

anche se non so il perché.

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.

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