Il tempo delle librerie

Sarebbe meglio dire la libreria del tempo..
siccome mi sono anche scocciato di gestire sempre la millis per i miei temporizzatori e ancora di più mi sono scocciato di vedere inesperti e similia che si incatastano a fare delay e domandarsi come mai poi i pulsanti non rispondono mi sono fatto una librerietta di temporizzatori
e non ditemi che esiste la timealarm, lo so, ma è anche troppo per due blink without delay....
cosa ho fatto? una libreria che gestisce 5 temporizzatori, basta fare il test temporizzatore(numero), oppure caricarlo con temporizzatore(numero, tempo)
è più difficile a dirsi che a farsi
metto qui la libreria, occhio che io non so programmare c++, è tutto santo C (beh, non proprio, ma quasi)

#ifdef TEMPORIZZATORI
#else
#define TEMPORIZZATORI 5
#endif

bool temporizzatore(char item, unsigned long tempo = 0);
bool temporizzatore(char item, unsigned long tempo)
{
    static unsigned long int tempi[TEMPORIZZATORI];
    static unsigned long int avvii[TEMPORIZZATORI];
    byte indice = (item - 'A') % TEMPORIZZATORI;

    if (tempo)
    {
        // il tempo è presente
        // carichiamo l'elemento dell'array
        avvii[indice] = millis();
        tempi[indice] = tempo-1;
        return 0;
    }
    else
    {

            // tempo è nullo, si tratta di interrogazione
            if (millis() - avvii[indice] > tempi[indice])
            {
                // tempo superato
                // azzero il tempo
                avvii[indice] = 0;
                tempi[indice] = 0;
                return 1;
            }
            else
            {
                return 0;
            }
 
    }
}

la copiate in un file puntoacca e lo mettete nel percorso di ricerca delle librerie, sotto ve lo allego
invece l'esempio d'uso: banale

// di Nelson "StandardOil"
// Idea da sviluppare: libreria di timer

//#define TEMPORIZZATORI 5
// cambiare la define PRIMA di chiamare la libreria cambia il numero dei temporizzatori indipedenti gestibili
// di default sono 5
// occupazione di memoria: due unsigned long int per ogni temporizzatore inizializzato (come farlo diretto in codice)
#include "temporizzatori.h"


void setup(void)
{
    Serial.begin(9600);
    Serial.println("Prova temporizzatori multipli");
}

void loop(void)
{
    if (temporizzatore('A'))
    // chiamare il temporizzatore a vuoto esegue il test
    // temporizzatori non inizializzati si considerano sempre scattati
    {
       
        Serial.println("temporizzatore A a 5 secondi");
        temporizzatore('A', 5000);
        // ricordarsi di reinizializzare il temporizzatore
        // che per progetto e' ONE SHOT e si resetta
    }

    if (temporizzatore('B'))
    {
        Serial.println("temporizzatore B a 3 secondi");
        temporizzatore('B', 3000);
    }
    if (temporizzatore('C'))
    {
        Serial.println("temporizzatore C a 2 secondi");
        temporizzatore('C', 2000);
    }
    if (temporizzatore('D'))
    {
        Serial.println("temporizzatore D a 1,5 secondi");
        temporizzatore('D', 1500);
    }
    
    if (temporizzatore('E'))
    {
        Serial.println("temporizzatore E a 8 secondi");
        temporizzatore('E', 8000);
    }
}

è banale, come vedete
basta chiamare a vuoto il temporizzatore con solo argomento il suo nome, che vi restituisce 1 se non inizializzato o tempo scaduto
e per inizializzarlo basta chiamare il temporizzatore con due argomenti, il nome del temporizzatore e il tempo da aspettare e restituisce zero
questione NOME del temporizzatore:
io lo so che alcuni inesperti qui si incasinerebbero se la funzione accettasse due numeri sarebbero capaci di ssconfonderli
quindi i temporizzatori si riconoscono dal NOME, un singolo carattere
e siccome io lo so che alcuni sarebbero capaci di usare caratteri a muzzo ho messo un modulo (resto della divisione)
se ve ne servono di più o di meno cambiate la define
per ogni domanda io qui sono
Sono graditi gli applausi[/center]

No, scherzo, aiutatemi a trovarci i bacherozzi (bug in italiano)

oh, ma non si riesce proprio a fare rosso e centrato?, ci riuscii, evviva sempre Patrick_M

temporizzatori.ino (1.38 KB)

temporizzatori.h (921 Bytes)

come così?

bravo, se mi spieghi come hai fatto avrai la mia eterna gratitudine, almeno fino a domani mattina....

bah io ho messo [ centra ] [ rosso ] frase [ / rosso ] [ / centra] ovviamente i tag non sono questi...

essendo gia passata la mezzanotte ho guadagnato un giorno :wink: :smiley:

bravo un giorno
gratis[/center]
(non è vero: te lo sei veramente guadagnato)

la questione è che devono essere sulla stssa riga, ora capii, e non bisogna mettere la chiusra del colore, che è automatica

no, funzionano anche su righe diverse, penso al contrario che sia una questione di precedenze

se provi a quotare questo post sul mio la chiusura del colore c'è

Standardoil:
bravo un giorno
gratis

(non è vero: te lo sei veramente guadagnato)

la questione è che devono essere sulla stssa riga, ora capii, e non bisogna mettere la chiusra del colore, che è automatica
[/color]

Patrick_M:
come
così?

Oppure c'è Looper --> looper - un semplice schedulatore senza timer/interrupt - Megatopic - Arduino Forum

PaoloP:
Oppure c'è Looper --> looper - un semplice schedulatore senza timer/interrupt - Megatopic - Arduino Forum

Che si trova, aggiornato alla 1.0, sul sito di Leo, QUI :smiley:

Guglielmo

Sì, beh, diciamo che il mio obbiettivo era molto più limitato, non pensavo di comparararmi con quei livelli

Interessante (dalla lista dei topic ho letto il titolo ed ho capito subito che era tuo senza neanche vedere l'autore... ;)), per ora ho visto velocemente il codice ma gli darò un'occhiata stasera o domani, spero.

Per ora solo una cosa, la prima che ho notato. Invece di:

#ifdef TEMPORIZZATORI
#else
#define TEMPORIZZATORI 5
#endif

metti:

#ifndef TEMPORIZZATORI
#define TEMPORIZZATORI 5
#endif

che significa "se non è definita TEMPORIZZATORI la definisci".

Inoltre, a che serve mettere quel check solo per il simbolo? In genere nelle "librerie" si fa l'#ifndef per capire se è stato già definito tutto quello che serve, ma in caso negativo (ossia se NON è definita la tua variabile della libreria) dentro alla #ifndef (quindi fino a #endif) ci metti TUTTO, perché se la variabile è già definita significa che la libreria è già stata inclusa nel progetto, ed eviti doppie definizioni. Quindi secondo me devi mettere l'#ifndef all'inizio e l'#endif alla fine di tutto.

Anche io a suo tempo feci qualcosa del genere, ma come libreria "vera" in C++ proverò a darti qualche consiglio, e magari se trovo il tempo provo a trasformartela in libreria C++ così entri anche tu in questo baratr... mondo. :slight_smile:

Non ho usato la ifndef perché non la conoscevo, la mia dispensa del precompilatore è vecchia.
Quel pezzo serve per poter predefinire il numero prima di richiamare la libreria, aggirando così il default
Lo ho scritto, da qualche parte, nel primo post

Si, lo so, scusami, o in questi casi ragiono sempre per oggetti, quello che ti dicevo è l'uso generale dell'#ifndef nelle librerie C++... :wink: Nel tuo caso si, a parte il#ifndef fa quello che dici, ma simulare una libreria con un file *.h (che formalmente dovrebbe contenere solo prototipi e definizioni), funziona ma non è proprio canonico diciamo... :smiley:

Tra l'altro chiariscimi anche perché metti il prototipo prima della funzione stessa:

bool temporizzatore(char item, unsigned long tempo = 0);
bool temporizzatore(char item, unsigned long tempo)
{
   ...

In pratica non serve a nulla... :wink:

Perché se non mettevo il prototipo non mi compilava, ho dato la colpa all'argomento di default, ma non sono sicuro.

Qui forse è bene che io trovi un anima pia che mi guida, più o meno questo è il limite delle mie conoscenze...

Standardoil:
Perché se non mettevo il prototipo non mi compilava, ho dato la colpa all'argomento di default, ma non sono sicuro.

Se non ricordo male, se definisci un valore di default allora devi usare il prototipo prima di invocare la funzione (ossia prototipo all'inizio del codice, e la funzione può poi stare ovunque). Se non usi default o se definisci la funzione sopra al resto (ovvero prima di utilizzarla) credo che non sia necessario il prototipo.
Ad esempio questo a te compila e gira?

void test(int a = 10) {
  Serial.print("test(");
  Serial.print(a);
  Serial.println(")");
}

void setup() {
  Serial.begin(9600);
  test();
  test(20);
}

void loop(){
}

PS: io difficilmente uso i valori di default, se non in C++ sotto forma di overload..

Non so, ci guardo stasera, adesso non posso.
L'uso di un argomento di default chiaramente è per differenziare il settaggio da l'interrogazione del timer

Standardoil:
L'uso di un argomento di default chiaramente è per differenziare il settaggio da l'interrogazione del timer

Due funzionalità per la stessa funzione?
Brrr.... Orrore...

È come altro potrei fare, in C, a conservare l'informazione senza usare variabili globali?
Non ci vedo nulla di male comunque, non sono funzionalità slegate, cose così ogni tanto si vedono, brutte forse, ma non sbagliate in assoluto

Provato
Compila regolarmente e va
quindi qui occorre un minimo di "storia":
io sono autodidatta e principiante, come tale dovrei essere meno cattivo, lo so, ho gia' fatto ammenda di questo
non so (e qui nera vergogna) esattamente che collegamento ci sia tra file puntoacca e file puntocipipi
essì, lo ammetto, non lo so
per scrivere le mie librerie (che poi mi servono per condensare funzioni e idiosincrasie mie, cosa che è esattamente lo spirito delle librerie aggiuntive)
dicevo per scrivermele mi limito a "isolare" le parti di codice che voglio "inlibrare" (bel neologismo, vero?)
in una tab separata del progetto
quando ho isolato il tutto e il progetto compila e va, sposto il file corrispondente al tab, lo metto nella mia cartella Nelson, lo cito come include e buonanotte al secchio
forse manca un po' di finezza, ma non ho altra maniera
in particolare scrivere e debuggare mi risulterebbe piuttosto difficile dato che non ho un IDE differente rispetto a quello di Arduino, e se il file si chiama puntoacca mi si apre l'editor di testo....

quindi ben venga una indicazione su metodi migliori