Compteur d'impulsion avec attachInterrupt

Bonjour à tous,

Je souhaite mesurer une impulsion sortant d'une prise d'un véhicule afin de pouvoir compter les impulsions en 1 secondes.

J'ai pris des mesures à l’oscilloscope et voici le signal qui sort du fil ( sans être branché sur la carte Uno ) :

7Vcc stable lorsque le véhicule est démarré et stationnaire.
Chaque impulsion ramène la tension à 0Vcc et le signal est propre.


Lorsque je branche ce fil sur la borne 2 de ma carte Uno en utilisant la PULLUP interne ( carte relié à la masse du véhicule qui émet le signal ) , le signal n'est plus bon du tout, je pense que les pins digitaux ne prennent que 5V maxi ( résistance à installer en amont ) ?

Voici le bout de programme que j'ai mis en place pour lire ce signal :


const byte pinImpulsionTracteur = 2;
volatile int compteurImpulsion = 0;
unsigned long tempsActuel = millis();
unsigned long dernierTemps = 0;

void setup() {
  
  Serial.begin(115200);
  pinMode(pinImpulsionTracteur, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(pinImpulsionTracteur), comptageImpulsion, FALLING);

}

void loop() {

  unsigned long tempsActuel = millis();
  
  if(tempsActuel - dernierTemps >= 1000 ) {
    Serial.println(compteurImpulsion);
    compteurImpulsion = 0;
    dernierTemps = tempsActuel;    
  }

}

void comptageImpulsion() {
  compteurImpulsion++;
}

Avez un éclaircissement à m'apporter ?

Vos pins ne supportent pas 7V …. Vous allez griller la pin ou le 328P du UNO

Il faut un pont diviseur de tension ou un module d’adaptation (rapide si les signaux fluctuent rapidement)

J'ai trouvé la solution pour tomber à 5Vcc avec un diviseur de tension oui :

J'ai réussi à avoir un retour de ma variable Serial.println(compteurImpulsion); par contre, je ne comprends pas, elle s'incrémente sans revenir à 0.

if(tempsActuel - dernierTemps >= 1000 ) {
    Serial.println(compteurImpulsion);
    compteurImpulsion = 0; // ==> devrait remettre à 0 ma variable non ?
    dernierTemps = tempsActuel;    
  }

Une idée sur l'erreur ?

Bonjour udina

J'ai essayé ton programme, ta variable vient bien à zéro toutes les secondes.

Cordialement
jpbbricole

Sur mon moniteur série, lorsque j'ai mis les roues à tourner de manière stable, ça a démarré à 0 et à chaque ligne, il m'incrémentait la valeur et lorsque j'ai arrêté les roues, il n'a pas pour autant remis à 0 ma valeur.

Essaies ici:

Est ce que ton programme n'est pas le même que celui du post#1?

Merci pour la simulation, j'oscille bien entre 1402 et 1405 sur 10 lignes, je refais un test demain matin et je t'enverrais le screen du moniteur série. Le fait d'être un poil plus fort en tension ( 5.1V ) n'engendre pas de soucis sur le pin 2 ?

Non, je doute :wink:

Affaire à suivre, merci à toi

Il faut une section critique dans la loop quand vous accédez à la variable partagée avec l’interruption.

Par exemple dans la loop quand il est temps d’aller triturer le compteur vous commencez par désactiver les interruptions vous copiez le compteur existant et le remettez à zéro ainsi que le chrono à millis() et vous réactivez les interruptions et travaillez à l’affichage avec la copie.

Si vous ne faites pas cela rien n’empêche que l’interruption arrive au plus moment et modifie des octets pendant que la loop remettait à zéro le compteur par exemple

Merci à tous les deux, après test ce matin, j'avais toujours le problème sur le pin 2 de ma carte Uno qui n'a pas dû aimer être sous la tension de 7V avant que je mette en place le pont diviseur de tension.
En changeant par le pin 3 de la carte, tout est rentré dans l'ordre.
Dans un second temps, je souhaiterais analyser cette information vitesse avec une carte Arduino Nano Every ABX00028 qui serait relié à une carte Uno en UART RX / TX

Les pins digitals peuvent il faire de l'interruption sur ce genre de modèle ?

pourquoi avez vous besoin de deux cartes ? ça rajoute en complexité

Car j'ai une carte Uno qui contient déjà un code avec une gestion qui a besoin de tourner sans rajouter d'interruption.
Le code se trouve au post#22 du sujet suivant :
https://forum.arduino.cc/t/potentiometre-pwm-a-deux-canaux/1316572/21

Ca me permettra de rajouter une sécurité ou lorsque le nombre d'impulsion arrive à une certaine valeur, le véhicule s'arrête par sécurité.

Vous auriez 3 cartes alors ?? (et ce code au post 22 pourrait avoir des interruptions sans aucun souci)

Non, il n'y aurait que deux carte, la Uno principal ( réceptrice du UART RXT / TX ) pour la gestion du véhicule et une carte Nano ( émettrice de la variable de vitesse ). Je pensais que la surveillance des boutons par la bibliothèque OneButton avait besoin d'une priorité sur la loop, c'est pourquoi j'ai pensé qu'il fallait deux cartes. Je vais tenter d'intégrer dans mon programme principal l'interruption voir ce que ça donne. Merci pour l'informtion

non la bibliothèque OneButton fait du polling, quand vous faites

ça va simplement faire un digitalRead() pour voir l'état de la pin et réagir en conséquence en déclenchant le callback si nécessaire.

Même à 16MHz c'est rapide et pour l'appui d'un bouton par un humain, on parle de toutes façons en dizaines de millisecondes donc l'arduino a le temps de faire beaucoup d'autres choses que de surveiller les boutons.

Vous pouvez à mon avis compter vos impulsions, surveiller les boutons et émettre la vitesse sur UART de temps en temps sans aucun souci sur votre UNO.

1 Like