(Résolu) Interruption + Serial.write () --> Problème

Bonjour à tous,

Me revoilà avec un nouveau problème :grin:

J'ai un programme qui doit envoyer des données en série à un certain moment dans le loop. J'ai programmé un bouton poussoir en mode switch (on/off) avec une interruption pour que l'état puisse être lu à n'importe-quel moment.

Le but est d'envoyer par le port série, l'état du switch (on ou off) et en même temps d'allumer une LED si l'état est sur ON (pour vérifier le bon fonctionnement de l'interruption). Mais il se trouve que l'interruption ne fonctionne pas quand il y a un Serial.write qui traine dans le programme... Rien ne se passe. Si je retire le Serial.write, la LED s'allume et s'éteint comme il faut.

J'ai lu que l'interruption pouvait perturber le fonctionnement de la lecture en série, mais je n'ai rien vu à propos de l'écriture. Quelqu'un aurait une idée ? Je mettrai le programme si nécessaire.

Merci :wink:

Code ?

Bon ben apparemment c'est nécessaire :stuck_out_tongue:

const int BP = 5;
const int LED = 6;

// switch on/off

int reading_BP;
int state_BP = HIGH;
int previous_BP = HIGH;


void setup () {

pinMode (BP, INPUT);
pinMode (LED, OUTPUT);

digitalWrite (BP, HIGH); // actication pull-up
digitalWrite (LED, HIGH);

Serial1.begin (9600);

attachInterrupt (2, interrupt, LOW);

}

void loop () {

if (state_BP == LOW) {
digitalWrite (LED, LOW);
}
else { 
digitalWrite (LED, HIGH); }

Serial1.write (state_BP);

}

void interrupt () {

  // switch on/off
  
reading_BP = digitalRead (BP);

if (reading_BP == LOW && previous_BP == HIGH) {
    if (state_BP == HIGH)
    state_BP = LOW;
    else 
    state_BP = HIGH;
  }
  previous_BP = reading_BP;
  
}

Beaucoup de code inutile qui pourrait être simplifié.

Si je comprend bien tu échantillonnes la valeur du bouton poussoir à chaque interruption.
Quand tu détectes un front descendant, tu inverses l'état de la variable state_BP.

Il est préférable de ne pas oublier les pinMode( ); c'est plus fiable.

Pour l'instant je ne vois aucune raison pour laquelle le Serial1.write() devrait changer le fonctionnement du code.

Mega ou Leonardo ?

Qu'est-ce qui génère l'interruption ?

J'ai oublié de copier les pinMode, mais elles sont bien dans le programme, au temps pour moi :wink:

C'est bien ça pour le bouton poussoir, oui.

C'est la Mega et c'est le bouton poussoir qui génère l'interruption.

Par contre, comment je pourrais plus simplifier le code ?

Evite de modifier le code préalablement publié, les commentaires que l'on a fait perdent leur sens et ceux qui relisent derrière n'y comprennent rien.

1erement, en oubliant que c'est bouton poussoir qui déclenche l'interruption, le code suivant fait la même chose :

void loop () {
  digitalWrite (LED, state_BP);
  Serial1.write (state_BP);
}

void interrupt () {
  // switch on/off
  reading_BP = digitalRead (BP);
  if (reading_BP == LOW && previous_BP == HIGH) {
    state_BP = !state_BP;
  }
  previous_BP = reading_BP;
}

2emement, tu as choisit une interruption sur niveau bas

attachInterrupt (2, interrupt, LOW);

Donc le CPU part en continu en interruption tant que le bouton est en bas.
Ca ne sert à rien.
Utilise plutot FALLING et ta routine d'interruption devient :

void interrupt () {
  state_BP = !state_BP;
}

Tu n'a plus besoin de détecter le front descendant puis que le mode FALLING le fait pour toi.

Donc il est fort probable que ton interruption ne marche pas bien a cause de cela

Si j'ai bien tout compris, le code devient alors :

const int BP = 30;
const int LED = 44;

int state_BP = HIGH;


void setup () {

  pinMode (BP, INPUT);
  pinMode (LED, OUTPUT);

digitalWrite (LED, HIGH);

Serial1.begin (9600);

attachInterrupt (3, interrupt, FALLING);

}

void loop () {

 digitalWrite (LED, state_BP);
 Serial1.write (state_BP);
  
}

void interrupt () {
  
state_BP = !state_BP;
  
}

Mais rien ne se passe :confused: Le mode falling, je l'avais déjà essayé plusieurs fois mais ça n'a jamais fonctionné.. Et ce avec la Uno et la Mega.

Comment est branché le poussoir à l'Arduino ?

Poussoir entre GND et pin 3 ?
Tu as oublié le pullup :
pinMode( 3, INPUT_PULLUP ); ou pinMode( BP, INPUT_PULLUP );

Il y a aussi le fait que le poussoir génère certainement des rebonds ce qui rend la méthode pas forcément très pratique.

Le tout est câblé de la façon suivante :

BP à la pin 30 et l'interrupt à la pin 21 (interrupt n°3). Mais là avec le programme je n'ai pas besoin de la pin 21 de toute façon, donc le BP n'agit que sur l'interruption.

C'est bon !

C'est très très con mais il s'agissait d'un petit fil sur ma breadboard qui reliait constamment la pin interrupt à la masse... Je ne l'avais pas vu.. Même en ayant vérifié plusieurs fois il m'est passé sous les yeux !

Enfin ma question n'aura pas été inutile non plus, j'ai pu apprendre comment largement simplifier mon code, merci beaucoup :wink: