Skyduino:~#
Articles
arduino, Corrigé, programmation, projet

[Arduino] Faire une touche tactile avec une simple résistance

Bonjour tout le monde !

Aujourd’hui je vous ai concocté un article qui va à coup sur vous plaire ;)

Le sujet du jour : Comment concevoir des touches tactiles avec une « bête » entrée / sorties numérique et une résistance !

OMG WTF BBQ ! Comment un tel miracle et t-il possible !?

Héhé, let’s go, un peu de théorie !
Préparez vous Jamy et Fred ne seront pas là pour vous re-expliquer ;)

Prenons tout d’abord ce schéma comme base :

(schéma fait avec LTspice)

GPIO représente une broche numérique de notre arduino.
R1 est une résistance de pull-up au 5v d’au moins 1M ohms (= 1000K ohms).
Et (c’est là qu’il faut bien saisir l’astuce) C1 représente la capacité du corps humain en contact avec la touche.

En gros il faut voir l’intégralité du corps humain comme un gros condensateur.

Maintenant question : pourquoi la résistance ? Comment détecter / mesurer la présence de ce « condensateur » pour pouvoir faire notre touche tactile ?
C’est très simple !

Un condensateur se charge en un certain temps (je vous passe le calcule de Uc(t), de la constante de charge, etc …).
Plus la valeur de la résistance de charge est grande, plus le condensateur met de temps à ce charger.

En partant de ce principe il est possible d’utiliser n’importe quelle broche numérique en tant que « touche tactile ».

L’astuce ce décompose en plusieurs étapes :
1 – tout d’abord on envoie 0v dans la broche (en sortie donc) pendant quelques millisecondes, cela a pour effet de décharger le « condensateur » (sous-entendu nous) relié à la broche.
2 – on place la broche en entrée tout en désactivant les résistances de pull-up interne.
3 – le faible courant parcourant la résistance de pull-up externe (rappel : >1M ohms) va commencer à charger le condensateur.
4 – tant que le condensateur n’as pas franchi la barre des VCC/2 (tension de commutation d’une broche numérique) on va incrément un compteur.
5 – dés que l’on atteint VCC/2, on arrête de compter, et on regarde le résultat obtenu. S’il est supérieur à notre valeur de référence c’est que quelque chose est en contact avec la broche.
6 – dans le cas ou rien n’est en contact avec la broche, celle ci commutera quasi instantanément et la valeur du compteur sera proche de 0.

Pas con hein ;)

Oui MAIS …
La charge du « condensateur » prend quelques microsecondes !
On a beau avoir une résistance de fort valeur on a aussi une capacité à charger de très faible valeur !

Le compteur dont je parle compte donc … des cycles CPU !
Avec un ATmega328p à 16MHz on peut s’attendre en moyenne à 50 cycles CPU lors de l’appui sur une touche, oui seulement 50 cycles !
Autant dire qu’il faut passer par de la manipulation de port et oublier les fonctions arduino qui sont beaucoup trop lente !

Mais mais mais ! Ça veut dire que pour faire un clavier avec 10 touches tactiles il me suffit d’avoir 10 résistances de 1M ohms et 10 entrées / sorties numérique !?
Exactement ! :)

Et justement tient … pourquoi ne pas faire un clavier avec 10 touches tactiles !

Vous aurez donc besoin de :
- une carte arduino
- 10 résistances de 1M ohms (ou plus)
- 10 fils (ou des pince crocodile)
- 10 morceaux de trucs métallique

Avant de parler du côte hardware arduino parlons un peu de ces fameuse « touches tactiles ».

Mes touches sont composées d’un morceau de papier d’aluminium, collé sur un morceau de carton (avec de la colle en bâton), le tout collé sur un autre morceau de carton.

Un cutter, du carton, du papier d’aluminium, un peu de découpage / collage (niveau CM2) et vous devrez avoir un truc pas trop mal ;)

Pour les résistances le câblage est on ne peut plus simple, il suffit de faire comme sur le schéma !
Entrée / sortie -> résistance -> +5V
. |------> touche tactile

Une fois les résistances en place il suffit de relier les touches tactiles et le tour est joué !

Maintenant le plus important, le code !

/* Seuil de détection */
const uint16_t THRESHOLD = 50;

/* setup() */
void setup() {

  /* Initialise le port série à 115200 bauds */
  Serial.begin(115200);

  /* Aucune initialisation requise des broches "tactiles",
   * la fonction touch_measure() ce charge de tout ;)*/
}

/* loop() */
void loop() {

  /* Pour chaque broches de D2 à D11 (10 touches) */
  for (uint8_t i = 2; i < 12; ++i){

    /* Test si la "touche" a été appuyé ou non */
    if(touch_measure(i) > THRESHOLD)
      Serial.print('1');
    else
      Serial.print('0');

    //Serial.println(touch_measure(i), DEC);

    /* Sépare chaque bits */
    Serial.print(' ');
  }

  /* Sépare chaque lignes */
  Serial.println();

  /* Délai no-flood */
  delay(500);
}

/**
 * Mesure la capacité électrique présente sur une broches digitale
 *
 * Principe : Place la broche au 0v, puis compte le nombre de cycles requis avant que la broche ne commute.
 * Ce système tire parti du temps de charge d'un condensateur au travers d'une résistance de forte valeur (>1M ohms).
 *
 * @param measurePin Broche sur laquelle effectuer la mesure
 * @return Valeur comprise entre 0 (= pas de capacitance) et 255 (= "grosse" capacitance)
 *
 * Remarque : une résistance >1M ohms entre la broche et +VCC est obligatoire !
 */
uint8_t touch_measure(uint8_t measurePin){

  /* Registre bas-niveau, DDR = port de configuration, PORT = port de sortie, PIN = port d'entrée */
  uint8_t xport = digitalPinToPort(measurePin);
  volatile uint8_t *ddr = portModeRegister(xport);
  volatile uint8_t *port = portOutputRegister(xport);
  volatile uint8_t *pin = portInputRegister(xport);

  /* Résultat de la mesure, Bitmask de la broche à mesurer */
  uint8_t cycles, bitmask = digitalPinToBitMask(measurePin);

  /* Décharge la capacité en contact avec la broche */
  *port &= ~(bitmask);     // Place la broche à LOW
  *ddr |= bitmask;         // Place la broche en sortie
  delayMicroseconds(1000); // Attend pour être sur que la capacité est déchargé

  /* Place la broche en entrée, sans résistance de pull-up ! */
  /* (La résistance de >1M ohms externe servira de résistance de pull-up) */
  *ddr &= ~(bitmask);

  /* Mesure le nombre de cycles CPU requis avant que la broche ne commute */
  for(cycles = 0; cycles < 256; ++cycles){
    if (*pin & bitmask) break; // Si la broche a commuter on quitte la boucle
  }

  /* Re-décharge la capacité en contact avec la broche
   * afin d'éviter tout parasitages d'une autre mesure sur une autre broche.
   * Dans le cas contraire il serait impossible de manipuler plus d'une touche "tactile" */
  *port &= ~(bitmask);
  *ddr |= bitmask;

  /* Retourne le résultat */
  return cycles;
}

Et maintenant jouons un peu avec nos touche tactiles fraîchement réalisées !
J’ai choisi un seuil de détection à 50 cycles CPU, cette valeur semble donner des résultats pas trop mal avec peu de fausses détections.

Alors elle est pas belle la vie ?
Oubliez les boutons mécaniques qui marchent une fois sur deux, avec des rebonds à filtrer, des cliquetis à chaque pression.
L’avenir c’est le tactile, on n’arrête pas de vous le dire ! ;)

Allez bon WE à tous, et bon bricolage :)

About these ads

Discussion

25 réflexions sur “[Arduino] Faire une touche tactile avec une simple résistance

  1. Salut,

    Tres sympa cette bidouille

    Dans le même genre:

    http://www.elektor.fr/nouvelles/capteur-tactile-a-la-mac-gyver.2176905.lynkx

    Publié par Philippe | 2 juin 2012, 15 h 06 min
    • Je me suis basé sur le principe de fonctionnement de la librairie Qtouch de Atmel.
      Je suis tombé sur le lien instructables cité dans ton article juste après avoir finit mon code …

      Au final on a fait exactement la même chose, j’ai juste la gestion « arduino » des broches en plus dans ma version.
      Par contre je sait pas si le fait d’utiliser du crayon comme conducteur est une bonne idée … moi j’utilise du papier d’alu …

      Publié par skywodd | 2 juin 2012, 15 h 16 min
      • l’avantage de l’alu, c’est que cela ne s’oxydera pas, quant au crayon (noir) , le carbone est normalement un bon conducteur.

        Publié par Philippe | 2 juin 2012, 16 h 23 min
      • Salut,

        dis moi, pour optimiser un peu, tu pourrais pas plutôt faire un compteur qui compte jusqu’à ta valeur seuil et si ta broche a commuté, renvoie true et sinon false… au lieu de compter jusqu’à 256 ?

        Publié par thom | 15 juin 2012, 16 h 34 min
  2. J’aime les touche a tout ;-)

    Publié par \fab\ | 3 juin 2012, 11 h 03 min
  3. @thom Oui ce serait envisageable, mais bon on est pas à quelques µs prés ;)

    Publié par skywodd | 15 juin 2012, 16 h 41 min
  4. Projet sympa, avec pleins d’applications possibles.
    Deux petites questions :
    – pour pouvoir gérer plus de « touches », serait-il possible de les brancher en matrice ?
    – y a-t-il moyen d’utiliser un papier imprimable en guise de touche ? L’idée serait de faire une déco murale interactive …

    Publié par Nath | 24 juillet 2012, 14 h 38 min
    • >> – pour pouvoir gérer plus de “touches”, serait-il possible de les brancher en matrice ?

      Non je ne pense pas, enfin pas avec mon schéma tel quel.
      Il faudrait revoir les valeurs des résistances à la hausse (théoriquement x2) ou alors utilisé un microcontrôleur beaucoup plus rapide pour faire les mesures.

      >> – y a-t-il moyen d’utiliser un papier imprimable en guise de touche ? L’idée serait de faire une déco murale interactive …

      Si tu colle du papier d’aluminium derrières le papier d’imprimante ça marche sans probléme ;)

      Publié par skywodd | 24 juillet 2012, 17 h 08 min
  5. Bonjour à tous, superbe boulot aussi simple qu’efficace !
    En me basant sur le même principe, j’ai tracé des traits au crayons gris sur une simple feuille de papier et j’ai superposé une plaque de verre par dessus. Après quelques réglage de sensibilité, j’arrive à capter les touchés.
    Mon idée finale est de créer une plaque capacitive déportée que l’on placerait derrière le rétroéclairage d’un écran LCD, afin de rendre celui-ci tactile.
    Malheureusement, la dalle LCD perturbe les champs et fausse totalement la captation.
    Auriez-vous des idées pour éviter la perturbation causée par la dalle ?

    Voici ce que je cherche à réaliser :

    ============= Plaque de Verre
    ——————— Dalle LCD
    ********************* Rétro-éclairage
    xxxxxxxxxxxxxxxxxx surface Capacitive « maison » pilotée par l’arduino.

    D’avance merci pour votre aide !

    Publié par F.Tassier | 18 mars 2013, 13 h 41 min
    • J’ai aucune idée …
      Dans les écrans capacitif « classique » la surface capacitive est entre la dalle lcd et le verre, il y a peut être une raison à cela.

      Publié par skywodd | 18 mars 2013, 16 h 56 min
      • Les dalles capacitives n’ont probablement pas le même fonctionnement que ce type de montage, je pense étudier leur fonctionnement pour me rapprocher au possible de leur principe, en espérant éviter les perturbations du LCD

        Publié par F. Tassier | 18 mars 2013, 17 h 05 min
  6. Salut,
    j’aimerais savoir si on peut mettre une résistance 10kOhms dans le montage au lieu de 1mOhm ? Parce qu’en fait je n’ai pas de résistance 1MOhm.

    Publié par Alexandre De Angelis | 31 juillet 2013, 18 h 04 min
  7. Bonjour,

    Comment faire ce genre de projet sans PC derrière l’Arduino?
    Est-ce possible?
    Pour le moment on utilise l’option Serial qui n’est dispo que par l’USB et non en alimentation externe…

    Merci d’avance

    Publié par Mathieu Caseau | 13 novembre 2013, 12 h 21 min
    • Bien sûr que c’est possible ;)
      Il suffit de ne pas utiliser Serial et de faire une sortie d’informations sur autre chose, des leds par exemple (voir pas de sortie du tout).

      Publié par skywodd | 13 novembre 2013, 13 h 32 min
      • Re-bonjour,

        Voici mon code actuel, je suis débutant sur Arduino et en programation.
        Pourriez-vous m’indiquer par quoi je devrais changer mon envois et réception du serial Pour pouvoir avoir mon capteur capacitif sans que l’Arduino soit connecté en USB sur le PC?

        Merci bcp d’avance.

        Le but de mon montage étant d’animer des leds sur une maquette et démarrer l’animation par le toucher d’une plaque conductrice… Le actionTouche et Action Relache existent mais je ne les ai pas mis ici dans le code. Ils contiennent l’animation à proprement parler.

        #include

        CapacitiveSensor capSensor = CapacitiveSensor(3,2);

        int threshold=1000;

        const int led_chauffage = 4;
        const int led_01 = 5;
        const int led_02 = 6;
        const int led_03 = 7;
        const int led_04 = 8;
        const int led_05 = 9;
        const int led_06 = 10;
        const int led_07 = 11;
        const int led_08 = 12;
        const int led_09 = 13;

        void setup()
        {
        Serial.begin(9600);

        pinMode(led_chauffage, OUTPUT);
        pinMode(led_01, OUTPUT);
        pinMode(led_02, OUTPUT);
        pinMode(led_03, OUTPUT);
        pinMode(led_04, OUTPUT);
        pinMode(led_05, OUTPUT);
        pinMode(led_06, OUTPUT);
        pinMode(led_07, OUTPUT);
        pinMode(led_08, OUTPUT);
        pinMode(led_09, OUTPUT);
        }

        void loop()
        {
        long sensorValue = capSensor.capacitiveSensor(30);

        Serial.println(sensorValue);

        if(sensorValue > threshold)
        {
        actionTouche();
        }
        else
        {
        actionRelache();
        }

        delay(10);
        }

        Publié par Mathieu Caseau | 13 novembre 2013, 19 h 43 min
      • Poste ton code et ton montage sur le forum arduino.cc, c’est pas pratique de répondre sur mon blog ;)

        http://forum.arduino.cc/?board=33.0

        Publié par skywodd | 18 novembre 2013, 20 h 09 min
      • bonjour, j’ai essayé de réaliser un touche tactile (qui allume un led dans un premier tps):
        – sans aucun problème lorsque la uno est branchée en USB
        – problème avec une alim externe (7V), rien ne se passe. J’ai pourtant bien relié la résistance d’1M au Vcc = 7V. j’ai mis en commentaire tout ce qui est en rapport avec Serial.

        Une idée ?

        Publié par cesar6269 | 1 août 2014, 13 h 58 min
      • @CESAR6269
        >> J’ai pourtant bien relié la résistance d’1M au Vcc = 7V. j’ai mis en commentaire tout ce qui est en rapport avec Serial.

        Le VCC doit être relié au +5v de l’arduino qu’importe l’alimentation. Si tu envois du +7v (VIN) dans une des broches tu va tout cramer.

        Publié par Skywodd | 6 août 2014, 15 h 10 min
  8. Bonjour,

    J’ai réussi a utiliser la capteur capacitif.

    J’ai malgré tout un problème.

    J’utilise une plaque très fine d’alu déportée de 50cm par rapport à l’arduino comme capteur.

    Tout fonctionne, j’indique le threshold voulu suivant le montage et la réaction au toucher de la plaque métallique et mon animation de leds fonctionne dés que je touche la plaque.

    Un problème persiste néanmoins: si la température du lieu dans lequel je suis n’est pas constant (entre 5° et 23°), le seuil de sensibilité de mon capteur change. Est-ce normal?
    Que faire pour éviter cela? (composant en plus à mettre que la résistance d’1MOhm?)
    Ou programme avec capteur de température et changement automatique du seuil suivant la température?

    En gros, comment stabiliser cet interrupteur capacitif?

    Merci beaucoup d’avance.

    Mathieu

    Publié par Mathieu Caseau | 24 janvier 2014, 14 h 58 min
    • >> Est-ce normal?

      C’est normal, la capacité de la plaque dépend de la température.

      >> Que faire pour éviter cela? (composant en plus à mettre que la résistance d’1MOhm?)
      >> Ou programme avec capteur de température et changement automatique du seuil suivant la température?
      >> En gros, comment stabiliser cet interrupteur capacitif?

      Tu peut faire une calibration de ton capteur à différentes températures.
      Si la température est de X tu prends la valeur A comme référence, si la température est de Y tu prends la température B, etc.

      D’un point de vue électronique je ne pense pas qu’il existe de solution miracle.

      Publié par skywodd | 1 février 2014, 15 h 29 min
  9. bonjour,
    je voulais faire ces touches tactiles, le code marche mais je ne trouve pas comment avoir la feuille de résultats (pour dire quelles touches on a touché)
    Pouvez vous m’aider?
    Merci par avance

    Publié par Carole | 6 mars 2014, 15 h 12 min
  10. Merci, ça marche super !
    @carole (si tu suis toujours) : tu terminal série est il bien à 115200 bauds ?

    Publié par aurel05 | 11 avril 2014, 22 h 33 min
  11. Super programme !
    Serait-il possible de détecter la position du doigt selon l’endroit de la touche afin de faire une sorte de trackpad ?! Apparemment la valeur retournée de la capacitance ne semble pas corrélée avec cette position même sur une touche résistive.

    Publié par Antoni | 22 octobre 2014, 17 h 12 min
  12. Bonsoir,
    La valeur retournée n’est déjà pas très stable alors pouvoir dire que le doigt est à 1, 10 ou 20 cm du raccordement, je ne pense pas cela faisable.

    Publié par Mathieu | 22 octobre 2014, 17 h 21 min

Rétroliens/Pings

  1. Pingback: Le tactile capacitif pour les nuls ! - 2 juin 2012

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Archives

Wow. Dogecoin. Amaze.

Laissez un tip en Dogecoin

DMMNFk6WBVTpx2Wu1Z35GL61QXSd6r6WQx

Suivre

Recevez les nouvelles publications par mail.

Rejoignez 768 autres abonnés