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'.

image
image

fig. 1

Programme javascript pour calculer les résistances

// 7 résistances à disposition
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:

R01kΩ
R11kΩ
R21kΩ
R3330Ω
R41kΩ
R5330Ω
R610kΩ
image

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.

ToucheValeur
282
1153
3212
0393
8454
*558
7617
#656
9709
5776
4881
6922
Aucune touche1023

Programme C++ pour l'arduino

Cette exemple converti les valeurs analogiques en caractères avec une gestion des rebonds.

#define NB_KEYS 12 // nombre de touches
#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
  }
}