Connecter un clavier numérique COM-08653 Keypad sur une entrée analogique d'un Arduino
Ce projet propose de connecter un clavier (grille de contacts 3 x 4) en analogique grâce à des ponts de résistances. Le clavier utilisé est un Keypad COM-08653
Le premier problème à résoudre est de déterminer les valeurs des résistances des ponts suivant le schéma (fig.1).
Comme je n'avais pas envie de déterminer les meilleures valeurs possibles pour me rendre compte que je n'avais pas les bonnes résistances, j'ai choisi l'approche de faire au mieux avec ce que j'avais.
Et comme je n'aime pas trop calculer à la place de mon ordinateur, j'ai fait un petit programme en javascript qui calcul le meilleur emplacement des résistances que l'on a à disposition.
Il faut donc indiquer 7 résistances que l'on a dans le tableau 'resistances'.
fig. 1
Programme javascript pour calculer les résistances
var resistances = [330, 330, 1000, 1000, 1000, 1000, 10000];
// calcul les rapports des résistances pour chaque touche
function calcul(r) {
return [
r[0] / (r[0] + r[3]),
r[0] / (r[0] + r[3] + r[4]),
r[0] / (r[0] + r[3] + r[4] + r[5]),
r[0] / (r[0] + r[3] + r[4] + r[5] + r[6]),
(r[0] + r[1]) / (r[0] + r[1] + r[3]),
(r[0] + r[1]) / (r[0] + r[1] + r[3] + r[4]),
(r[0] + r[1]) / (r[0] + r[1] + r[3] + r[4] + r[5]),
(r[0] + r[1]) / (r[0] + r[1] + r[3] + r[4] + r[5] + r[6]),
(r[0] + r[1] + r[2]) / (r[0] + r[1] + r[2] + r[3]),
(r[0] + r[1] + r[2]) / (r[0] + r[1] + r[2] + r[3] + r[4]),
(r[0] + r[1] + r[2]) / (r[0] + r[1] + r[2] + r[3] + r[4] + r[5]),
(r[0] + r[1] + r[2]) / (r[0] + r[1] + r[2] + r[3] + r[4] + r[5] + r[6])
];
}
// calcul l'écart le plus petit entre deux valeurs
function min_diff(v) {
var diff = 10000000;
for(var i=0;i<v.length-1;i++) {
for(var j=i+1;j<v.length;j++) {
diff = Math.min(diff, Math.abs(v[i]-v[j]));
}
}
return diff;
}
function order(a, b) {
if(b.length>1) {
for(var i=0;i<b.length;i++) {
var f = b[i];
order( a.concat([f]), b.slice(0, i).concat(b.slice(i+1)) );
}
}
else {
var r = a.concat([b[0]]);
var v = calcul(r);
var m = min_diff(v);
if(m>max) {
max = m;
best_order = r;
best_values = v;
}
}
}
var dispo = [];
var max = 0;
var best_order = [];
var best_values = [];
order([], resistances);
alert(best_order);
Montage
Dans mon cas, le résultat est le suivant:
R0 | 1kΩ |
R1 | 1kΩ |
R2 | 1kΩ |
R3 | 330Ω |
R4 | 1kΩ |
R5 | 330Ω |
R6 | 10kΩ |
Sur le circuit, il y a deux trous supplémentaires qui ne sont pas connectés. Je les ai utilisé pour la masse et le Vcc. Le circuit étant photographié de derrière, la connexion (1) se trouve à gauche du fil noir (masse) et la connexion (7) à droite du fil rouge (Vcc).
J'ai utilisé des résistances qui ont des pattes assez fines pour pouvoir en enfiler deux dans un trou. Le fil vert représente notre signal analogique.
Calibrage
Connectez le clavier à l'arduino. Le fil noir sur GND, le fil rouge sur +5V et le fil vert sur l'entrée analogique A0. Programmez l'arduino avec le programme d'exemple Basics/AnalogReadSerial puis ouvrez le moniteur série.
Touche | Valeur |
---|---|
2 | 82 |
1 | 153 |
3 | 212 |
0 | 393 |
8 | 454 |
* | 558 |
7 | 617 |
# | 656 |
9 | 709 |
5 | 776 |
4 | 881 |
6 | 922 |
Aucune touche | 1023 |
Programme C++ pour l'arduino
Cette exemple converti les valeurs analogiques en caractères avec une gestion des rebonds.
#define TOL 10 // tolérance
#define KB_PIN A0 // Entrée analogique
void setup() {
Serial.begin(9600); // Initialise le port série
}
char read_key_once(void) {
static int levels[NB_KEYS] = {82,153,212,393,454,558,617,656,709,776,881,922};
static char chars[NB_KEYS] = {'2', '1', '3', '0', '8', '*', '7', '#', '9', '5', '4', '6'};
int v = analogRead(KB_PIN);
for(int i=0;i<NB_KEYS;i++) {
if(v<levels[i]-TOL) continue;
if(v>levels[i]+TOL) continue;
return chars[i];
}
return 0;
}
char read_key(void) {
char key, key2;
int i = 0;
key = read_key_once();
do {
delay(1);
key2 = read_key_once();
if(key==key2) {
i++;
}
else {
i=0;
key = key2;
}
} while(i<5);
return key;
}
void loop() {
char key = read_key();
if(key!=0) {
Serial.println(key);
while((key = read_key()) != 0); // wait for key release
}
}