Keypad à lecture analogique
Matrice Carrée
Le keypad
Le keypad classique est composé de 4, 12 ou 16 boutons:
Il est pré-câblé, par exemple:
Un keypad pré-câblé ne pourra jamais faire une lecture poly: si on appuie sur les boutons 1, 2 et 4, on ne pourra pas savoir si le bouton 5 est appuyé ou non, car cela ne rajoute pas de connexions. Dans la suite, je ne vais donc m'intéresser qu'à la lecture mono, bien qu'une lecture stéréo serait possible.
Montage
Voici un schéma pour un keypad 16 touches:
Et voici par où passe le courant si on appuie par exemple sur la touche 9:
En analysant ce schéma, on comprendra que l'on va diviser la tension VCC avec en haut une résistance P et en bas une résistance comprise entre 0 (si on presse la touche 1) et 15*R (si on presse le D).
Voici le schéma général pour C colones et pour L lignes:
On choisira de prendre pour le CNA le 1,1V comme tension de référence. On essaiera d'avoir proche de 1023 pour la touche corrspondante à la résistance maximale, de façon à avoir un écart le plus grand possible entre les différentes valeurs lues.
On lira sans aucune erreur la valeur 1023 (aucun bouton appuyé) car c'est le résultat d'une lecture de 5V avec une référence de 1,1V. Les autres lectures peuvent être entâchées d'une erreur. Si on veut pouvoir avoir une erreur possible la plus grande (sécurité maximale), on essaiera d'approcher le graphe suivant:
Pour une Arduino MAX vaut 1024, qui correspond à une tension de Vref de 1,1V. Mais on lira au maximum 1023.
Calcul de la résistance P
Voici en résumé comment cela se présente si on appuie sur la touche n:
Appelons:
- VCC la tension d'alimentation (5V pour une Uno)
- Vref la tension de référence (1,1V pour une Uno)
- MAX la valeur qui correspondrait à Vref (1024 pour une Uno)
- N le nombre de boutons
- ΣR la résistance R lorsque le dernier bouton est appuyé (c'est aussi la somme de toutes les résistances)
- ε l'écart possible (qui dépend de tous les paramètres précédents)
- Vin,n la tension d'entrée de l'Arduino si on appuie sur le bouton n
- CANn la valeur numérique lue si le bouton n est appuyé
L'idéal bien sûr est d'avoir des résistances R et des résistances C*R, mais en fonction des restes du tiroir, on peut être ammené à avoir des résistances légèrement différentes, par exemple si R=500Ω avoir les 4*R de 2,2kΩ.
Calculons Vin,N-1 par le pont diviseur:
ΣR (1) Vin,N-1 = ────── VCC P + ΣR
Puis avec le graphe:
MAX - 1 (2) ε = ──────── 2N - 1
Et d'autre part:
MAX - 1 - ε Vin,N-1 (3) ─────────── = ─────── MAX Vref
Extrayons P/ΣR: mettre l'ε de (2) dans l'expression (3), puis écrire l'égalité des Vin,N-1 entre les expressions (1) et (3). On obtient alors:
MAX (2N-1) VCC (4) P/ΣR = ──────────── . ──── - 1 2(MAX-1)(N-1) Vref
Changer la valeur de P (pour avoir une valeur normalisée) va changer CANN-1 et les écarts ε. Si on diminue un peu la valeur de P, cela va diminuer beaucoup l'erreur acceptable pour le dernier bouton εN:
Les autes valeurs des erreurs ε seront réparties régulièrement. Mais c'est la valeur minimale des différents ε qui est limitant. Il ne faut donc pas prendre P plus petite que la valeur idéale. Si on prend maintenant P un peu plus grand, cela va donner:
La dernière erreur maximale εN va augmenter, et cela va diminuer les autres erreurs mais 2N-2 fois moins. C'est donc plus acceptable.
Application: pour un keypad 16 touches avec des résistances R de 1kΩ:
ΣR = 15 . 1kΩ = 15kΩ 1024 (2.16-1) 5V P/ΣR = ───────────── . ──── - 1 = 3,7 2.1023.(16-1) 1,1V P = 3,7 . 15kΩ = 55,5kΩ
On prendra une résistance légèrement supérieure, par exemple une 56kΩ.
Erreurs sur les valeurs R /C.R
Pour des raisons d'arrondis, de fond de tiroirs... on peut être amené à choisir des couples R/C.R légèrement différents, par exemeple pour un clavier à 4 colonnes on pourait prendre 500Ω/2,2kΩ au lieu de 500Ω/2,0kΩ. Les écarts ε possibles seront alors inégaux, mais cela fonctionne quand même si on n'a pas trop de boutons. Notez que dans la séire E24 (24 valeurs par décade) On peut avoir des rapports entiers:
| rapport | Valeur des résistances |
| 2 | 2/1 22/11 24/12 30/15 36/12 150/75 |
| 3 | 3/1 33/11 36/12 39/13 |
| 4 | 12/3 300/75 |
| 5 | 75/15 10/2 110/22 120/24 15/3 180/36 |
| 6 | 12/2 18/3 |
| 7 | 91/13 |
| 8 | 120/15 16/2 24/3 |
| 9 | 8/2 27/3 |
Pour 16 touches, il faut des couples R/4R, on peut prendre (1,2kΩ/300Ω) (12kΩ/3kΩ) (3kΩ/75Ω) (30kΩ/750Ω)...
On peut aussi n'utiliser que des résistances identiques pour R et 4R. On peut par exemple utiliser deux résistances de 1kΩ en parralèle pour avoir R=500Ω et en série pour 4R=2kΩ. Cela peut faire par exemple:
Linéarisation
Malheureusement si n varie de 0 à N la tension en entrée de l'Arduino ne va pas varier linéairement! On obtient pour 16 touches:
La courbe rouge est la courbe idéale (linéaire) et la courbe bleue est celle que l'on a réellement. Pour un pavé de 9 touches l'erreur entre les deux courbes atteint quasimet l'erreur ε autorisé, et pour peut que l'on ait une dispertion sur la valeur des résistances, la lecture serait fausse. Sans correction, on peut espérer pouvoir utiliser un maximum de 6 touches (erreur de lecture possible partagée pour moitié par les erreurs sur les valeurs et par moitié par la non linéarité).
Il peut être nécessaire de corriger la valeur lue pour la linéariser. Je conçois quatre possibilités:
- on ne corriger rien si on a moins de 6 boutons
- on corrige la courbe avec l'expression mathématique exacte. On obtient alors une courbe linéaire, mais cela fait intervenir une division
de réels qui est un peu longue. Mais cela va permettre de mettre un maximum de boutons... si les réssitances sont parfaites!
- on mesure les valeurs pour les N boutons et on fait une table. Cela veut dire que si une résistance n'avait pas la bonne valeur, ce
serait pris en compte. C'est la méthode qui va maximaliser le nombre de boutons. Mais si on a peu de boutons, une correction suffit et si
on a beaucoup de boutons il faut une grande table et une lecture de la table est plus complexe.
Il n'y a pas de solution universelle, par la suite je vais m'intéresser à la correction exacte. La solution avec table sera étudiée dans une autre page car elle n'est pas spécifique à la lecture d'un keypad, mais fonctionne avec quasi tous les ensembles de boutons lus en analogique.
Extraction du numéro du bouton
Appelons:
- VCC la tension d'alimentation (5V pour une Uno)
- Vref la tension de référence (1,1V pour une Uno)
- MAX la valeur qui correspondrait à Vref (1024 pour une Uno)
- N le nombre de boutons
- CANn la valeur numérique réelle pour le bouton n
- P la résistance fixe entre l'entréz et VCC
- R les réssitances que l'on insère pour chaque bouton
- ΣR la somme de toutes les résistances R. Cela vaut (N-1)R si toutes les résistances sont identiques.
Mon choix est de calculer d'abord la valeur du convertisseur pour le dernier bouton CANN-1 et d'utiliser ce résultat pour trouver la valeur n. Ce serait bien de remplacer la valeur théorique CANN-1 par la valeur réellement lue. Cela permet de s'affranchir par exemple de l'erreur sur un VCC.
On a pour la lecture réelle un pont diviseur:
n.R.VCC (5) CANn = ───────────── (P + n.R).Vref (N-1).R.MAX.VCC ΣR.MAX.VCC (6) CANN-1 = ────────────────── = ──────────── (P + [N-1].R).Vref (P + ΣR).Vref
Elliminons tout d'abbord Vref et VCC entre ces deux équations:
VCC (P + ΣR).CANN-1 (7) (6) ⟹ ───── = ─────────────── Vref ΣR.MAX
Et remplaçons le dans (5):
n.R.VCC n.R.(P + ΣR).CANN-1 (8) CANn = ───────────── = ───────────────── (P + n.R).Vref (P + n.R).ΣR.MAX
C'est n que l'on cherche, multiplions par le dénominateur des deux côtés, regroupons ce qui contient n à droite puis exprimos n:
(9) CANn.(P + n.R).ΣR.MAX = n.R.(P + ΣR).CANN-1 CANn.P.ΣR.MAX = n.R.(P + ΣR).CANN-1 - CANn.n.R.ΣR.MAX = n . [R.(P + ΣR).CANN-1 - CANn.R.ΣR.MAX] CANn.P.ΣR.MAX (10) n = ───────────────────────────────── R.(P + ΣR).CANN-1 - CANn.R.ΣR.MAX P/R.CANn (11) n = ──────────────────────── (P/ΣR + 1).CANN-1 - CANn
Application: pour un keypad 16 touches avec des résistances R de 1kΩ et P de 56kΩ:
ΣR.MAX.VCC 15kΩ.1024.5V CANN-1 = ──────────── = ─────────────── = 983,4 (P + ΣR).Vref (56kΩ+15kΩ).1,1V
On peut garder cette valeur, mais si on mesure 981, on prendra la dernière valeur.
P/R.CANn 56 CANn n = ──────────────────────── = ──────────────────────── (P/ΣR + 1).CANN-1 - CANn (56kΩ/15Ω + 1).981 - CANn 56 CANn n = ─────────── 4643 - CANn
Bilan
- lecture simple, mais avec correction
- permet d'utiliser les claviers matriciels pré-câblés usuels
- un seule broche pour un keypad
- résistances proches compensant en partie les erreurs
- utilisation d'interruption possible
MAIS
- lecture mono
- des résistances en plus
- je ne connais pas de bibliothèques pour ce montage
Très très intéressant, mais peu utilisé.