Newsgroup: it.hobby.elettronica.digitale
Titolo: Aiuto per convertire file arduino da delay a millis..

ciao a tutti,
ho fatto uno sketch per arduino 2009 che 
mi serve per accendere e spegnere 8 led 
a caso per un tempo a caso da 1 a 5 
secondi, fatto in modo che alcuni led 
rimangano accesi in contemporanea ad 
altri (simulando l'accensione e lo 
spegnimento delle luci di casette di un 
presepe), e funziona tutto.
Però ora vorrei convertire questo sketch 
in modo da non usare la funzione delay 
ma utilizzare la funzione millis perchè 
in contemporanea a questo codice vorrei 
fargli fare un'altra cosa.
 
Io ci ho provato in mille modi ma non ho 
capito proprio come fare...
c'è qualche anima pia che me lo può 
convertire?
 
Ecco il mio codice:
 
long ledrandom;
long timerandom;
 
 
 
void setup() {
   // initialize the digital pin as an 
output.
   // Pin 13 has an LED connected on 
most Arduino boards:
   pinMode(2, OUTPUT);
   pinMode(3, OUTPUT);
   pinMode(4, OUTPUT);
   pinMode(5, OUTPUT);
   pinMode(6, OUTPUT);
   pinMode(7, OUTPUT);
   pinMode(8, OUTPUT);
   pinMode(9, OUTPUT);
 
   randomSeed(analogRead(0));
}
 
void loop() {
   ledrandom = random(2, 10);
   digitalWrite(ledrandom, HIGH);
 
 
   timerandom = random(1000, 5000);
   delay(timerandom);
 
 
   ledrandom = random(2, 10);
   digitalWrite(ledrandom, LOW);
 
}

 ha scritto nel messaggio 
news:DJ9Bq.104530$GZ3....@tornado.fastwebnet.it...


 c'� qualche anima pia che me lo pu� convertire?


> c'è qualche anima pia che me lo può convertire?



soluzione "economica e commerciale"
 
il delay lo setti al quanto di tempo piu' piccolo ( diciamo .1 s o anche 
meno )
e poi nel loop principale ti organizzi tanti timer software ( 
decrementati ad ogni iterazione e ripristinati al loro valore quando si 
azzerano ) quanti sono i "task" che hai.
 
quando un contatore arriva a zero lo setti al valore desiderato di 
ritardo ed esegui il task a lui "associato" ( accensione / spegnimento / 
cambio di stato della luce
 

 cambio di stato della luce
 
 
Piccola variante che utilizzo io:
 
i timer software (contatori) li decremento direttamente nella isr del 
timer hw. Se sono a 0 imposto il flag relativo e ricarico.
Nel loop principale testo questi flag ed eseguo le operazioni necessarie.
 
Forse non c'è molta differenza ma mi sembra più leggibile il codice. La 
isr rimane comunque molto corta dal momento che le istruzioni da 
eseguire sono veramente poche. Inoltre è anche più facile gestire dei 
prescaler software utilizzando un ulteriore contatore a livello più alto.
 
Marco
 

Nel void loop metti un ciclo infinito all'interno del quale controlli quando 
passa un secondo (se vuoi con millis).
Ogni volta che passa un secondo generi un valore random da 1 a 5. Se il 
valore generato è =5 (o qualsiasi altro valore) allora commuti lo stato di 
accesso/spento del led relativo.
Questo ripetuto per tutti i led.
In questo modo sia lo stato di acceso che quello di spento varieranno in 
modo casuale da 1 a 5 secondi.
 
Alcuni spunti di base per farlo li puoi trovare qui: 
http://arduino.cc/en/Tutorial/BlinkWithoutDelay
 
 
Nel ciclo principale puoi poi inserire tutte le altre cose che vuoi fare. 
All'arduino dovrebbe restare tutto il tempo necessario per farle.
Ciao
 
 

 accesso/spento del led relativo.
 
ottima idea!
grazie :-D

Arduino non è multitasking, non c'è un sistema operativo in grado di
gestire la concorrenza.
Il bello è che puoi gestire direttamente tutto quello che vuoi
(programmare un timer, accedere a qualunque registro, ...) dato che il
codice che scrivi viene compilato dal gcc.
La soluzione gestita dall'interrupt si potrebbe scontrare con i
problemi di concorrenza per cui devi sapere esattamente quello che fai
durante l'interrupt e quello che fai nel programma principale: non
devono interferire tra loro; questo è ovvio ma le conseguenze (il
comportamento del programma) non sempre sono facili da prevedere per
via delle possibili interazioni impreviste.
 
Anche io al posto tuo farei + o - quello che ti hanno suggerito:
invece del delay metti un ciclo while in cui controlli se il tempo che
desideri è passato o no. Se non è passato chiami una funzione che
svolge l'altro compito.
Ovviamente questo altro compito deve durare 'poco' e restituire prima
possibile il controllo al ciclo while che conta il tempo.
Non puoi insomma mettere un altro ciclo while in cui ad esempio
aspetti (polling) che un certo segnale cambi di stato.
 
Spero di essere stato utile
ciao
Stefano
