ESP32 et interruption, compte double

Bonjour,
Sur un module TTGO LoRA T3, j'ai programmé avec l'IDE Arduino 2 pins pour gérer des interruptions et compter des fronts montants d'impulsions qui arrivent à vitesse lentes. (pluviomètre et anémomètre)

Il s'avère que sont comptés non seulement les fronts montants (RISING) mais également descendants (FALLING).

J'ai d'abord pensé à des rebonds de contacts et j'ai donc rajouté un anti-rebond soft qui fonctionne bien.

Puis j'ai trouvé un document de chez Espressif (relevés de bugs) qui stipule qu'on ne peut utiliser 2 pins du même groupe pour gérer les interruptions.
J'ai donc fait l'essai avec une seule pin, avec le même résultat !

Jai trouvé d'autres posts où les gens galèrent avec l'ESP et les interruptions.

Est-ce que quelqu'un a déjà utilisé avec succès les interruptions sur le même module ?

Pour le moment, j'en suis arrivé à la conclusion que l'ESP32 est buggé de ce côté !

Cordialement,

Personne ? :upside_down_face:

Bonjour,

un peu de lecture ?

https://randomnerdtutorials.com/?s=esp32+interrupt

Bonjour

Pour information : l'ESP32 possède un bloc de compteurs/décompteurs nommé PCNT = Pulse counter pouvant progresser sur des fronts de GPIO......... les interruptions, devenues rares, ne survenant qu'aux débordement de ces compteurs 16bits

Un électronicien ne peut que se poser la question suivante :wink:
Pourquoi faire un comptage logiciel par interruptions élémentaires quand un comptage matériel est disponible dans la puce ?

ici une bibliothèque qui utilise ces compteurs 'hardware' d'impulsions :
https://github.com/madhephaestus/ESP32Encoder

Bonjour et merci pour vos réponses,

Ce truc n'est pas loin de me rendre fou... :laughing:
Le programme fonctionne parfaitement sur un Arduino mais déraille sur un module TTGO. Et je ne vois aucune raison pour laquelle ça ne fonctionnerait pas, à part un bug dans l'ESP32.

J'espérais que quelqu'un d'autre ait constaté le problème pour lever le doute.

Je vais regarder du côté des compteurs, que je n'ai jamais utilisés et qui semblent nettement plus compliqués à mettre en œuvre. :upside_down_face:

Pourquoi faire un comptage logiciel par interruptions élémentaires quand un comptage matériel est disponible dans la puce ?
Peut-être parce qu'il n'y a aucune raison que ça ne fonctionne pas ? :joy:

Cordialement,

Pour ma part , sans avoir eu l'occasion de constater le pb rencontré (sans doute en raison d'un usage plus léger de interruptions) je m'attends à priori à trouver de temps en temps des différences de comportement entre un microcontrolleur 8 bits (AVR) et un SOC 32 bits tournant en arrière plan sous le petit systeme d'exploitation RTOS (ESP32).....et des bugs en proportion :wink:

à l'occasion de ce fil je découvre un échange sur le même sujet.. il il semble que l'ESP32 ait besoin de fronts plutôt raides sur les GPIO d'interruption pour que ce défaut (mode CHANGE de fait qq soit le choix de mode ) n'apparaisse plus

quels sont les temps de montée/descente des signaux actuellement appliqués aux GPIO ?

L'insertion entre capteur et GPIO d'un trigger (74HC14 ou autre) élimine-t-il le défaut de comportement ?

Juste un point de précision :
En français, Timer se traduit par Compteur. :grinning:

Autre point :
Il y a une énorme différence entre un micro espressif et les autres micros "plus classiques".

Le micro qu'utilise Espressif, ce n'est pas Espressif qui le conçoit ni le fabrique, c'est Cadence (Micro gamme Xtensia).
La gamme de micros Xtensia est constituée de micros "à terminer par le client" -> le client de Cadence ce n'est pas toi c'est Espressif.

Espressif a deux solutions pour terminer les micros :

  1. concevoir s'il possède les compétences, ou acheter à Cadence des blocs (briques) d'électronique à ajouter
  2. remplacer le maximum de blocs électroniques par de la programmation.

Pour Expressif la deuxième solution est la moins onéreuse, mais c'est aussi la plus lente et la moins performante.
La remarque d' @al1fch est judicieuse, quand les compteurs sont présents pourquoi passer par du logiciel, plus lent de par son principe : impossibilité de paralléliser des ordres comme on peut le faire en électronique.
Sans cela comment expliquer que malgrè un cout plus élevé, les autres fabricants de micro continuent à concevoir et implanter des blocs d'électronique à l'intérieur de leurs micros.

Il ne faut pas se laisser impressionner par la très haute fréquence d'horloge des micro espressif.
Un digitalWrite avec un ESP32 est certes plus rapide qu'avec un atmega328p mais absolument pas dans le rapport des fréquences horloges.

Mon "tout petit avis" :

  1. S'il n'y a pas de Wifi ni de bluetooth dans le projet, un ESP32 n'est pas forcément la meilleure solution même si le prix est interressant..
  2. De toute façon un vrai ARM 32 bits sera moins simple à utiliser qu'un avr 8 bits.

Merci pour la recherche !

Je me sens déjà moins seul puisque apparemment pas mal d'autres rencontrent ce problème et n'ont pas trouvé de solution fiable.

Je ne pense pas que ce soit un problème de fronts raides, j'ai ajouté un "nettoyage" par soft.
On voit très bien que le compteur s'incrémente à chaque front.

Je pourrais bien sûr tricher et décrémenter de 1, mais ce n'est pas sérieux. :smiley:

Quand on voit le nombre de bugs connus autour de cet ESP32, on peut commencer à douter de tout !

Il y est fait mention d'un bug sur la gestion des interruptions, mais uniquement dans le cas de 2 pins utilisées dans le même groupe.
Le bug que je rencontre est différent.

Merci,

Merci pour ces explications sur Espressif.

Je pensais que les interruptions étaient justement gérées principalement en hard.

Malheureusement, mon projet, une station météo LoRa, utilise le LoRa et le WiFi.

Je vais tenter PCNT, mais ça m'a l'air bien compliqué.. :smiley:

Cordialement,

C'est vrai avec Microchip, STMicro et d'autres équivalents.

J'ai lu (hier) que STMicro avait des produits Lora et SigFox mais pas WiFi.

Le RP2040 picoW est doté de WiFi (produit extérieur de concepteur connu).

Très souvent on voit des cartes en deux modules : un module microcontroleur associé avec un module spécialisé Wifi.
Je n'ai jamais testé, n'ayant sur le WiFi qu'une curiosité, mais c'est peut-être qu'il y a une raison.

Bonjour

Ayant rappelé l'existence du bloc de compteurs PCNT (Pulse counter) dans les ESP32, il aurait été cavalier de ne pas mentionner un exemple basique d'utilisation :wink:

Faute, à ce jour, de bibliothèque simple de style Arduino pour gérer ces compteurs hardware (autre qu'une bibliothèque ciblant les encodeurs en quadrature) voici un exemple basique utilisant le driver pcnt.h fourni par Espressif dans le SDK acompagnant tout core ESP32 pour Arduino, Doc Espressif

Fonction de l'exemple : Comptage sur GPIO15 d'implusions produites par GPIO22, carte utilisée LOLIN 32
L'état du compteur , qui tourne tout seul dans son coin, est récupéré par polling dans loop()


/* ESP32 : Exemple  d'utilisation basique d'un des compteurs 16 bits PCNT

 en l'absence de bibliothèque simple à ce jour,  utiisation directe du driver  'pcnt.h'
 fourni par Espressif dans le SDK  accompagnant le core ESP32
 
 Relier GPIO22 (sortie de paquets d'impulsions) à GPIO15 (entrée du compteur)
 Non traités : interruption à chaque débordement du compteur , changement de sens de comptage à  chaud....etc...

d'après  https://github.com/espressif/arduino-esp32/issues/6312
et https://github.com/espressif/arduino-esp32/issues/8244

al1fch 06/2023
*/

#include "Arduino.h"
#include "driver/pcnt.h"

int16_t count = 0;    ///

void setup() {
e
    pcnt_config_t pcnt_config = {
        .pulse_gpio_num = GPIO_NUM_15,  // GPIO entrée comptage ou décomptage
        .ctrl_gpio_num = PCNT_PIN_NOT_USED, // éventuel GPIO annexe
        .lctrl_mode = PCNT_MODE_KEEP,
        .hctrl_mode = PCNT_MODE_KEEP,
        .pos_mode = PCNT_COUNT_DIS,  // front montant inactif
        .neg_mode = PCNT_COUNT_INC,  //  INC sur front descdeant , DEC pour décompter
        .counter_h_lim = 32767,
        .counter_l_lim = -32768,
        .unit = PCNT_UNIT_0,
        .channel = PCNT_CHANNEL_0,
    };

    pcnt_unit_config(&pcnt_config); 
    pcnt_set_filter_value(PCNT_UNIT_0, 100);  //élimination glitches < 100ms 
    pcnt_filter_enable(PCNT_UNIT_0);
    pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_H_LIM);
    pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_0);
    pcnt_counter_pause(PCNT_UNIT_0);
    pcnt_counter_clear(PCNT_UNIT_0); // semble  indispensable de fait  pour lancer le compteur
    pcnt_counter_resume(PCNT_UNIT_0);

    Serial.begin(115200);
    pinMode(22, OUTPUT);
}

void loop() {
    for (int i = 0; i < 100; i++) {
        digitalWrite(22, HIGH);
        delay(1);
        digitalWrite(22, LOW);
        delay(1);
    }

    delay(1000);

    pcnt_get_counter_value(PCNT_UNIT_0, &count); //
    Serial.println(count); //

}

:point_right:Pour info : PCNT est exploité ici dans une réaisation de fréquencemetre 40MHZ

N.B L'utilsation des compteurs PCNT des ESP32 se simplifie grandement si on sous-traite leur configuration à la bibliothèque ESP32Encoder utilisée ici en mode SingleEdge :wink:

// compteur PCNT des ESP32  al1fch 06/2023
// selon  l'exemple  SimpleEncoderDemo de la biliohèque ESP32Encoder

#include <ESP32Encoder.h>  // https://github.com/madhephaestus/ESP32Encoder.git

#define SENS 15   // entrée définissant le sens de comptage
#define PULSE 25  // entrée du compteur

ESP32Encoder compteur;

void setup() {
  compteur.attachSingleEdge(PULSE, SENS);
  compteur.setFilter(100); // filtre 100mS
  compteur.setCount(0);
  
  Serial.begin(115200);
  pinMode(22, OUTPUT);  // génération d'implusions pour tester le comptage
}

void loop() {

  for (int i = 0; i < 10; i++) {  // génération de n impulsions pour test
    digitalWrite(22, HIGH);
    delay(1);
    digitalWrite(22, LOW);
    delay(1);
  }

  delay(1000);

  long newPosition = compteur.getCount();
  Serial.println(newPosition);
}

Question hors sujet déplacée
A post was split to a new topic: Question sur les interruptions

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