Interruption

Toujours sur mon projet d’affichage de température et distance sur un LCD…
Mon objectif est d’afficher la température et l’humidité toutes les secondes, et de lancer une mesure de distance par ultrasons par appui sur un bouton.
Donc, je voudrais faire une interruption lors de l’appui sur le bouton et lancer la mesure.

Bien sûr, sinon je ne serais pas en train d’écrire ça, ça ne marche pas !
Je pense que chaque fonction marche bien séparément, c’est la gestion de l’interruption (une première pour moi) qui doit poser problème.
La mesure se lance directement sans que j’appuie sur le bouton.

Pouvez-vous m’aider ? Listing joint…

Telemetre_temperature.ino (2.8 KB)

lesept: Mon objectif est d'afficher la température et l'humidité toutes les secondes,...

Juste une petite question : quelle la pertinence de vouloir afficher des valeurs toutes les secondes sachant que la constante de temps de ce type de capteur est de l'ordre de la minute ?

Cordialement.

Pierre

Bonjour,

Il est inutile d'utiliser une interruption pour traiter un bouton. Si le bouton est pris en compte avec quelques ms de retard, l'utilisateur n'y verra absolument rien.

Plus grave: le traitement d'interruption doit être le plus court possible (typiquement on met à jour quelques variables). Toi tu fais un traitement interminable qui comporte des affichages et de plus fait appel à des fonctions qui utilisent des interruptions alors que les interruptions sont masquées.

N'utilises pas les interruptions pour ce bouton, il n'y en a pas besoin et ça fonctionnera beaucoup mieux.

D'accord, je voulais surtout apprendre à faire des interruptions. Pour que ce soit court, je peux simplement mettre à jour une variable commune et la tester dans la boucle principale pour lancer la mesure. Mais c'est déjà ce que je faisais sans l'interruption, en testant le niveau de la pin du bouton... Donc, intérêt moyen.

OK, merci de vos réponses.

Effectivement si c'est pour apprendre tu peux positionner un flag en interruption quand on appuie sur le bouton et le tester dans la loop().

J’ai suivi vos avis et j’ai fait simple, avec une détection de l’appui au sein d’une boucle avec un temps contrôlé par millis(). çà fonctionne bien. Merci encore !

Finalement, ça ne fonctionne pas si bien : au bout d’un moment, l’afficheur se met à afficher la température en continu et ne laisse plus de ressource pour capter le bouton. Où est mon erreur ?
Voici le code de l’attente du bouton :

// Surveillance du bouton pendant 10 secondes
  int Attente = 10000;
  int Temps_debut = millis();
  while (millis() - Temps_debut < Attente) {
    buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH) { 
      Mesure_distance ();
      Affiche_LCD(ligne1,ligne2); }
    delay(100); // Pour éviter de saturer le processeur
  }

Merci de votre aide et votre indulgence pour le débutant que je suis…

Bonjour,

Je ne vois pas bien ce que tu veux faire avec ton while. Il suffit de tester si le bouton a changé d'état et si il a été appuyé

  static int buttonStatePrec = LOW;
  buttonState = digitalRead(buttonPin);
  if (buttonState != buttonStatePrec)
  {
    // le bouton a changé d'état
    buttonStatePrec = buttonState;
    if (buttonState == HIGH)
    {
      // le bouton a été appuyé
      Mesure_distance();
    }

C’est ce que j’ai fait au début, mais je trouvais que ça manquait de fluidité. L’appui sur le bouton n’est pas pris au vol, il faut appuyer un certain temps avant qu’il fasse l’affichage.
Ce que je veux faire c’est : afficher température et humidité sur le LCD en continu, et lorsqu’on appuie sur le bouton, afficher la distance mesurée pendant 2 secondes, puis revenir à l’affichage de la température et de l’humidité.
Mais si j’affiche vraiment en continu, l’afficheur va très vite et perd du contraste. Donc j’ai mis une temporisation (un delay) mais si j’appuie sur le bouton au moment du delay, l’appui n’est pas attrapé, donc je dois appuyer longtemps.
D’où le while.

Tel quel, ça fonctionne bien, pendant une quarantaine de secondes, et puis il semble que quelque chose se passe et je retombe dans mon problème précédent : l’afficheur affiche a toute vitesse, le contraste chute et l’appui sur le bouton n’est pas attrapé. Et je ne comprends pas pourquoi ça change.

En attaché, le programme complet…

Telemetre_DHT11.ino (3.16 KB)

Interdit d'utiliser des delay : c'est une fonction bloquante. Utilise millis() voir l'exemple blink without delay

delay est à réserver pour la gestion du matériel quand un composant électronique met un temps [u]quantifié[/u] pour répondre, dans ce cas l'utilisation de delay est justifiée.

68tjs: Interdit d'utiliser des delay : c'est une fonction bloquante. Utilise millis() voir l'exemple blink without delay

delay est à réserver pour la gestion du matériel quand un composant électronique met un temps [u]quantifié[/u] pour répondre, dans ce cas l'utilisation de delay est justifiée.

Ça ne m'aide pas, c'est déjà ce que je fais. Regarde mon listing 2-3 posts plus haut ...

J'ai trouvé, j'ai utilisé des int au lieu de long :

  int Attente = 10000;
  int Temps_debut = millis();

il fallait faire :

  unsigned long Attente = 10000;
  unsigned long Temps_debut = millis();

Maintenant, ça marche comme je veux. Je vais tester le DHT22 car je viens de le recevoir...