Ottimizzazione
delle tastiere analogiche
Nel dominio dei microcontrollori,
la necessità di interfacciare una tastiera a matrice porta normalmente
all’adozione di una circuiteria che dedica un piedino digitale della MCU ad
ogni Linea e Colonna del dispositivo, come nell’esempio seguente.
A volte, però, capita di non
disporre di tutti i pin digitali necessari per gestire la tastiera. Vengono in
aiuto, in questi casi, delle soluzioni alternative. L’uso di ingressi analogici
del microcontrollore permette infatti di spostare il problema della
discriminazione del tasto premuto ad una analisi del livello di tensione
prodotto da un partitore resistivo attivato dalla pressione del tasto stesso.
Si trovano sul web numerosi esempi di Keypad analogiche aventi fino a 20 tasti.
Le soluzioni sono molteplici, ma tutte basate sullo stesso principio. Esistono
in particolare soluzioni ibride, dove viene utilizzato un ingresso analogico del
micro per ogni linea della tastiera di input, come nell’esempio seguente
riferito ad una singola linea di tasti.
Si arriva finalmente alla più efficiente configurazione che
offre su una singola linea di uscita il potenziale elettrico stabilito dalla
chiusura di un partitore differente a seconda del tasto che viene premuto, come
nel seguente esempio (fonte http://www.technoblogy.com/show?28WK).
Due parametri vanno considerati,
nell’analisi del circuito: La minima distanza digitale nelle letture a fronte
della pressione dei pulsanti, e l’impedenza offerta al piedino di lettura
analogica del microcontrollore.
Nel caso 4R x 5C di cui sopra, la minima distanza è di 24 unità digitali su 1024, ponendoci nel caso di un ADC a 10 bit. Tale distanza la osserviamo nella pressione dei pulsanti S3 rispetto a S4, oppure S11 rispetto a S16. La tabella riportata di seguito mostra i valori digitali per ogni pulsante, e la differenza rispetto al valore più vicino ottenuto premendo un diverso pulsante.
Per quanto riguarda l’impedenza,
prendendo in considerazione il parallelo tra i due rami resistivi volti alla
alimentazione ed a massa, si va da un minimo di zero per S20 fino ad un
massimo, premendo S1, di 1/(1/27 + 1/(4.7+4.7+8.2+10+33+3.3+2.7))=19K circa.
Questo
pone qualche problema se il livello di tensione definito dal partitore attivato
viene letto da un microcontrollore come p.es. il PIC18F2620 il cui datasheet
raccomanda “The maximum recommended
impedance for analog sources is 2.5 k”. Prendiamo in considerazione proprio questo
dispositivo, studiando il modello dei pin analogici descritto nella
documentazione tecnica citata.
Dato il valore Rs della
impedenza della rete resistiva sorgente, possiamo avvalerci delle formule
riportate nel datasheet, per calcolare il tempo minimo di acquisizione
necessario:
TACQ = TAMP + TC + TCOFF …dove
TAMP è fisso a 0.2 us, e TCOFF vale zero per temperatura <25 gradi
Utilizzando la Adc_Read
di MikroC per la lettura del livello di tensione, il tempo dedicato alla
acquisizione è di 12 TAD, che calcolato per un clock di 4 MHz fornisce:
Per
avere contezza della deviazione rispetto al valore definito dal partitore, ho
eseguito delle misure dirette, mostrando su un Display da 4 cifre a 7 segmenti
il valore recuperato da Adc_Read, senza cambiare le impostazioni standard del
registro ADCON2. L’accuratezza
rilevata è di +/-1 unità digitale fino a 100 Kohm di impedenza, che devia
rapidamente andando oltre tale valore. Considerando reti resistive che non
superino i 20 Kohm di impedenza massima ci assicuriamo buone prestazioni nella
fase di lettura, evitando imprecisioni da parte dell’unità ADC.
Per rispondere, partiamo da uno
schema modificato rispetto al precedente, ma equivalente. Mi viene più facile,
in questa disposizione, impostare i termini del problema. Peraltro, la tastiera
in esame fa parte di una applicazione più estesa, che prevede la realizzazione
di una calcolatrice scientifica single-chip, che proporrò in seguito.
Ho tentato diversi approcci per
giungere ad una soluzione. Dopo aver tentato dapprima analiticamente senza
grande successo, visto che il numero di incognite superava quello delle
equazioni, ho adottato infine una ricerca mista, che parte dal calcolo delle
resistenze a fronte di tensioni generate casualmente per la prima linea e prima
colonna di pulsanti, per calcolare infine le tensioni nella parte centrale
della matrice. Durante la ricerca, il programma che ho scritto mette via via da
parte la “Miglior rete” e prosegue ad oltranza, fino ad interruzione utente o
al raggiungimento di un obiettivo. Le formule usate sono le seguenti:
Relazione tra Vij e le resistenze
di linea RLi e di colonna RCj:
[1] Vij
= 1-RL1/(Σ(RL,1,i)+ Σ(RC,1,j))
Imponendo un valore per RL1 ed
alle tensioni di partitore ottenute dai pulsanti disposti sulla prima linea e
prima colonna, si possono ricavare in sequenza i valori delle resistenze RL ed
RC:
RC1=RL1*(1/(1-V11)-1)-S : S = S+RC1
RC2=RL1*(1/(1-V12)-1)-S : S = S+RC2
RC3=RL1*(1/(1-V13)-1)-S : S = S+RC3
RC4=RL1*(1/(1-V14)-1)-S : S = S+RC4
RC5=RL1*(1/(1-V15)-1)-S : S = S+RC5
RL2=RL1*(1/(1-V21)-(RC1/RL1)-1)-S : S = S+RL2
RL3=RL1*(1/(1-V31)-(RC1/RL1)-1)-S : S = S+RL3
RL4=RL1*(1/(1-V41)-(RC1/RL1)-1)-S : S = S+RL4
Poi con la [1] si ricavano le
altre tensioni e si calcola infine MinDiff come valore più piccolo tra le
differenze ottenute da ogni coppia di tensioni Vij-Vi’j’.
Il ciclo parte dalla generazione
casuale delle tensioni Vij entro i limiti previsti, e di RL1. Dopo la
generazione conseguente delle RL e RC, si scartano tutti i casi dove la Rs
ottenuta è superiore ad un limite impostato, e di mette da parte la Miglior
Rete ottenuta, ovvero quella che fornisce la maggior MinDiff.
Il programma
“Matrix.exe” resta in esecuzione per diversi giorni. Questa è la sua scarna ma
funzionale interfaccia grafica. L’utente lo può interrompere in qualunque
momento, accontentandosi del risultato migliore ottenuto dall’avvio fino
all’arresto:
Il programma prevede, in
alternativa all’avanzamento per generazione casuale di Tensioni, di scegliere
altri due metodi: generazione casuale dei valori delle resistenze, e
generazione incrementale, fattibile solo per piccole tastiere, pena
l’esecuzione per mesi o anni su un computer normale.
Ho eseguito varie sessioni fino a matrici di 10x10 pulsanti. I risultati
ottenuti per la 4R x 5C mostrata sopra sono analoghi a quelli ottenuti dagli
autori del sito di origine. In linea generale, il programma Matrix eseguito per
almeno due giorni con diverse dimensioni della matrice di tasti indica un
andamento del tipo seguente:
Considerando i possibili errori
di lettura, mitigabili eseguendo letture di conferma, le dimensioni della
matrice di tasti non dovrebbero superare i 64 contatti. Quindi 8 righe per 8
colonne. Al superamento di 72 tasti si rischia di scendere sotto 4 unità
digitali, sempre con un ADC a 10 bit, aumentando il rischio di errore di
interpretazione da parte del microcontrollore.
Il programma Matrix genera anche
un disegno Bitmap dello schema, ed un file di testo con codice C utilizzabile
per la stesura del programma da sviluppare per la nostra applicazione. Di
seguito un esempio per una tastiera da 42 tasti disposti in 6 righe per 7
colonne.
Il codice indica, a titolo di
esempio, una singola operazione di lettura tramite la funzione ADC_Read, ma
sarebbe preferibile implementare delle ulteriori letture di controllo, prima di
convalidare il valore acquisito.
Per i valori delle resistenze è
stata scelta la serie E24, ma è possibile eseguire il programma indicando la
serie E12. In questo caso però la MinDiff raggiunta è inferiore a 10.
Una ulteriore considerazione
riguarda la precisione ed accuratezza dei valori delle resistenze commerciali.
Scegliamo una serie, per esempio la E24. La sua “precisione” teorica è del 5%.
Questo significa unicamente che se si desidera un valore X qualsiasi, esso
discosterà dal valore più prossimo di quella serie non oltre il 5%. La “accuratezza”
invece, ovvero lo scarto tra il valore di targa e quello misurato, è in
generale migliore. Sempre per le E24, il costruttore si mantiene di solito al
di sotto del 1%. Per limitare imprecisioni nella lettura dovute a valori non
accurati delle resistenze impiegate, si consiglia tuttavia di misurarle con uno
strumento di qualità in un pool di campioni, e scegliere quella più vicina al
valore riportato nello schema.
Un secondo file di testo generato dal programma Matrix riporta anche i livelli di tensione teorici letti a fronte della pressione di ogni pulsante della matrice. Questi valori, una volta realizzata la tastiera, potrebbero venir confrontati con le letture reali, per eseguire micro-aggiustamenti negli estremi di discriminazione del codice suggerito.
Invito
i lettori interessati ad utilizzare il programma, scaricabile QUI e
lasciarlo eseguire per un tempo lungo, al fine di massimizzare la
MinDiff. Qualora si riscontrassero anomalie, siete pregati di
documentarle e comunicarmele per consentirmi la correzione. Riceverete
direttamente la versione aggiornata.