Come suggerito, vado ad aprire un nuovo topic per questa piccola libreria che ho messo online giusto oggi.
Si tratta di una "raccolta" di funzionalità che possono tornare utili quando si ha a che fare con dei segnali digitali sia in ingresso che come uscita.
L'idea alla base è stata ispirata dalle classi DigitalIn e DigitalOut presenti nel framework Mbed, ma ovviamente in chiave Arduino
Per quanto riguarda gli ingressi digitali (tutti con filtro anti-rimbalzo software, eventualmente disattivabile) è possibile dopo aver definito in quale logica lavorano (pull-up, pull-down):
intercettare l'evento di singolo click;
intercettare l'evento di doppio o più click (è quello che crea più rogne, ma anche il meno utile secondo me, mica è un mouse );
intercettare l'evento di pulsante premuto a lungo con distinzione tra il momento in cui diventa vera la condizione oppure in concomitanza del "release" ;
associare una funzione di callback sul fronte di salita (logico, non elettrico);
associare una funzione di callback sul fronte di discesa (logico, non elettrico);
usare delle "short hands" per la lettura del valore (sempre logico);
esempio if (input) { fai_qualcosa; }
Lato uscite digitali invece è possibile definire il tipo di comportamento dell'uscita e su quale livello del segnale va considerata attiva. Le modalità implementate fino ad ora sono le seguenti:
Set/Reset, anche qui con "short hands":
esempio: if (input) { output = true; }
temporizzatore con ritardo alla diseccitazione;
temporizzatore con ritardo all'eccitazione;
temporizzatore con ritardo all'eccitazione con memoria;
blink con doppia modalità di funzionamento, X lampeggi o fintanto che rimane il trigger è attivo.
@Maurotec ti rispondo qui visto che ho creato il topic specifico come suggerito da Guglielmo.
Intanto grazie per aver provato la libreria e per i suggerimenti!
Per quanto riguarda update() chiamato direttamente in click() ci avevo pensato (cosi da poter rendere anche il metodo privato).
Il problema è che per analogia dovrei fare la stessa cosa con il doppio click e quello prolungato e questo incasina il funzionamento quando voglio distinguere contemporaneamente i diversi eventi sullo stesso pulsante.
In realtà è tutto il circo messo in piedi per il doppio click che crea problemi e ammetto che sono tentato di rimuovere del tutto la funzionalità e riscrivere il metodo update() in modo più semplice e lineare, magari con una macchina a stati finiti più chiara.
Per quanto riguarda il nome del metodo isActive() l'idea era quella di rendere la cosa più generica e non limitarsi solo all'idea del push button, ma in effetti pensandoci su in quali casi reali dovrei aver bisogno di un debounce software o ditinguere il tipo di evento? Mi sa che "accolgo" il suggerimento e rendo il nome più esplicito.
C'è da ragionarci su ancora un po. Se la mia istanza la chiamo relay, relay.isPressed() non ha proprio senso. Stessa cosa se il nome della istanza fa riferimento ad un segnale. Non è facile.
Per adesso potresti documentare meglio questo metodo, spiegando cosa restituisce.
Se trovi di meglio ben venga, ma come detto la vedo difficile. Dovrebbe essere qualcosa che va bene sia con signalA, relayA, greenButton ecc. Per assurdo in così breve tempo non mi viene nulla di più sensato di isActive().
Per quanto riguarda il discorso del doppio click mi piacerebbe avere una tua opinione, pensi possa essere utile?
Alla fine non mi interessa avere una classe che faccia tutto il possibile (ci sono già ottime librerie per i push button), ma solo le cose realmente utili e che lo faccia in modo efficiente.
Lascia decantare. Il doppio click come pure long pressed long long pressed assieme al click fanno 4 funzioni con un solo tasto e se c'è veramente un solo pulsante più che utile diventa necessaria. Il problema sembra essere di altra natura; fa troppe cose. DigitalIn::click() ?? un click su un segnale digitale. Ok ho dato uno sguardo a mbed ed in effetti ho trovato ciò che mi aspettavo, cioè una gerarchia di classi.
Dalla classe DigitalIn mi aspetto dei metodi che abbiano a che fare con i segnali digitali e non di certo il metodo click(). click & company hanno senso con un pulsante.
Servirebbe quindi che la classe DigitalIn implementi i metodi read write ecc quelli strettamente legati ai segnali digitali. Poi la classe Button eredita DigitalIn magari privatamente e implementa click & company.
Ho solo dato uno sguardo veloce a mbed e non so suggerirti altro al momento. Ok si vedi qui c'è da prendere spunto ma non è così facile per me adesso (forse sono poco motivato). Interessante l'uso dei template a tutto spiano.
Ops, dimenticato auto trigger che è simile al grilletto di una mitragliatrice, e spara colpo dopo colpo con la differenza che la frequenza dei colpi è bassa all'inizio man man che il pulsante resta premuto e passa il tempo la frequenza dei colpi si incrementa. Si usa quando devi modificare dei parametri nel range 0.0 100.0 ad incrementi di 0.1 ci si impiega una eternità
senza auto trigger. Lo trovi impiegato su questa tipologia di controller teletermostati
@Maurotec grazie per il link. Non conoscevo questo libro e lo sto trovando davvero molto molto interessante, soprattutto per via dell'attenzione che dedica ad discorso dell'efficienza e dell'ottimizzazione del codice.
Ad esempio non immaginavo che i template potessero aiutare a creare codice più efficiente se usati con cognizione, anzi avrei proprio scommesso il contrario. Proverò ad implementare questi accorgimenti nella libreria... vedremo cosa ne salta fuori
Bella questa funzionalità! La conosco, ma non ci avevo proprio pensato ad implementarla...
Su wokwi c'è questo esempio che mostra la differenza tra pulsante con e senza rimbalzo.
Cercando con il libmanager "button" escono un numero molto ampio di librerie, in testa c'è AceButton che ricordo, ma le altre (e sono davvero tante) sono sconosciute. Vorrei visionare il codice di tutte, ma ci vorrà molto tempo e pazienza.