Un petit projet d’une après-midi pour implémenter une interface tactile à l’aide d’un microcontrôleur.
Un peu de contexte : nous sommes en 2019, je suis en 5e année d’école d’ingénieur, en cours d’IoT (Internet of Things, objet connectés). Par groupe de 5, nous devons réaliser un projet sur 4 jours, sur le thème “un objet connecté inutile, mais désirable” (un sujet de société finalement). Notre équipe décide de s’orienter vers une plante connectée appelée Super Spinach 3000, mais pour moi, il manque quelque chose pour que l’ensemble soit plus désirable.
Je me rappelle alors du projet “Botanicus interacticus” de Disney Research Hub, permettant de brancher une interface sur une plante pour visualiser les interactions tactiles avec un utilisateur. Une plante connectée, c’est bien, mais une plante connectée qui peut exprimer sa joie d’être caressée ou permet d’allumer la lumière/musique, c’est bien mieux !
L’équipe, convaincue par mon idée, m’a confié la réalisation de cette partie (oups !).
Détection d’impédance
On va commencer par afficher les données brutes sur une pin analogique avant et pendant un contact, avec le code suivant (Fichier > Exemples > 01: Basics > AnalogSerialRead) :
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.println( analogRead( A1 ) );
}
Les résultats sont affichés à l’aide du moniteur série de l’éditeur Arduino.
Ce qu’on cherche à faire ici est un simple diviseur de tension.
Pin flottante
J’ai simplement mis un fil de la pin A1, et j’observe les données pendant quelque temps avant de poser mon doigt dessus. Voilà un exemple des données brutes, au moment où je touche le fil :
Le signal ressemble à une sinusoïdale oscillant autour de 512 (1024/2) à vide, saturée entre 0 et 1023 quand un contact est établi.
Qu’est-ce que c’est que cette sinusoïdale ? (cliquer pour étendre)
Le convertisseur analogique vers digital (ADC) de l’Arduino utilise 10 bits, ce qui nous donne des valeurs de 0 a 1023.
Ici, observe un bruit sinusoïdal, assez faible avant que j’établisse le contact, puis fortement amplifié. Cela indique qu’il s’agit d’un bruit extérieur au système, capté par “l’antenne” formée par le fils sur la pin A1 et mon corps.
Ce bruit est caractérisé par 5 périodes toutes les 100 millisecondes, ce qui représente donc 50Hz (et là si vous êtes attentifs, vous voyez où je veux en venir).
Et oui, un signal sinusoïdal de 50Hz c’est bien celui du réseau électrique français ! On peut difficilement ne pas le capter dans des mesures avec un fils servant d’antenne comme nous avons maintenant.
Et le GIF associé :
Quand bien même le contact est détecté (la LED rouge s’allume), la pin reste parfois “chargée” pendant quelques secondes quand j’enlève la main, ce qui n’est pas un comportement désiré.
Pull up 2 M Ohms
En ajoutant une résistance de 2 Mega Ohms entre notre pin et l’alimentation Vcc (ici, 5 Volts), on “force” la lecture et la reinitialisation de la pin.
La valeur de base est cette fois très proche de 1023, et descend vers 980 quand un contact est établi. Cette fois, on peut simplement ajouter une condition pour allumer la LED si on passe en dessous de la valeur 1000 :
//allumer la led si on passe sous le seuil, sinon eteindre
digitalWrite(LED_BUILTIN, sensorValue < 1000);
(Les clignotements sont dus au bruit sinusoïdale vu précédemment)
Plus de problèmes de pin chargée maintenant, la forte impédance de la résistance permet également d’éliminer la plupart des bruits.
Cependant, utiliser un simple seuil n’est pas une bonne idée, le système devient sensible à toute perturbation. Cette implémentation repose uniquement sur la résistance du corps humain, une valeur assez variable en fonction des conditions (humidité et épaisseur de la peau, isolation du sol, …), mais surtout cette méthode ne fonctionne pas très bien si on veut détecter le contact avec un autre objet, comme une plante dans notre cas.
Pour détecter un contact avec une plante, on va garder le même circuit et y ajouter une détection capacitive.
Détection capacitive
Un condensateur est une couche d’isolant entre deux couches de matériaux conducteurs. Ce composant présente une certaine capacité à retenir et libérer des charges, et on va utiliser cette propriété pour détecter un contact avec notre plante.
On cherche ici à charger le condensateur, puis détecter le temps qu’il prend à se décharger complètement (via la valeur cycles
).
Cette valeur est comparée à une baseline cycleThreshold
qui représente notre capacitance de base de l’environnement, étalonnée quand le système est à vide ou réglée via un potentiomètre.
const int plantSensor = 4;
uint8_t cycleThreshold = 25;
void setup() {
pinMode(plantSensor, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
//empty capacitor
pinMode(plantSensor, OUTPUT);
digitalWrite(plantSensor, LOW);
delayMicroseconds(1000);
//count commutation
pinMode(plantSensor, INPUT);
uint8_t cycles;
for(cycles = 0; cycles < 256; cycles++) {
if(digitalRead(plantSensor) == HIGH)
break;
}
//touch detected
digitalWrite(LED_BUILTIN, cycles > cycleThreshold);
}
Ce système est moins sensible au bruit et la valeur de sortie est bien plus stable. De même, la résistance du corps humain influe beaucoup moins sur le résultat. J’ai fait des tests avec un fils relié au GND sur ma peau, de plus en plus prêt du fils de détection, sans observer de changements comportementaux (à l’opposé de la méthode par impédance).
Résultats !
De nombreux matériaux peuvent maintenant vous servir d’interface !
Une banane :
Une plante :
Notre projet Super Spinach 3000 et son interface tactile nous a offert un petit 18/20, tout le monde voulait caresser notre plante (voir le code du projet final). Je me suis également occupé de l’affichage de l’état de contentement de la plante via l’écran E-paper (la qualité du code général n’est pas de mon ressort…).
Sur le GIF de la plante, on peut voir que la LED s’allume avant que j’établisse le contact. Cela est dû à une valeur de cycleThreshold trop basse : la proximité de ma main à la plante est suffisante pour que la capacité change (avec un condensateur créé par ma main | l’air comme isolant | la plante). Intéressant pour un petit tour de magie.
Notes
Je ne suis pas sûr de l’effet à long terme de ce type d’interface capacitive sur un organisme vivant, mais on peut faire quelques observations/déductions:
- Aucune idée de ce que peut avoir comme effet de charger et décharger en permanence la plante (ne le risquez pas : probablement pas bon)
- Le fil connecté dans la plante va agir comme une cathode, et attaquer le milieu (surement pas bon)
- Le fil est composé de métal (cuivre ?), qui est plutôt du côté “mauvais” sur le spectre de la santé des plantes. En tout cas, percer un trou dans la plante pour y passer le fil n’est certainement pas bon d’un point de vue contamination (certainement pas bon)