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







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 minJe 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 minl’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 minSalut,
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 minJ’aime les touche a tout
Publié par \fab\ | 3 juin 2012, 11 h 03 min@thom Oui ce serait envisageable, mais bon on est pas à quelques µs prés
Publié par skywodd | 15 juin 2012, 16 h 41 minProjet 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 minBonjour à 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 minJ’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 minLes 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