ESP32-S3-wroom et touches tactiles

Bonsoir,

j'ai fait quelques essais avec les touches tactiles (concept top pour la solidité des réalisations !) mais j'ai des résultats surprenants. Je vais essayer de détailler :

Boutons réalisés provisoirement avec trois carrés d'alu (barquette alim.) de 1,5cm de côté, double-face dessous sur la plaque de bidouille, une boucle de fil rigide 0,5 mm direction le breadboard, carré d'alu puis scotch sur l'ensemble pour isoler et solidariser. Je pense réaliser le "clavier" définitif en circuit imprimé epoxy-cuivre mais je ne pense pas que ça ai de l'importance pour le moment.

Le code :

// boutons tactiles
const int bouton1 = 1; // pin 1 - GPIO1 - T1
const int bouton2 = 2; // pin 2 - GPIO2 - T2
const int bouton3 = 3; // pin 3 - GPIO3 - T3

void setup(){
    Serial.begin(115200);
}
 
void loop(){
    Serial.print("Bouton 1 : ");
    Serial.println(touchRead(bouton1));  
    Serial.print("Bouton 2 : ");
    Serial.println(touchRead(bouton2)); 
    Serial.print("Bouton 3 : ");
    Serial.println(touchRead(bouton3)); 
    Serial.println("------------------"); 

    delay(1000);  
}

La sortie de la console série quand je n'appuie pas sur les boutons

Bouton 1 : 31362
Bouton 2 : 63972
Bouton 3 : 38675
------------------

et en appuyant sur les trois boutons (valeurs semblables quand c'est un ou deux seulement)

Bouton 1 : 75609
Bouton 2 : 129086
Bouton 3 : 104478
------------------

C'est le comportement attendu pour un ESP32-S3 (valeur qui augmente) mais ce qui m'étonne c'est la disparité des valeurs (notamment bouton 2 dont la valeur de base est proche de la valeur de bouton1 activé !). Cela ne semble pas lié à la construction des touches : une permutation des fils ne change rien.

Est-ce normal ?

Cela risque de compliquer le code inutilement si je dois définir des seuils différents pour chaque pin...

Y a-t-il une méthode propre pour coder ensuite les interruptions sans trop se soucier des seuils ?

Merci d'avance


La situation semble moins problématique que prévue :

https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/touch.html#touchattachinterrupt

Le paramètre important est threshold qui définie un seuil de variation... c'est déjà mieux :wink:

Mais la disparité de valeur reste surprenante...

Je continue mes essais, malheureusement infructueux :frowning:

Le code suivant ne fonctionne pas et je ne comprend pas pourquoi ...

Avec bool ledstate = true; la LED reste tj allumée en les boutons sont sans effet. Avec bool ledstate = false;, elle reste éteinte.

Est-ce que quelqu'un y voit plus clair que moi ?

// touchbtns tactiles
const int touchbtn1 = 1; // pin 1 - GPIO1 = T1
const int touchbtn2 = 3; // pin 3 - GPIO3 = T3
const int touchbtn3 = 4; // pin 4 - GPIO4 = T4
const int TOUCH_THRESHOLD = 1000;  //sensibilité à ajuster éventuellement :-(

#define LED_BUILTIN  2
bool ledstate = true; 
//bool ledstate = false; 
 
// ------------------------------ SETUP ------------------------------------------
void setup(){
  Serial.begin(115200);

// interruptions 
  pinMode(LED_BUILTIN, OUTPUT);

  touchAttachInterrupt(touchbtn1, i_bouton1, TOUCH_THRESHOLD);
  touchAttachInterrupt(touchbtn2, i_bouton2, TOUCH_THRESHOLD);
  touchAttachInterrupt(touchbtn3, i_bouton3, TOUCH_THRESHOLD);
}
// ------------------------------ FIN DU SETUP -----------------------------------

// ------------------------------ INTERRUPTIONS ----------------------------------
void i_bouton1() {
    ledstate = false;
    // censé éteindre la LED
}

void i_bouton2() {
    ledstate = true;
    // censé allumer la LED
}

void i_bouton3() {
    ledstate = !ledstate;
    // censé basculer l'état de la LED
}


// ------------------------------ LOOP -------------------------------------------
void loop(){

    if (ledstate) {
        // allumée
        digitalWrite(LED_BUILTIN, HIGH);
    }
    else {
        // eteinte
        digitalWrite(LED_BUILTIN, LOW);
    }

}

Par rapport au code posté hier soir, j'ai déplacé les fils puisque, si j'ai bien compris, la LED de la carte partage le pin 2 (mais ça ne marchait pas mieux avec le câblage initial)

Bonjour,

Pas sûr de bien comprendre ton montage. Je ne connais pas cet ESP WRom
Pour raccorder les boutons tu n'utilises pas GND ?
Dans le setup il faut mettre des résistances pullup sur tes entrées 1 , 2 et 3 ?
( pinMode(bouton_x, INPUT_PULLUP);
La lecture devrait de donner soit 0 soit 1 ? (hormis les rebonds)
Avant de te lancer dans les interruptions, faire qq chose de simple qui fonctionne.

Question conne, mais la fonction touchRead te donne bien une valeur supérieur à 1000?

1 Like

Merci de te pencher sur le problème mais il s'agit de touches à effleurement capacitif : un seul fil "en l'air" sur une petite surface (cf post 1) et elles semble être électriquement fonctionnelles puisque la fonction touchRead() renvoie qqchose.

Oui : valeurs de base de l'ordre de 30000 à 60000 d'après les mesures du post 1.

Comme tu disais que tu avais modifié ton branchement, je posais à tout hasard la question.

Par acquis de conscience, je vais vérifier sur le pin 4 mais les autres n'ont pas été modifiés...

Je n'ai pas juste la matos sous la main pour tester mais j'ai déclaré le pin 2 en mode sortie. Par contre pour les boutons je ne les ai pas déclaré en mode entrée.

Mais si touchRead() fonctionnait au départ c'est que ça ne devrait pas être nécessaire, non ? (Est-ce pour autant conseillé de le faire ?)

Bonsoir,

je pense avoir trouvé la réponse et merci à terwal pour sa question pas conne du tout puisqu'elle m'a mis sur la piste...

J'ai repassé le premier schéma avec le pin 4 comme bouton et j'ai pu constaté que les valeurs renvoyées par touchRead() étaient totalement figées et ce pour les trois boutons ! Normal que les interruptions ne se fassent pas !
Même chose pour le pin 5 mais les autres (pas tous testés mais la plupart) fonctionnent !

--> reste un mystère : pourquoi ?

Et reste à tester les interruptions avec les pins fonctionnels. À suivre !

Pas tout à fait résolu mais ça progresse !

Les interruptions n'ont pas l'air de fonctionner comme ce que j'avais pu voir avec un arduino nano et des boutons mécaniques classique :

  • pas de différence entre le toucher et le relâcher du bouton (ou pas encore trouvé). Il y a donc deux interruptions par clic
  • j'ai mis un compteur d'interruption et là je comprend plus bien

Le code :

// touchbtns tactiles
const int touchbtn1 = 1; // pin 1 - GPIO1 = T1
const int touchbtn2 = 6; // pin 6 - GPIO3 = T6
const int touchbtn3 = 3; // pin 3 - GPIO4 = T4
const int TOUCH_THRESHOLD = 1000;  //sensibilité à ajuster éventuellement

#define LED_BUILTIN  2
bool ledstate = true; 
//bool ledstate = false; 

int i_count = 0;
int i_cprec = 0;
 
// ------------------------------ SETUP ------------------------------------------
void setup(){
  Serial.begin(115200);

// interruptions 
  pinMode(LED_BUILTIN, OUTPUT);

  touchAttachInterrupt(touchbtn1, i_bouton1, TOUCH_THRESHOLD);
  touchAttachInterrupt(touchbtn2, i_bouton2, TOUCH_THRESHOLD);
  touchAttachInterrupt(touchbtn3, i_bouton3, TOUCH_THRESHOLD);
}
// ------------------------------ FIN DU SETUP -----------------------------------

// ------------------------------ INTERRUPTIONS ----------------------------------
void i_bouton1() {
    ledstate = false;
    i_count++;
    // censé éteindre la LED
}

void i_bouton2() {
    ledstate = true;
    i_count++;
    // censé allumer la LED
}

void i_bouton3() {
    ledstate = !ledstate;
    i_count++;
    // censé basculer l'état de la LED
}


// ------------------------------ LOOP -------------------------------------------
void loop(){

    if (ledstate) {
        // allumée
        digitalWrite(LED_BUILTIN, HIGH);
    }
    else {
        // eteinte
        digitalWrite(LED_BUILTIN, LOW);
    }
    if (i_cprec != i_count) {
          i_cprec = i_count;
          Serial.print(ledstate);
          Serial.print("  --  ");
          Serial.println(i_count);
    }
}

J'ai appuyé successivement sur les trois boutons (entre parenthèses mes commentaires - ce n’est pas dans la sortie serial.print)

23:46:06.508 -> 0  --  3                  (appui bt 1: la LED s'éteint)
23:46:07.382 -> 0  --  6                  (relache bt 1: la LED reste éteinte)
23:46:10.575 -> 1  --  9                  (appui bt 2: la LED s'allume)
23:46:11.284 -> 1  --  12                 (relache bt 2: la LED reste allumée )
23:46:13.093 -> 0  --  15                 (appui bt 3: la LED s'éteint)
23:46:13.739 -> 1  --  18                 (relache bt 3: le LED s'éteint)

Pourquoi est-ce que le compteur compte trois par trois ??? :face_with_raised_eyebrow:

Les variables modifiées dans les routines de traitement d'interruption doivent être déclarées volatile.
Cela indique au compilateur de ne pas faire d'optimisation sur celles-ci et de relire leur contenu en RAM systématiquement avant de les utiliser. Cela est nécessaire car le contenu des variables change de façon totalement asynchrone par rapport au déroulement du reste du code.

Espressif a publié une note d'application où ils donnent des informations sur la réalisation des touches capacitives (voir le 3.9)

Il faut peut-être mettre en place un peu de filtrage.

Un peu de lecture sur le sujet ?

1 Like

Bonjour à tous,

mea culpa, J'étais "à côté de la plaque".
Je connaissais ce principe mais je ne savais pas que l'ESP32 l'utilisait de cette manière.
A+

Merci, je corrigerai ça pour voir ce qui se passe.

Merci pour la doc, je vais étudier ça...

Pour le filtrage, tu parles d'éventuels rebonds ? Normalement il ne devrait pas y en avoir avec ce genre de technique et il serait étrange qu'il y en ai à chaque fois exactement trois... Pareil, je vais ajouter une capa de filtrage pour voir.

Joli comme expression à propos d'un contact sensitif :wink:

When using the touch function, it is recommended to populate a zero-ohm series resistor at the chip side to reduce the coupling noise and interference on the line

Ils ne sont pas sympa de ne pas préciser plus clairement entre quoi et quoi il faut brancher cette résistance... « chip side » c'est vague :face_with_raised_eyebrow:

C'est aussi mentionné ici, page 13 :

2.10 Touch Sensor
When using the touch function, it is recommended to reserve a series resistor at the chip side to reduce the coupling noise and interference on the line, and to strengthen the ESD protection. The recommended resistance is 470 Ω ~ 2 kΩ, preferably 510 Ω. The specific value also depends on the testing of the product

Je pense qu'il s'agit d'une résistance entre la GPIO et GND, et il faut la mettre le plus près possible du SoC ESP32 ("chip side").

Bonjour
la resistance est a insérer entre la zone tactile et le GPIO