Ardu? No!Les boutons ≫ Lecture analogique de boutons par calcul

Lecture analogique de boutons par calcul

Dans un ensemble de boutons utilisant la lecture analogique, on obtient une valeur par bouton (ou combinaison). Pour décoder l'information, il y a en gros deux méthodes:
- on identifie la lecture en parcourant une table des limites. Ceci est décrit dans la page Lecture analogique avec une table
- on utilise le fait que la répartition des valeurs est mathématique. C'est cette méthode qui est évoquée dans cette page. Bien entendu comme cela dépend du montage, les pages de chaque possibilité donne éventuellement le moyen d'extraire l'information.

Répartition linéaire des lectures

On va supposer ici que l'on a qu'une broche repérée BOUTONS qui doit lire l'état de plusieurs boutons. Dans le cas ou il y aurait plusieurs broches dédiés à la lecture de boutons, il faudra répéter plusieurs fois l'algorithme.

La lecture des boutons se fera grâce à l'instruction valeurLue=digitalRead(BOUTONS); et par analyse de la variable valeurLue, on en déduira l'état des boutons.

Si on veut avoir le maximum de chances de ne pas se tromper (indiquer un bouton pour un autre), il faudrait que la répartition des valeurs possibles soit régulière. Une valeur possible est ce que l'on obtient sur un bouton ou sur plusieurs si on fait une lecture poly:

Graphe des lectures pour N possibilités régulièrement répartis

Pour connaître le numéro d'une possibilité, la valeur théorique est n.1024/N mais toute valeur s'en écartant de moins de ½.1024/2N sera aussi bonne. Si la courbe réelle s'en écarte un peu (à cause du procédé, des tolérances des composants...), la lecture sera encore valide.

En principe "Aucun bouton appuyé" se traduit par une valeur nulle ou de 1023.

Le programme de test est simple, mais l'utilisation d'analogRead() n'est pas très performante:

// Lecture analogique mono de boutons
const word MAX_CONVERSION = 1024; // Valeur max+1 du CNA, 1024 avec un AVR
const word N = 6; // Nombre de possibilités 
const byte BOUTONS = A0; // Broche pour des boutons


void setup()
{
}

void loop()
{
  word valeurLue = analogRead(BOUTONS); // Lecture
  valeurLue = (valeurLue + MAX_CONVERSION / (2 * N - 2)) / (MAX_CONVERSION / (N - 1));  // N° du bouton 0..N
  // valeurLue contient le nombre 0..N recherché
  // Ici, traitement de l'information
}

Répartition non linéaire des lectures

En général, les répartitions ne sont pas linéaires. On peut avoir par exemple:

Graphe des lectures pour N possibilités irrégulièrement répartis

Pour extraire le numéro du bouton, nous avons trois solutions:
- faire comme si c'était linéaire, ce qui fonctionne si on a peu de boutons car on peut se permettre quelques erreurs.
- calculer une correction, ce qui permet d'avoir une courbe corrigée linéaire.
- mettre les différentes limites dans une table. Cela permet d'élliminer les incertitudes notament sur les résistances, mais la table peut prendre de la place, et la recherche dans la table peut être plus longue. Mais cette méthode fonctionne quel que soit le montage.

La page Lecture avec une table indique comment avoir un programme qui utilise une table. Les pages qui suient indiquent donnent des montages possibles avec une lecture sans table.

Condition pour une lecture certaine

La conversion ne va pas donner toujours la même valeur dans les mêmes conditions. Si la lecture donne une valeur avec une dispersion de Δ/2 en plus ou en moins, il faut que l'écart des valeurs soit d'au moins Δ. Sinon on risque de lire une valeur pour une autre. Avec 1024 points de lecture, si Δ était nul, on pourrait lire 1024 boutons en lecture mono. Dans la pratique on est bien en deçà.

Si on ne mesure pas les limites, mais que l'on se fie aux valeurs théoriques calculées, cela va donner une dispersion supplémentaire. Par exemple en utilisant des résistances à 5%, il est possible que les valeurs lues soient bonnes à 5% aussi (voir plus si les erreurs sur deux valeurs se cumulent). Pour une lecture voisine de 1023, cela fait une erreur de 50 points et si par ailleurs tout le reste était parfait, on ne pourrait plus discerner que 10 ou 20 boutons en lecture mono de façon certaine.

Lire N bouton en lecture poly, demande les mêmes écarts qu'une lecture de 2N boutons en lecture mono. En gros si on est capable de lire 6 boutons en lecture poly, on devrait être capable de lire 64 boutons en lecture mono.

Pour diminuer les imperfections de mesure, je garde souvent la valeur lue à condition d'avoir lu deux fois consécutivement la même valeur. Cette méthode est simple et élimine les lectures aberrantes.

J'ai essayé différentes méthodes:
- lire plusieurs fois jusqu'à trouver 2, 3, 4... mesures identiques
- lire N valeurs et garder la moyenne
- prendre la valeur médiane de N valeurs (compliqué car il faut trier les valeurs)
- lire N valeurs, retirer la mesure la plus petite et la mesure la plus grande et faire la moyenne de ce qui reste
- pareil en enlevant 2 mesures ou plus de chaque côté.
Il n'y a pas de solution miracle, je choisis en principe deux mesures consécutives identiques.