Dopo aver rilasciato il leOS, mi è stato fatto notare che spesso alcune librerie di terzi usano il timer 2, risultando incompatibili con leOS. Altri mi hanno chiesto uno schedulatore più semplice, sempre indipendente dai timer/interrupt del microcontrollore.
Rielaborando il core del leOS è nato looper (che si potrebbe tradurre in un orrido “ciclicatore”), che altro non è se non una routine che esegue ad intervalli prefissati altre sub-routine. looper non usa timer o interrupt ma si basa esclusivamente sulla funzione millis() di Arduino.
A differenza di leOS, va richiamato manualmente all’interno del ciclo principale del proprio sketch ma, rispetto ad esso, consuma meno risorse ed è indipendente dall’hardware, potendo essere compilato su ogni microcontrollore supportato dall’IDE di Arduino.
Per usare looper, scaricate il pacchetto che trovate in fondo all’articolo e scompattatelo all’interno della vostra cartella delle librerie (/home/utente/sketchbook/libraries su Linux, \Documenti\Arduino\libraries su Windows). Fatto questo, includete il core di looper all’inizio del vostro sketch e create una nuova istanza della libreria:
#include "looper.h"
looper myScheduler;
Fatto questo, siete pronti ad usare looper. Looper mette a disposizione questi 4 metodi per gestire i compiti, che nel looper si chiamano “jobs”:
myScheduler.addJob(funzione, intervallo_in_ms[, ONE_TIME]);
myScheduler.removeJob(funzione);
myScheduler.pauseJob(funzione);
myScheduler.restartJob(funzione);
La sintassi è identica a quella dei corrispondenti metodi di leOS con la differenza che “Task” è stato sostituito da Job per far capire che nel looper le funzioni da eseguire non sono indipendenti dal codice principale (nel leOS esse sono eseguite da uno scheduler gestito da un interrupt). Con .addJob si aggiunge allo scheduler un nuovo job indicato da “funzione”, con un intervallo di esecuzione specificato da “intervallo_in_ms”. L’aggiunta del parametro opzionale ONE_TIME indica a looper che questo task deve essere eseguito 1 volta sola e poi eliminato.
.removeJob elimina il task indicato, mentre .pauseJob e .restartJob rispettivamente mettono in pausa e riavviano un determinato job.
Per far lavorare looper basta aggiungere la chiamata al metodo .scheduler() in qualunque parte del loop principale:
void loop() {
...
myScheduler.scheduler();
}
Una importante caratteristica di looper è il metodo .myDelay() che permette di fermare l’esecuzione del codice contenuto nel loop() senza fermare l’esecuzione dei job che sono presenti nello scheduler. Per usare questa funzione basta sostituire la funzione delay() di Arduino con .myDelay():
...
myScheduler.myDelay(intervallo in ms);
...
Visto che looper non si basa sugli interrupt, la sua precisione dipende totalmente dalla durata del loop principale. looper funziona bene se il loop principale ha una durata inferiore a quella del task con il tempo di intervallo più breve perché altrimenti il task verrà eseguito non alla scadenza prefissata ma dopo il loop principale. looper non viene invocato automaticamente ma solo manualmente: è in pratica una routine come tutte le altre che richiama altre routine.
Corredano la libreria diversi esempi che mostrano l’utilizzo di looper.
NOTA:
il codice basato sulla precedente versione di looper deve essere aggiornato per renderlo compatibile con la nuova sintassi dei metodi.
NOTA PER GLI UTENTI DI leOS:
a partire dalla versione 1.0.0, looper può essere utilizzato abbinato al leOS: uno degli esempi allegati mostra proprio questa possibilità.

5 commenti
1 ping
Vai al modulo dei commenti ↓
Codeman
23 ottobre 2012 a 13:33 (UTC 1) Link a questo commento
That seems to be a very nice tool for me. But I have a simple problem (maybe a general C++ problem than a problem with your schedular?):
I want to add a member function of an object to the schedular:
— cut here —
#include “looper.h”
#include
#include “DMX_RGB.h”
looper myScheduler;
DMX_RGB LEDBar1(9,10,11,8);
DMX_RGB LEDBar2(12,13,14,8);
DMX_RGB LEDBar3(15,16,17,8);
DMX_RGB Spot1(1,2,3,7);
void setup()
{
myScheduler.addTask(LEDBar1.worker,MASTER_TIMER);
}
void loop()
{
myScheduler.scheduler();
}
— cut here —
But the compiler complies:
LightShow.cpp: In function ‘void setup()’:
LightShow:13: error: no matching function for call to ‘looper::addTask(, int)’
How can I add an obejct member function to the schedular?
Regards, Codeman
Leonardo Miliani
24 ottobre 2012 a 00:47 (UTC 1) Link a questo commento
What does LEDBar1 is? The compiler’s saying that it’s not a function.
Codeman
24 ottobre 2012 a 10:52 (UTC 1) Link a questo commento
LEDBar1 ist an instance ob the DMX_RGB object. Here is the class definition:
class DMX_RGB {
private:
byte _red;
byte _green;
byte _blue;
byte _dim;
byte _red_memory;
byte _green_memory;
byte _blue_memory;
int _steps;
int _addr_red;
int _addr_green;
int _addr_blue;
int _addr_dim;
float _stepping_red;
float _stepping_green;
float _stepping_blue;
public:
DMX_RGB(int addr_red, int addr_green, int addr_blue, int addr_dim);
~DMX_RGB();
void set_rgbd(byte r, byte g, byte b, byte d);
void set_r(byte r);
void set_g(byte g);
void set_b(byte b);
void set_d(byte d);
void fade_to(byte r, byte g, byte b, int time, int steps);
void fade_to(byte r, byte g, byte b, int time);
void set_steps(int steps);
void flash(byte flashes, int min_time, int max_time, int fade_time);
void worker();
};
As you see there is a public method named “worker()” which I want to be called from looper. So I thaught that LEDBar1.worker() should be the function I can call with looper::addTask…
Leonardo Miliani
24 ottobre 2012 a 22:14 (UTC 1) Link a questo commento
OK. Try creating a little function inside your code, put in it the call for the method and then add that function to the scheduler.
I.e.:
void setup() {
myScheduler.addTask(tempFunction,MASTER_TIMER);
….
}
void loop() {
myScheduler.scheduler();
}
vodi tempFunction() {
LEDBar1.worker();
}
Codeman
25 ottobre 2012 a 09:12 (UTC 1) Link a questo commento
With a function wrapper it seems to work! Thanks a lot!
khriss.com leOS, un sistema operativo essenziale per Arduino da Leonardo Miliani | khriss.com
30 agosto 2012 a 09:36 (UTC 1) Link a questo commento
[...] richiesto da numerose applicazioni – e dovrebbe “liberare” il PWM sui pin 3 e 11. looper è uno scheduler molto più semplice di leOS che dev’essere invocato esplicitamente dagli [...]