Lire 64 boutons avec une seule broche

Bonjour,

Après m'être intéressé par mettre deux (seulement deux) boutons sur une seule broche avec une lecture digitale, je me suis penché pour lire 64 boutons sur une seule broche avec le analogRead.

Voici le programme de test utilisé:

// Diviseur de tension à 32 résistances séries, 32 boutons

// VCC
//  ├── SWN-1 ─┐
// 1kΩ         │
//  ├── SWN-2 ─┤
// 1kΩ         ├── Vers A5
//  ├── SWN-3 ─┤
// 1kΩ         │
//  ├── SWN-4 ─┤
// 1kΩ         │
//     . . .
//  ├── SW2 ───┤
// 1kΩ         │
//  ├── SW1 ───┤
// 1kΩ         │
//  ├── SW0 ───┤
// 1kΩ       100kΩ
//  │          │
// GND        GND

const float N = 64; // Nombre de boutons; A ajuster 
// R=100kΩ Résistance de pull-down
// P=Nx1kΩ Résistance de la chaine complète sans la pull-down
const float PsurR = N*1.0/100.0; // Pour des 1kΩ et 100kΩ; A ajuster
const byte BOUTONS = A5; // Broche de lecture; A ajuster

void setup()
{
  Serial.begin(115200); // Régler aussi la console à 115200 bauds!
}

int valeurLue, // Résultat de la conversion brute puis corrigée
    oldValeurLue, // Mémorisation pour permettre deux lectures consécutives identiques
    touche, // Numéro de la touche
    oldTouche; // Touche précédente appuyé pour ne pas l'afficher plusieurs fois

void loop()
{
  do // Lecture brute
  {
    oldValeurLue = valeurLue; // Sauvegarde de la mesure précédente
    valeurLue = analogRead(BOUTONS); // Nouvelle lecture
  } while (valeurLue!=oldValeurLue); // On recommence jusqu'à avoir deux lectures identiques

  // Correction de la valeur
  float temp=valeurLue*PsurR; // 1024βP/R
  valeurLue=1024.0*(temp-1024.0+sqrt((1024.0-temp)*(1024.0-temp)+4*temp*temp/PsurR))/(2*temp);

  //Extraction
  touche=(valeurLue+(512.0/N))/(1024.0/N); // cela donne le N° de la touche 0..N-1
  
  // Affichage
  if (touche!=oldTouche) // Si changement
  {
    if (touche) // C'est une nouvelle touche
    {
      Serial.print("Bouton SW");
      Serial.print(touche-1); // Boutons numérotés à partir de 0
      Serial.print("   (erreur:");
      Serial.print(valeurLue-touche*1024.0/N,0); // Valeur de l'erreur
      Serial.print("/");
      Serial.print(512.0/N,0); // On a le droit d'une erreur de 16 maximum
      Serial.println(")");
      delay(100); // Antirebond
    }
    oldTouche=touche; // Mémorisation pour ne pas afficher plusieurs fois
  }
}

Les résistances utilisées proviennent d'un lotde résistances à cuche carbonne 1kΩ+/-5% mais la bande de tolérance indique argent (10%?) Les mesures à l'ohmmètre indiquent une dispersion de +/-3% à 24°C.
Je n'ai pas trié les résistances, je les ai prises au hasard. L'intérêt de ce montage est que les erreurs sur une résistance compense une erreur inverse sur une autre.

J'ai en plus utilisé une Uno car son convertisseur est plus mal câblé que sur une nano. Je me place dans un contexte défavorable exprès. Essayez donc avec des résistances métalliques et une Nano!

Le programme li le CAN jusqu'à trouver deux lectures consécutives identiques. D'après ce que j'ai vu, plusieurs mesures du même bouton ne diffèrent gère que de 0 à 2 points sur les 1024.

Les interrupteurs ont été remplacés par un fil Dupont (ou Dupond?) et le tout sur une planche à pain (labdec en anglais). La difficulté est de mettre 65 résistances dessus, puis de trouver où les pattes des résistances se touchent.

Le programme calcule le bouton appuyé et affiche comme erreur la valeur lue et corrigée moins la valeur théorique attendue. Pour 64 boutons, je peux avoir une erreur de l'ordre de 7 points, mais je n'en ai jamais plus que 4. On peut corriger une grande succession de valeurs comme j'ai obtenu en ajustant la valeur de la résistance de pull-down dans le programme. Cette résistance permet d'avoir 0 si on n'a pas de bouton appuyé, au lieu d'un potentiel flottant.

Voici le résultat obtenu;

Bouton SW0   (erreur:-3/8)
Bouton SW1   (erreur:-3/8)
Bouton SW2   (erreur:-3/8)
Bouton SW3   (erreur:-3/8)
Bouton SW4   (erreur:-3/8)
Bouton SW5   (erreur:-4/8)
Bouton SW6   (erreur:-3/8)
Bouton SW7   (erreur:-3/8)
Bouton SW8   (erreur:-4/8)
Bouton SW9   (erreur:-3/8)
Bouton SW10   (erreur:-3/8)
Bouton SW11   (erreur:-3/8)
Bouton SW12   (erreur:-3/8)
Bouton SW13   (erreur:-3/8)
Bouton SW14   (erreur:-3/8)
Bouton SW15   (erreur:-4/8)
Bouton SW16   (erreur:-3/8)
Bouton SW17   (erreur:-3/8)
Bouton SW18   (erreur:-4/8)
Bouton SW19   (erreur:-5/8)
Bouton SW20   (erreur:-3/8)
Bouton SW21   (erreur:-4/8)
Bouton SW22   (erreur:-3/8)
Bouton SW23   (erreur:-3/8)
Bouton SW24   (erreur:-4/8)
Bouton SW25   (erreur:-2/8)
Bouton SW26   (erreur:-3/8)
Bouton SW27   (erreur:-3/8)
Bouton SW28   (erreur:-2/8)
Bouton SW29   (erreur:-3/8)
Bouton SW30   (erreur:-2/8)
Bouton SW31   (erreur:-2/8)
Bouton SW32   (erreur:-2/8)
Bouton SW33   (erreur:-3/8)
Bouton SW34   (erreur:-2/8)
Bouton SW35   (erreur:-2/8)
Bouton SW36   (erreur:-2/8)
Bouton SW37   (erreur:-1/8)
Bouton SW38   (erreur:-1/8)
Bouton SW39   (erreur:0/8)
Bouton SW40   (erreur:-1/8)
Bouton SW41   (erreur:-1/8)
Bouton SW42   (erreur:0/8)
Bouton SW43   (erreur:0/8)
Bouton SW44   (erreur:0/8)
Bouton SW45   (erreur:0/8)
Bouton SW46   (erreur:0/8)
Bouton SW47   (erreur:1/8)
Bouton SW48   (erreur:0/8)
Bouton SW49   (erreur:0/8)
Bouton SW50   (erreur:1/8)
Bouton SW51   (erreur:1/8)
Bouton SW52   (erreur:0/8)
Bouton SW53   (erreur:0/8)
Bouton SW54   (erreur:0/8)
Bouton SW55   (erreur:1/8)
Bouton SW56   (erreur:0/8)
Bouton SW57   (erreur:1/8)
Bouton SW58   (erreur:1/8)
Bouton SW59   (erreur:1/8)
Bouton SW60   (erreur:0/8)
Bouton SW61   (erreur:0/8)
Bouton SW62   (erreur:-1/8)
Bouton SW63   (erreur:-1/8)

En théorie, j'aurais pu mettre au moins 100 boutons, l'erreur ne dépend quasiment pas du nombre de boutons.

Un tuto complet sur les boutons et ses montages est en préparation, mais pour répondre à @techolz, je livre déja un montage intéressant.

Quand à la réponse donnée dans https://forum.arduino.cc/t/diviseur-de-tension-arduino-adc-10-bits/1136129/84: "58 boutons sur 8 fils déjà, c'est pas si mal.", c'est rangé aux oubliettes, parce que si sur un fil on peut y mettre 64 boutons, sur 8 fils, j'en mets plus de 500!

Note pour ceux qui ne sont pas électronicoinformaticiens, quand je dis que je mets 128 boutons sur mes deux fils, il ne s'agit pas de varicelle sur ma descendance.

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.