[Risolto]Multitasking con Arduino?

Ciao a tutti ragazzi. Ho da poco compilato un codice per Arduino per poter controllare il motore di una caldaia a pellet.
Il codice che ho compilato, pur essendo abbastanza semplice, è molto lungo e contiene al suo interno molti if.
per farvi capire ha più o meno un aspetto del genere:

void loop(){
funzione di accensione bottone();

istruzione 1
istruzione 2
.
.
.
istruzione n

}

le istruzioni possono essere degli if oppure delle funzioni che mi sono creato io. Il mio problema è questo:
Se mi trovo in certe condizioni di temperatura che controllo con degli if nel void loop faccio accendere il motore per un tot secondi e poi lo faccio spegnere dai 4 ai 6 secondi. Il fatto è che se premo il pulsante per "spegnere" il ciclo, quindi interviene funzione di accensione bottone() devo aspettare per forza la fine di quei 4-6 secondi. Come posso migliorare questa situazione? non è possibile creare una specie di multitasking?cioè quando premo il pulsante di spegnimento in qualsiasi momento del programma Arduino risponda con la funzione di spegnimento?

Grazie mille ragazzi!

Hai 2 strade:

  1. usare la funzione millis() per gestire gli eventi in base al tempo, oppure
  2. usare leOS/leOS2. Questi sono 2 scheduler che ho scritto qualche mese fa e che possono eseguire in background semplici compiti (come ad esempio l'attivazione di un pin) ad intervalli programmati.
    Questa è la discussione in cui ho presentato il lavoro:
    http://arduino.cc/forum/index.php/topic,111732.0.html
    Qui trovi le librerie:
    leOS, un semplice SO per Arduino – Leonardo Miliani

grazie per la risposta leo.
Avevo visto già questi tuoi due scheduler. In effetti sono molto comodi, il fatto è che non posso usarli perché purtroppo l'evento non è regolare, è regolato dalla temperatura.
Mi sa che a questo punto mi toccherebbe utilizzare la funzione millis(), che peccato però...la funzione delay è molto comoda!almeno non devo scrivere altri if...

guarda che con il leos puoi modificare dinamicamente la durata di un task :wink:

Madwriter:
guarda che con il leos puoi modificare dinamicamente la durata di un task :wink:

Esatto.
Puoi mettere in pausa un task, riavviarlo a richiesta, farlo andare solo 1 volta (onetime task), cambiare l'intervallo in corso d'opera. E' molto aggiustabile alle proprie esigenze.

Scusa ma non puoi attaccare quel pulsante ad un interrupt

no non posso attaccarlo ad un itterrupt perchè per adesso ho preso in esempio il fatto di premere il bottone per accenderlo e spegnerlo, ma in sostanza riguarda tutta la funzionalità del programma, dall'aggiornamento sul monitor LCD della temperatura rilevata, alla comunicazione con la porta seriale ecc...per come l'ho compilato, queste istruzioni vengono eseguite dopo il tempo di delay...

Allora, Leo72 ho provato la tua libreria leOS.h e devo dire che è davvero fenomenale!Complimentoni davvero!
Avevi ragione a quanto pare può essere un metodo per liberarmi delle attese nel loop. Ora il mio piccolo problema è questo (dovuto al fatto che devo ancora devo fare pratica con questa libreria).
Ho trovato in giro un tuo esempio dove facevi accedere il led per 1000ms e poi spento per altri 1000ms.

Come potrei fare a tenerlo acceso ad esempio per 100ms e poi spento per 5000ms? Sempre utilizzando leOS ovviamente...scusate l'ignoranza
e poi se durante l'esecuzione del programma dovessi cambiare l'intervallo di tempo in cui rimane spento? ad esempio da 5000ms a 8000 ms come dovrei fare? Ho letto sulla tua guida in pdf che hai implementato la funzione

myOS.modifyTask(yourFunction, newInterval [, newTaskStatus]);

ma vale anche per la libreria leOS? o solo per leOS2?

Per principio e per la filosofia di un programma scritto bene, secondo me, non serve un multitasking per scrivere un programma del genere. Serve non usare delle funzioni che interrompono l'esecuzione del programma come per esempio delay().

Nel concreto leOS puó risolvere questo problema, ma é solo una cura contro gli effetti non la causa.

Ciao Uwe

Il concetti di base è la programmazione "a stati" anziché sequenziale.
Credo che leOS possa rendere l'implementazione più semplice rispetto alla tecnica "blink without delay" nuda e cruda (anche se in questo caso sarebbe più che sufficiente IMHO). Ma se non si acquisisce il concetto di "stato" la vedo dura...

hermit274:
Come potrei fare a tenerlo acceso ad esempio per 100ms e poi spento per 5000ms? Sempre utilizzando leOS ovviamente...scusate l'ignoranza
e poi se durante l'esecuzione del programma dovessi cambiare l'intervallo di tempo in cui rimane spento? ad esempio da 5000ms a 8000 ms come dovrei fare?

tuxduino:
Il concetti di base è la programmazione "a stati" anziché sequenziale.
Credo che leOS possa rendere l'implementazione più semplice rispetto alla tecnica "blink without delay" nuda e cruda (anche se in questo caso sarebbe più che sufficiente IMHO). Ma se non si acquisisce il concetto di "stato" la vedo dura...

Sì, devi lavorare a "stati". Cioè fissare uno "stato led", che poi modifichi tramite software.
Posso darti un suggerimento. Usa un task non solo per cambiare lo stato del led ad intervalli regolari (altrimenti viene un'onda quadra con d.c. al 50%,) ma con delle variabili controllare quanto il led deve stare acceso e quanto spento.

Ho letto sulla tua guida in pdf che hai implementato la funzione

myOS.modifyTask(yourFunction, newInterval [, newTaskStatus]);

ma vale anche per la libreria leOS? o solo per leOS2?

Le funzioni delle 2 versioni sono identiche, cambia solo il minimo intervallo selezionabile. Nel leOS questo è 1 ms, nel leOS2 questo è pari a 16 ms, il minimo intervallo selezionabile per il contatore del Watchdog.
Quindi se vuoi eseguire qualcosa ogni 2 ms il leOS2 non va bene. Per contro, il leOS entra in conflitto con tutto quello che usa il timer 2 mentre il leOS2 no. Devi vedere quale fa al caso tuo. A meno di usi con cose particolari (vedi ad esempio la Tone o altro) che fanno uso di quel timer, la leOS è da preferire. La leOS2 è ancora in beta (ho una cosa da sistemare che non mi torna del tutto).

Per Multitasking c'è questo microcontroller che costa davvero poco e li hai almeno 8 core a disposizione.
http://www.xmos.com/discover/why/how

Certo che ci sarebbe da farne una simil arduino a 500MHZ se si considera che costa meno del 328, purtroppo gcc non produce codice per questa architettura.

Ciao.

Solo 59 dollari? ci vedo male io? dovè la fregatura?

O_o

MauroTec:
Per Multitasking c'è questo microcontroller che costa davvero poco e li hai almeno 8 core a disposizione.
http://www.xmos.com/discover/why/how

Certo che ci sarebbe da farne una simil arduino a 500MHZ se si considera che costa meno del 328, purtroppo gcc non produce codice per questa architettura.

Ciao.

http://www.digikey.com/product-detail/en/XCARD%20XK-1A/XCARD%20XK-1A-ND/2183685?cur=USD

Solo 59 dollari? ci vedo male io? dovè la fregatura?

Bello! :smiley:

MauroTec:
Solo 59 dollari? ci vedo male io? dovè la fregatura?

Che non é cosí semplice a programmarlo come Arduino. :wink: :wink: :wink:
Ciao Uwe

uwefed:

MauroTec:
Solo 59 dollari? ci vedo male io? dovè la fregatura?

Che non é cosí semplice a programmarlo come Arduino. :wink: :wink: :wink:
Ciao Uwe

Si trattase solo di questo io non lo vedrei come una fregatura, la fregatura io la vedo in cose di questo tipo:
L'ide c'è solo per windows.
Lo sviluppo e chiuso e quindi anche gli schemi.
Devo spendere cifre che non posso permettermi solo per sperimentare.

E per adesso sembra non esserci alcuna fregatura in quanto:
L'ide è multi piattaforma, quindi anche linux e c'è un plugin per eclipse.
Il compilatore è un mix di gcc e altro codice per il parallelismo, quest'ultimo non so se è proprietario?
Il costo è ridicolo, specie se guardate questo link http://www.cooking-hacks.com/indexa.php/shop/shields/xmos-processor-xs1-l1-64.html
dove si vede che il micro costa 2.00 euro.

Una cosa non la capisco. Sembra che ci sia solo SRAM per accogliere il programma ed i dati, ed 8 KB di ROM per il bootloader. Ma se stacco l'alimentazione il firmware viene perso?

Ciao ragazzi. scusate se rispondo in ritardo. a quanto pare avevate ragione! la programmazione utilizzando i delay è proprio penosa! purtroppo, da principiante, nn pensavo che mettendo un delay qui e un altro li rallentare così tanto l'esecuzione del loop!
cmqe ieri sera ho sbattuto un pò e sono riuscito a eliminare tutti i delay utilizzando le librerie Metro.h

hermit274:
Ciao ragazzi. scusate se rispondo in ritardo. a quanto pare avevate ragione! la programmazione utilizzando i delay è proprio penosa! purtroppo, da principiante, nn pensavo che mettendo un delay qui e un altro li rallentare così tanto l'esecuzione del loop!
cmqe ieri sera ho sbattuto un pò e sono riuscito a eliminare tutti i delay utilizzando le librerie Metro.h

Errore comune, forse una introduzione ad arduino ed in genere alla programmazione su microcontroller ti avrebbe posto subito in evidenza la limitazione del delay, ma questo potrebbe scoraggiare molti appassionati che non avrebbero mosso neanche i primi passi usando il delay.

In altre parole, sbatterci il muso è meglio, chiedere lumi è meglio che fare da soli.

Ora che sai come fare per evitare il delay ti posso dare altri consigli.
In generale:
Conviene sempre spezzare il programma in tante funzioni che svolgono compiti che si esauriscono in breve tempo: es ti ritrovi a dovere ordinare
un'array di nomi, il che richiede 1 minuto, in questo tempo le altre parti del programma sono isolate e non vengono eseguite. Con gli interrupt attaccati sul timer si risolve. Ad esempio la leOS usa l'interrupt sul timer2 che interrompe periodicamente l'esecuzione di ordinamento di prima, controlla cosa c'è da fare, la fa ed esce ed il controllo ritorna alla routine di ordinamento. Il risultato è che l'ordinamento magari ci impiega più tempo ma almeno le altre parti del programma vengono eseguite periodicamente.

Conviene impiegare un po del proprio tempo a raggionare su questa cosa degli interrupt fino a mettere in evidenza i comportamenti negativi oltre che quelli positivi. Uno dei comportamenti negativi si ha quando uno o più pin devono cambiare di stato con tempistiche ristrette, in questo caso il codice che governa questi pin non deve essere interrotto pena il mancato rispetto delle tempistiche.

leo72:
Una cosa non la capisco. Sembra che ci sia solo SRAM per accogliere il programma ed i dati, ed 8 KB di ROM per il bootloader. Ma se stacco l'alimentazione il firmware viene perso?

Neanche io capisco come stanno le cose, ho provato a scaricare il datasheet ma devo iscrivermi e al momento non mi va. Tra le altre cose la memoria di 8K e di tipo OTP e non so quante volte può essere scritta. Insomma finche non si ha accesso totale alla doc rimangono tante domande e poche risposte imprecise.

Comunque se c'è interesse verso questa architettura apro un post nella sezione generale. Mi chiedo cosa pensa Astro di questa architettura, magari lui ne sa già qualcosa in più di noi e può far luce.

Ciao.

Allora parliamo di un Arduino MEGA?
La RAM puó essere scritta e letta infinte volte. La Flash ha un numero limitato di scritture/cancellazioni. Nella flash é memorizzato il Bootloader e il programma e non viene modificato durante l'esecuzione del programma ma solo quando fa un upload /programmazione. Un Kontroller in un dispositivo di orma viene programmato poche volte, una volta all inizio e dopo a qualche update del programma. Un dispositivo che usi come prototipo per scrivere e verificare il programma subbisce molte piú programmazioni ma starai anche dopo anni sempre sotto il valore massimo di scritture garantite.

Ciao Uwe