Offline
God Member
Karma: 6
Posts: 551
|
 |
« on: May 28, 2012, 07:39:45 am » |
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
Sr. Member
Karma: 0
Posts: 381
|
 |
« Reply #1 on: May 28, 2012, 07:54:51 am » |
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
Offline
Faraday Member
Karma: 51
Posts: 3194
|
 |
« Reply #2 on: May 28, 2012, 07:55:18 am » |
Si, 4'294'967'295 millisecondi, ovvero il limite dell'unsigned long. Più o meno 50 giorni.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
God Member
Karma: 6
Posts: 551
|
 |
« Reply #3 on: May 28, 2012, 07:59:47 am » |
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...
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 17008
Don't know what I do
|
 |
« Reply #4 on: May 28, 2012, 10:46:47 am » |
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.htmlTrovi 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
Offline
Faraday Member
Karma: 51
Posts: 3194
|
 |
« Reply #5 on: May 28, 2012, 11:36:15 am » |
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.htmlTrovi 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.  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.  Leo -1 
|
|
|
|
« Last Edit: May 28, 2012, 11:41:27 am by PaoloP »
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 3
Posts: 92
|
 |
« Reply #6 on: May 28, 2012, 02:02:40 pm » |
e se si modificasse il prescaler ?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 40
|
 |
« Reply #7 on: May 28, 2012, 02:13:55 pm » |
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
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 17008
Don't know what I do
|
 |
« Reply #8 on: May 28, 2012, 03:48:32 pm » |
@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  ), 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
Jr. Member
Karma: 3
Posts: 92
|
 |
« Reply #9 on: May 28, 2012, 03:53:09 pm » |
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
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 17008
Don't know what I do
|
 |
« Reply #10 on: May 28, 2012, 04:06:42 pm » |
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
Offline
Faraday Member
Karma: 51
Posts: 3194
|
 |
« Reply #11 on: May 29, 2012, 03:46:17 am » |
@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  ), 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.  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é.
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 17008
Don't know what I do
|
 |
« Reply #12 on: May 29, 2012, 03:53:48 am » |
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
Tesla Member
Karma: 76
Posts: 7539
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #13 on: May 29, 2012, 04:13:23 am » |
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
|
|
|
|
|
|