x piccio e chi intervenne nel post "pulsanti: interrupt vs polling"
formatting link
per l'hw ho fatto come suggerito (uso 2 porte perchè mi servono 10 pulsanti)
per il firmware ti chiedo questo: se non mi serve che il micro vada in sleep(), posso usare la scansione dei pulsanti a 500hz con debouncing indipendente per ogni linea e basta? cioè fare solo polling? non ci vedo controindicazioni ma chiedere male non fa
mi serve rilevare anche le pressioni di pi=F9 tasti contemporanei... da qui la decisione di abbandonare l'int-on-change e passare alla soluzione proposta nel 3d indicato
Se si può risparmiare energia, anche un pirillesimo, non vedo perché non farlo.
Francamente non riesco ad immaginare cosa abbia realizzato, dato che mi pare proprio che anche Piccio gli suggerisse di usare il wakeup on pin change.
Temo che però Piccio lo abbia messo fuori strada, segnalando la necessità di mettere in alta impedenza tutte le linee di scansione tranne quella attiva, cosa che non mi pare una complicazione né dell'HW né del SW. Vabbé che, con 10 tasti, risparmia solo tre pin...
Il giorno Tue, 27 Oct 2009 17:42:24 +0100, "F. Bertolazzi" ha scritto:
Non ho seguito il thread su ihed, ma la gestione tastiera in genere richiede un tempo trascurabile anche se fatto in polling sincronizzato a un timer di sistema, per cui la scelta se usare int-on change o il polling dipende alla fine da uno stile di programmazione.
Io uso spesso il polling con il timer perchè se si devono gestire cose come l'autorepeat meglio avere sotto una base tempi fissa.
Però in un applicazione a batteria con 3 tasti ho usato l'interrupt per svegliare il micro dallo Sleep, ma lì i bassi consumi erano prioritari.
lo so benissimo :) per "non aver sfruttato int-on-change" intendo "non ho cablato i pulsanti sulle linee RB[7..4] del pic, che hanno questa feature"
l'int-on-change sulla RB0 io lo chiamo int_ext0, poi non so; ho usato questa linea per sapere (interrupt) quando uno o più pulsanti sono stati premuti;
inizialmente le 10 linee dei 10 rispettivi pulsanti sono in out e a 0V mentre rb0 è in input (ha il pull-up)
la pressione di 1+ pulsanti fa scattare int_ext0 perchè porta rb0 a 0V
quindi quando scatta l'int_ext0 (fronte negativo) entro nella isr, metto rb0 in output (low) e metto le 10 linee dei pulsanti in input; quindi leggo le porte che mi interessano e le salvo; le linee hanno i pull-up ovviamente
se ho ben capito a questo punto Piccio suggeriva di scansionare a 500hz e debouncing a 30ms
bene, grazie! ma come fai in modo compatto a tenere il debouncing indipendente per ogni linea? cioè nel mio caso sto usando 1 array a 10 posizioni in cui carico i 10 byte dei countdown per il debounce che poi decrementerò con un timer
In linea generale, ognuno di questi contatori viene caricato ad un valorer max di anti-debouncing ogniqualvolta il relativo tasto =E8 pigiato. Ad ogni interrupt si decrementano nel caso in cui il tasto non sia pressato, anche e soprattutto a causa dei rimbalzi. I contatori diversi (maggiori) da zero li considero tasti premuti; quelli giunti a zero, invece, come non premuti. In base ai valori, ricostruisco l'input bit per bit in modo speculare alle linee di I/O. Le successive subroutine hanno il compito di compattare i bit e ricavare un codice.
Tempo fa ho scritto un'efficace gestione dei tasti con la particolarit=E0 di riconoscere i fronti di salita, di discesa e di permanenza per tot millisecondi dei tasti. In base agli eventi, una tabella di definizioni ed indirizzi di salto seguente una call (pocciando con lo stack) mi permetteva una gestione degli eventi estremamente efficace e leggera.
dove evento poteva essere: pressione_tasto, rilascio_tasto, durata_pressione[millisecondi]
Su interrupt gestivo rapidamente l'input dei tasti, antirimbalzo, i contatori, la rilevazione dei fronti. Il corpo principale (fuori dall'interrupt), il "main" semplicemente vedeva mappato in memoria il risultato degli eventi senza mai dover accedere all'I/O. Questo mi permetteva di mappare i tasti nei modi pi=F9 bizzarri.
Ah, ok, infatti avevo premesso "sempre il tuo controller non sia così vetusto da non averne", o, aggiungo ora, da averli solo in certi pin, precludendoti, tra l'altro, di fare cose molto interessanti con, ad esempio, gli output delle seriali.
Il giorno Tue, 27 Oct 2009 21:44:11 GMT, ice ha scritto:
E' più semplice scansionare a 30Hz e fare lì il debounce, e in caso di più tasti premuti o si ha un errore da gestire o se sono combinazioni permesse si struttura la scansione in modo da considerare alla fine i tasti funzione ( es.Ctrl) in modo da poter gestire le combinazioni di tasti.
Io però ho sempre usato un solo contatore per il debouce e uno per l'autorepeat.
In genere uso interrupt a frequenza cos=EC *alta* perch=E9 ho altri servizi. Comunque non scendo mai sotto i 100 Hz, anche nel caso della gestione dei soli tasti.
torepeat.
Di solito lo faccio anch'io, ma mi trovo spesso a far fronte con codici derivati da pressione simultanea di pi=F9 tasti (settaggi customer, collaudi, combo nascoste). Per=F2, quando ho molti tasti, non utilizzo altrettanti contatori.
che vantaggio ti da il fatto di essere speculare? non basta usare una maschera generica costruita sulla disposizione dei bit della porta che mi interessano?
se 3 tasti vengono (per ipotesi) premuti esattamente assieme, come riempi il buffer? cioè la tua routine come fa a mettere nel buffer ABC e non ACB?
fuori dalla isr immagino
interessante; solo che devi cambiare il fronte di trigger dell'int_ext0... come fai poi con gli altri tasti che verranno premuti mentre un tasto è ancora tenuto pressato?
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.