Pages: [1] 2 3 ... 6   Go Down
Author Topic: looper - un semplice schedulatore senza timer/interrupt  (Read 8281 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22924
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Seguendo la scia di leOS, e su richiesta di m_ri ( smiley-razz ) ecco looper.
Looper è un semplicissimo lanciatore di routine che NON usa timer/interrupt del microcontrollore. Esegue piccoli task ad intervalli prefissati, calcolati ricorrendo ad uno schedulatore che si appoggia a millis. E' indipendente dall'hardware (quindi gira su ogni micro) proprio perché non usa niente che non sia contenuto nel core di Arduino.

Chi ha usato il leOS si troverà a casa con looper, dato che eredita alcuni metodi da leOS nonché la loro sintassi.
Per usare il looper bisogna caricare la sua libreria ed istanziarne una copia:

Code:
#include "looper.h"
looper myScheduler;
Fatto questo, i metodi a disposizione sono 4:
Code:
myScheduler.addTask(funzione, intervallo_in_ms[, ONETIME]);
myScheduler.removeTask(funzione);
myScheduler.pauseTask(funzione);
myScheduler.restartTask(funzione);

Per far lavorare looper basta aggiungere questa chiamata in qualunque parte del vostro loop principale:
Code:
void loop() {
  ...
  myScheduler.scheduler();
}

La sintassi è identica a quella dei corrispondenti metodi del leOS ed è descritta nel README allegato.
4 esempi corredano la libreria, per mostrare come usare usare looper.

NOTA:
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.
Ad esempio, se impostate un task che fa lampeggiare un led ogni 500 ms e nel loop mettete un delay(1000), il led lampeggerà ogni secondo! Questo è ovvio, dato che a differenza di leOS, looper non viene invocato automaticamente ma solo manualmente. E' in pratica una routine come tutte le altre che richiama altre routine.

Spero di aver fatto cosa gradita, come al solito  smiley-sweat

* looper-0.1.zip (20.44 KB - downloaded 38 times.)
« Last Edit: August 01, 2012, 05:33:06 pm by leo72 » Logged


0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5957
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mmmm.

se ho capito questo e' qualle che io intendevo per delay2.0()
il leOS anche c'era vicino, ma forse era troppo,.

e' vero che il delay1.0 blocca looper, ma, sempre se ho capito, io posso usare looper al posto di ogni delay che ho in uno sketch, eliminando di fatto i delay bloccanti, e tenendo in gioco solo looper.

se imposto looper per accendere un led ogni 500ms, e poi uso vari delay per un totale di 499ms, looper non sara' intaccato? il mio led lampeggera' ogni 500ms ?
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22924
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

mmmm.

se ho capito questo e' qualle che io intendevo per delay2.0()
il leOS anche c'era vicino, ma forse era troppo,.
il leOS è tutt'altra cosa, molto più raffinata. E' immune dai vari problemi dei delay.
looper è molto più semplice. E' giusto una routine programmata per richiamare altre routine.

Quote
e' vero che il delay1.0 blocca looper, ma, sempre se ho capito, io posso usare looper al posto di ogni delay che ho in uno sketch, eliminando di fatto i delay bloccanti, e tenendo in gioco solo looper.
Se i delay li metti solo per eseguire a determinati intervalli altri compiti, sì: puoi usare looper in quel modo. Lo sketch di esempio "looper_2_task" fa infatti lampeggiare 2 led usando solo looper.

Quote
se imposto looper per accendere un led ogni 500ms, e poi uso vari delay per un totale di 499ms, looper non sara' intaccato? il mio led lampeggera' ogni 500ms ?
L'importante è che il loop principale duri sempre meno del task con il più piccolo intervallo, altrimenti quest'ultimo si allinea alla durata del loop principale.
Ad esempio, se metti un task a 500 ms per un flash di un led e poi metti un delay(1000) nel loop, vedrai che il led lampeggia ogni secondo, non ogni mezzo secondo.
Logged


0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5957
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

yep, ottimo, come al solito

quindi looper puo' sostituire ad esempio il Blink without delay, che e' il classico esempio di millis
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22924
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sì. Non so se hai visto gli esempi allegati ma c'è proprio un blinkWithoutMillis (come c'era nel leOS).

Il classico BlinkWithoutDelay compila in 1028 byte, BlinkWithoutMillis in 1558 byte, quindi neanche un grosso carico di risorse in più per avere in cambio molta libertà in più.
Logged


Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Seguendo la scia di leOS, e su richiesta di m_ri ( smiley-razz ) ecco looper.
very perfect smiley
mi sa che prima o poi dovrò offrirti una birra x tutte le volte che ti rompo le scatole..


gli ho dato un'occhiata veloce,ma mi sembra tutto ok..
unico suggerimento:penso proprio che puoi evitare di usare "volatile",e così consenti ottimizzazioni al compilatore..
(e io stass non ho fatto niente in quanto ha smesso di piovere,e son uscito..)
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22924
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

unico suggerimento:penso proprio che puoi evitare di usare "volatile",e così consenti ottimizzazioni al compilatore..
Azz... vero  smiley-yell
Come detto, looper l'ho sviluppato partendo proprio dal leOS per cui ho preso il suo codice ed ho tolto la roba inutile. Mi pareva di aver fatto pulizia profonda ma invece qualcosa l'ho lasciata. Ottimo appunto  smiley-wink
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22924
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ecco, ho modificato lo zip allegato al 1° post. Si guadagnano una trentina di byte sulla compilazione di looper_BlinkWithoutMillis.
Logged


Offline Offline
Edison Member
*
Karma: 28
Posts: 2031
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ecco, ho modificato lo zip allegato al 1° post. Si guadagnano una trentina di byte sulla compilazione di looper_BlinkWithoutMillis.
ora lo provo un èò complimenti smiley-grin come mai non lo hai chiamato LEOoper invece di looper  smiley-twist
Logged

"Due cose sono infinite: l'universo e la stupidità umana, ma riguardo l'universo ho ancora dei dubbi..." Albert Einstein

Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

benissimo..
altra cosa,ma probab te ne sei già acorto: dopo 49 giorni inizia a eseguire il task a ogni ciclo del loop per un po' di tempo(in quanto plannedTask riperte da 0,e millis è moolto maggiore)
Logged

Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ecco, ho modificato lo zip allegato al 1° post. Si guadagnano una trentina di byte sulla compilazione di looper_BlinkWithoutMillis.
ora lo provo un èò complimenti smiley-grin come mai non lo hai chiamato LEOoper invece di looper  smiley-twist
ssshhh,che non ci aveva neanke pensato a sto nome.... smiley-lol
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22924
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ecco, ho modificato lo zip allegato al 1° post. Si guadagnano una trentina di byte sulla compilazione di looper_BlinkWithoutMillis.
ora lo provo un èò complimenti smiley-grin come mai non lo hai chiamato LEOoper invece di looper  smiley-twist
ROTFL  smiley-lol
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22924
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

benissimo..
altra cosa,ma probab te ne sei già acorto: dopo 49 giorni inizia a eseguire il task a ogni ciclo del loop per un po' di tempo(in quanto plannedTask riperte da 0,e millis è moolto maggiore)
Sì, lo so. L'alternativa più semplice è usare un contatore a 64 bit come ho fatto con leOS ma in questo caso si appesantisce moltissimo il codice finale (sono diverse centinaia di byte in più di Flash occupata). Oppure rivedere la logica dello scheduler per aggirare l'overflow.
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22924
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

In allegato trovate looper2, è una versione modificata di looper che dovrebbe sistemare il bug dell'overflow di milis mediante l'uso di un contatore di overflow a 8 bit, creando in pratica una variabile a 40 bit, che dovrebbe quindi soffrire del problema dell'overflow dopo 34 anni. Ho modificato anche lo scheduler affinché usi questa nuova gestione a 40 bit.

Siccome non ho potuto provare per 49,7 giorni BlinkWithoutMillis, rilascio il codice così com'è  smiley-sweat smiley-sweat

* looper2.zip (3.1 KB - downloaded 30 times.)
Logged


0
Offline Offline
Shannon Member
****
Karma: 132
Posts: 10494
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ahhaha grande leo, sempre sulla cresta dell'onda (lo so, ultimamente son lento ma troppo lavoro e niente ferie rendono lesto pazzo)
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Pages: [1] 2 3 ... 6   Go Up
Jump to: