Interruption intempestive sur D3 [Résolu]

Bonjour à tous !

Ce bout de code ci-après, extrait d'un programme de 800 lignes environ, est celui qui pose problème.

L'électronique associée à la platine Arduino Nano

  • Un bouton-poussoir relié, via un trigger, à la pin d'interruption D3.
  • La DEL D13 intégrée à la platine Arduino.

Le problème
Une fois le programme lancé, un appui sur le bouton envoie (via un trigger) du 5V à la pin d'interruption D3 (interruption n°1).

Depuis le loop(), le programme passe alors de 'runStandByMode()' à 'runActivatedMode()'.

Après un temps variable (de 20 minutes à 71 minutes), une interruption est activée sans raison apparente et le programme repasse alors de 'runActivatedMode()' à 'runStandByMode()'.

La platine testée avec une alimentation prise du PC ou spécifique change systématiquement d'état.
La platine n'est pas dans un environnement électriquement perturbé.

Un déclenchement intempestif pouvant se produire après 60 minutes, j'ai déjà passé beaucoup de temps à tenter de cerner et de trouver le problème.

Ma demande d'aide
Je ne vois vraiment plus où peut se trouver le bug.
Merci pour votre aide.

Le code (extrait fonctionnel)
Nota : les 'Serial.print' servent pour la recherche du bug à afficher les horodatages d'activation des deux fonctions appelées.



#define STDBY_MODE 2
#define ACTIVATED_MODE 5
volatile int menuSelected = STDBY_MODE;
volatile bool isCentralUnitActivated;
const int LED_PIN = 13; 

void setup() {
  Serial.begin (9600); 
  pinMode(LED_PIN, OUTPUT); 
  digitalWrite(LED_PIN, LOW);                              
  attachInterrupt(1, setCentralUnitStatus, RISING);  // La fonction 'setCentralUnitStatus' est appelée                              
  isCentralUnitActivated = false;
}


void loop() {
  if (isCentralUnitActivated == false) {
      runStandByMode();
  }
  else { 
    runActivatedMode(); 
  }
}


void runStandByMode() {
  digitalWrite(LED_PIN, LOW); 
  Serial.print("Entrée de StandByMode : ");
  Serial.println(millis());
  while (menuSelected == STDBY_MODE) 
  {                             
    // Code supprimé remplacé par delay(50) pour ce test.
    delay(50);  
  }
}


void runActivatedMode() {
  unsigned long currentTime = 0;
  unsigned long previousTime = 0;
  digitalWrite(LED_PIN, LOW);
  bool ledState = false;
  Serial.print("Entrée de ActivatedMode : ");
  Serial.println(millis());
  while (menuSelected == ACTIVATED_MODE) 
  {  
    // Normalement, du taf ici...
    // ...et clignotement d'une DEL d'affichage d'état.
    currentTime = millis();
    if((currentTime - previousTime) > 1000)
    {
      previousTime = currentTime;
      ledState = !ledState;
      digitalWrite(LED_PIN, ledState);
    }
  }
  Serial.print("Sortie de ActivatedMode : ");
  Serial.println(millis());
  menuSelected = STDBY_MODE;
}


// Fonction appelée par l'interruption n°1.
void setCentralUnitStatus() 
{
  if (isCentralUnitActivated == false) {
    Serial.print("menuSelected = ACTIVATED_MODE : ");
    Serial.println(millis());
    menuSelected = ACTIVATED_MODE;
  }
  else {
    Serial.print("menuSelected = STDBY_MODE : ");
    Serial.println(millis());
    menuSelected = STDBY_MODE;
  }
  isCentralUnitActivated = !isCentralUnitActivated;
}


ça veut dire quoi? c'est câblé comment?

comment êtes vous sûr que le souci n'est pas ailleurs? c'est statistiquement le cas... postez tout le code.

PS/

Si previousTime n'est pas statique vous n'allez pas mémoriser sa valeur

@ J-M-L
ça veut dire quoi? c'est câblé comment?
Le bouton poussoir est relié à l'entrée d'un trigger de Schmitt (CD 40106). La sortie est reliée à la pin D2.

postez tout le code
Tout le code posant problème est celui posté.

Si previousTime n'est pas statique vous n'allez pas mémoriser sa valeur
Ah, peut-être bien que le problème viendrait de là !
Je ne pourrais toutefois tester votre remarque que demain.

Merci pour cette information ; je reviens dès les nouveaux tests avec l'ajout static effectués.

jetez un oeil sur les recommandations listées dans "Les bonnes pratiques du Forum Francophone” pour voir les éléments à fournir pour améliorer vos chances d'avoir des réponses pertinentes

vous n'avez pas démontré que le problème vient de là. Un débordement de tableau qui vient mettre le bazar dans la mémoire et toucher votre variable par exemple, un reboot intempestif dû à un bug etc..

On ne sait toujours pas comment c'est câblé, un schéma c'est mieux...

Bonjour,

Un simple trigger de Schmitt ne sert pas à grand chose (pour ne pas dire à rien) pour éviter les rebonds. D'autant plus que si on suit ce que tu dis, il n'y a ni pullup ni pulldown.
Il est rarement nécessaire de traiter les boutons en interruption.

@J-M-L
Il n'y a aucun autre code pouvant générer un défaut. Le code présenté génère lui-même le problème. C'est la raison pour laquelle je n'ai pas trouvé de solution.

@kamill
L'entrée du trigger comprend un circuit RC (donc anti-rebonds).
L'utilisation d'une interruption m'est (apparemment) apparue comme nécessaire par le fait que le code boucle sur un while et c'est (je pense) une façon rapide de quitter cette boucle.

Je vais tout d'abord tester l'ajout de 'static' de J-M-L !

Schéma du trigger utilisé
Capture d’écran 2021-08-16 à 13.35.52

J'ai eu le temps de faire le test avant de partir.
L'ajout de 'static' ne résout pas le problème.

Je vais donc modifier les connexions et supprimer l'interruption.

Merci pour votre aide.

Pour un suivi à l'attention de J-M-L et à kamill qui ont eu la gentillesse de considérer mon problème.

Le défaut venait du trigger (40106) qui, pour une raison encore inconnue - que je tenterai de trouver ultérieurement - présentait une sortie instable.

Peut être que le condensateur du RC est trop faible (47K, 470 nF).
J'ai supprimé ce circuit et utilisé un debounce logiciel...

Merci pour votre aide.

OK merci du suivi... ah ces composants c'est toujours plus compliqué que le logiciel à débuguer !!!

. ah ces composants c'est toujours plus compliqué que le logiciel à débuguer !!!

Sans oscilloscope , oui !