Funzione delay impazzita - Arduino mega

Buonasera,
Sono giorni che combatto con la funzione delay poiché sembra non essere assolutamente affidabile con le tempistiche indicate nel parametro.

Se uso delay(1000) mi aspetto un'attesa di 1 secondo ma.... Risulta essere assolutamente inaffidabile infatti per poter simulare un secondo di attesa devo almeno effettuare un delay(100000).

Da cosa può dipendere? Forse Arduino mega corrotto?

Non ne vengo a capo.
Grazie per le eventuali risposte

Buonasera,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

Fatto! :smiley:

Gene76:
Se uso delay(1000) mi aspetto un'attesa di 1 secondo ma.... Risulta essere assolutamente inaffidabile infatti per poter simulare un secondo di attesa devo almeno effettuare un delay(100000).

Difatti, se Arduino funziona bene, delay(1000) arresta completamente il programma per il tempo di 1000 millisecondi.

Hai per caso modificato la programmazione di Timer0 ? Hai, per caso, ricaricato il bootloader? Quali modifiche hai fatto?

Perché evidentemente NON c'è congruenza tra il "core" e il tempo realmente contato da detto Timer ... ::slight_smile:

Guglielmo

Prova ad utilizzare l'esempio BlinkWithoutDelay.
Se anche con quello i tempi "sbarellano", butta la mega e comprane una originale!

Ciao a Tutti,
dopo innumerevoli prove, ho constatato che il problema non è arduino mega ma la seguente libreria

#include <TVout.h>

infatti utilizzando la subroutine:

TV.begin(PAL,120,96);

il famoso delay(XXXX) inizia a sbarellare.

ovviamente non capisco come sia possibile... ma il problema sembra questo.

P.s. non ho agito in alcun modo sul Timer0 ne sul bootloader....

fatemi sapere cosa ne pensate.

grazie mille!
Ciao!

Evidentemente la libreria in questione agisce sul timer, tra l'altro se cerchi sul forum mi ricordo che in passato veniva indicato che l'uso di tale libreria impegnava Arduino quasi al massimo delle sue capacità per rispettare le tempistiche della trasmissione alla tv, magari è proprio pr questo che modifica la gestione dei timer onde evitare che il segnale video venga compromesso

Gene76:
.... P.s. non ho agito in alcun modo sul Timer0

... tu no, ma da quanto dici sembra che la libreria alteri in qualche modo le tempistiche di Arduino. Sicuramente ha bisogno di un timer per generare i vari segnali di sync TV, ma dovrebbe usare un'altro timer e non Timer0 ... ::slight_smile:

Da dove hai scaricato la libreria? Spero bene dal "Library Manager" del IDE così da avere la versione più aggiornata ...

Guglielmo

Ciao, si ho scaricato la libreria dal "Library Manager"...ma forse ho capito.

credo ci sia una omonimia con le funzioni delay.

cioè esiste la delay anche nella libreria TVout.

" Details
Delay some number of ms with an accuracy of: 20ms for PAL and 16ms for NTSC.
Use
delay(time) * Arguments: * unsigned int time: * The time in ms to wait before returning."

in pratica, se la richiamo tramite:

TV.delay(1000) il comportamento è corretto ma se la richiamo con la classica delay(1000) di arduino, tutto sbarella.

non dovrebbe, se non richiamata da TV utilizzare la funzione dell'IDE?

help!!!

... che "geni" ... chiamare un metodo della libreria con lo stesso none di una funzione del "core" Arduino ... ::slight_smile:

Secondo me, la cosa più saggia sarebbe aprire tutti i sorgenti della libreria e dove trovi la loro delay() chiamarla con un altro nome, esempio tvdelay(). Basta fare un find/replace su tutti (TUTTI) i sorgenti della libreria ...

Guglielmo

Ragazzi, ma che fatica! :o

possibile che sia davvero cosi ?!?!?

comunque non mi spiego questo:
non dovrebbe, se non richiamata da TV utilizzare la funzione dell'IDE?

credo che il solito nome sia voluto proprio per far usare il loro che evidentemente non è bloccante come il delay standard, ovvero il programma resta bloccato li ma la loro libreria mantiene in sync il segnale video.
E' solo un ipotesi ma credo sia meglio adeguare il suo programma sostituendo i delay con TV.delay

Gene76:
non dovrebbe, se non richiamata da TV utilizzare la funzione dell'IDE?

Si, ma avendo la libreria agito sui timer la funzione standard non funzione come ti aspetti, ovvero non rispetta i tempi.
Credo che se vuoi che i tempi vengano rispettati tu debba usare la funzione della libreria, io non la conosco ma magari è documentata la cosa

La cosa mi sembra ovvia
Siccome serve mantenere il sincronismo (anzi, i sincronismi) televisivi la funzione delay è veleno,
Ecco quindi perché ne hanno creata una specifica
E non mi sorprenderebbe se all'interno della libreria fosse pure sovraccaricata
È quindi sbagliato sia usarla che sostituirla nel sorgente della libreria
Ma tutto questo è scritto nella documentazione? Lo OP la ha letta?

>fabpolli: NO, né un'affermazione, né l'altra ...

/* delay for x ms
 * The resolution is 16ms for NTSC and 20ms for PAL
 *
 * Arguments:
 *	x:
 *		The number of ms this function should consume.
*/
void TVout::delay(unsigned int x) {
	unsigned long time = millis() + x;
	while(millis() < time);
} // end of delay

... quindi NON mi spiego cosa l'abbiano fatta a fare, visto che È bloccante (usa un while() in cui resta bloccata) e non fa altro che fare peggio quello che fa già la delay() del "core" ... ::slight_smile:

Il resto, se ho ben visto, è gestito ad interrupt, quindi, se è così, può tranquillamente usare la delay().

Guglielmo

P.S.: ... e, per di più, usa millis(), quindi sembra che millis() non venga alterato ... ::slight_smile:

Standardoil:
È quindi sbagliato sia usarla che sostituirla nel sorgente della libreria

Nulla di sbagliato ... è l'unica strada se vuole usare la delay() del "core" ... sapendo che, bloccando Arduino, SE il resto non è gestito ad interrupt (e non ho ancora verificato), il refresh video si ferma ... che può anche NON essere un problema.

Guglielmo

... mi sembra di vedere che i segnali di sync siano generati tramite un timer dedicato (sulla UNO dovrebbe essere Timer2) tanto è vero che hanno dei pin ben precisi in funzione della scheda, quindi, la delay() non arresta il funzionamento di detto timer, ma sicuramente arresta altre cose per cui, probabilmente, la può usare solo quando NON gli serve l'immagine video.

QUI la libreria su github.

Guglielmo

Vero, non ho aperto la libreria stavo facendo supposizioni :slight_smile: , allora si è inspiegabile l'uso del solito nome.

Gene76:
TV.delay(1000) il comportamento è corretto ma se la richiamo con la classica delay(1000) di arduino, tutto sbarella.

... beh, allora, invece di fare un sacco di modifiche e rendere poi NON aggiornabile la libreria, effettivamente, perché invece di scrivere delay()non scrivi TV.delay()? Tenendo però conto che, al massimo, puoi indicare 65535 msec, perché, i "geni" l'hanno pure fatta che acceta un "unsigned int" e NON un "unsigned long" ... ::slight_smile:

Guglielmo

Beh, dai... solitamente il delay si usa per pochi secondi al massimo (e se è accettabile bloccare tutto)... Che senso ha tenere bloccato tutto per minuti, ore o giorni??? :slight_smile: