Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Aiuto per convertire file arduino da delay a millis..

378 views
Skip to first unread message

M.G.

unread,
Nov 29, 2011, 1:43:43 PM11/29/11
to
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);

}

delo

unread,
Nov 30, 2011, 3:08:42 AM11/30/11
to
non conosco arduino, penso potresti usare
un timer periodico ( un clock) col periodo di un secondo
che attiva un interrupt. (cerca periodic interrupt /timer)
la gestione di questo interrupt accende e spegne i led
(potresti tenere un array con un elemento per ogli led con
il tempo che deve rimanere acceso, ad ogni interrupt lo
abbassi di 1 finche' non e' <=0 a quel punto lo ricarichi
con un valore casuale (due array e due
numeri casuali per avere i tempi acceso,spento.)
quindi ritorna al programma principale che fa le cose
aggiuntive.

ciao
delo


"M.G." <ma...@email.it> ha scritto nel messaggio
news:DJ9Bq.104530$GZ3....@tornado.fastwebnet.it...

ma...@email.it

unread,
Nov 30, 2011, 4:30:18 AM11/30/11
to
ti ringrazio per la risposta, ma preferirei usare la piattaforma di arduino,
per studio...



"delo" ha scritto nel messaggio news:jb4od4$mif$1...@speranza.aioe.org...

non conosco arduino, penso potresti usare
un timer periodico ( un clock) col periodo di un secondo
che attiva un interrupt. (cerca periodic interrupt /timer)
la gestione di questo interrupt accende e spegne i led
(potresti tenere un array con un elemento per ogli led con
il tempo che deve rimanere acceso, ad ogni interrupt lo
abbassi di 1 finche' non e' <=0 a quel punto lo ricarichi
con un valore casuale (due array e due
numeri casuali per avere i tempi acceso,spento.)
quindi ritorna al programma principale che fa le cose
aggiuntive.

ciao
delo


"M.G." <ma...@email.it> ha scritto nel messaggio
news:DJ9Bq.104530$GZ3....@tornado.fastwebnet.it...
> 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?

delo

unread,
Nov 30, 2011, 8:44:45 AM11/30/11
to
Non ho detto di cambiare piattaforma... per prova ho provato a cercare
interrupt, timer, periodic clock, array INSIEME a "arduino" per vedere
degli esempi.
La mia indicazione era solo su una possibile modalità per avere due "task"
una per le luci e una per l'altra applicazione, non so se arduino ha nativa
la
possibilità di fare multitasking, ma forse si può cercare anche questa con
google...
I tools per usarlo sono free e prevedono la possibilità di sumulazione su
pc?

ciao
delo


<ma...@email.it> ha scritto nel messaggio
news:4JmBq.104698$GZ3....@tornado.fastwebnet.it...
> ti ringrazio per la risposta, ma preferirei usare la piattaforma di
> arduino, per studio...
>
>
>
> "delo" ha scritto nel messaggio news:jb4od4$mif$1...@speranza.aioe.org...
>
> non conosco arduino, penso potresti usare
> un timer periodico ( un clock) col periodo di un secondo
> che attiva un interrupt. (cerca periodic interrupt /timer)
> la gestione di questo interrupt accende e spegne i led
> (potresti tenere un array con un elemento per ogli led con
> il tempo che deve rimanere acceso, ad ogni interrupt lo
> abbassi di 1 finche' non e' <=0 a quel punto lo ricarichi
> con un valore casuale (due array e due
> numeri casuali per avere i tempi acceso,spento.)
> quindi ritorna al programma principale che fa le cose
> aggiuntive.
>
> ciao
> delo
>
>
> "M.G." <ma...@email.it> ha scritto nel messaggio
> news:DJ9Bq.104530$GZ3....@tornado.fastwebnet.it...
>> 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?

mmm

unread,
Dec 1, 2011, 9:09:15 AM12/1/11
to
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

Marco Trapanese

unread,
Dec 1, 2011, 10:01:16 AM12/1/11
to
Il 01/12/2011 15:09, mmm ha scritto:

> 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


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

Hum

unread,
Dec 1, 2011, 5:41:09 PM12/1/11
to
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


mmm

unread,
Dec 2, 2011, 9:12:14 AM12/2/11
to
Marco Trapanese wrote:
> Il 01/12/2011 15:09, mmm ha scritto:
>
>> 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
>
>
>
> 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.
>

la tua soluzione e' quella "giusta", chiaramente un pelo piu' complessa
da implementatre per un principiante, tra l'altro non conosco bene
"arduino" ma ho avuto la sensazioneche introduce uno straterello sw tra
l'hardware e il programma utente ( accetto ben volentrieri smentite )
per cui il cpodice di interrupt potrebbe nno essere raggiungibile

> Marco
>

M.G.

unread,
Dec 4, 2011, 2:03:10 PM12/4/11
to
Il 01/12/2011 23:41, Hum ha scritto:
> 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.

ottima idea!
grazie :-D

Stefano Di Paolo

unread,
Dec 4, 2011, 6:28:53 PM12/4/11
to
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
0 new messages