Détecter l'état d'un bouton poussoir à tout moment

Bonjour,

Je suis débutant sur Arduino et j'ai essayé un petit projet que j'ai vu sur internet.

En fait j'ai 12 LEDs et plusieurs effets (par exemple un effet qui fait clignoter toutes les LEDs, un autre qui les fait s'allumer une par une etc...) et chaque effets se font chacun à la suite et en boucle.
Maintenant, j'ai ajouté un bouton poussoir qui me permet de changer d'effet quand j'appuie dessus, et tant que j'appuie pas ça reste sur le même effet en boucle.
Sauf que la lecture de l'état du bouton poussoir ne se fait qu'à la fin de l'effet, entre le moment où il se termine et le moment où il recommence. Et donc je voulais savoir si c'est possible que l'état du bouton soit lu en continu pour pouvoir changer d'effet à tout moment, et ne pas devoir attendre que l'effet d'avant se termine?

Merci d'avance pour votre aide.

Bonjour,

Oui, c'est possible :grin:

kamill:
Bonjour,

Oui, c’est possible :grin:

D’accord merci!
Est-ce que vous auriez un lien vers un programme qui l’utilise? ou un tuto? J’ai cherché mais j’ai rien trouvé…

Il faut deja supprimé tous les delay() de votre code
ensuite vous pourrez vous occupé de l'ecoute du pin boutton
regarder https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay

@J4l13n -> vrai, mais cela implique de tout réécrire depuis le début.

Sans réécrire c'est sans doute plus simple avec une variable "suite" mise à false quand on change d'effet et qui est mise à true quand on appuie sur le bouton.
Pour que le bouton soit lu pendant un delay, il faut alors passer par attachinterrupt: un appui sur le bouton déclenche une interruption qui met suite à true

Mets ton code pour qu'on puisse te guider.

#define t   30
#define t1  20
#define t2  100
#define t3  50

int j;
int k;
int i;
int bouton=1;
int etat;
int effet;

void setup() {
  // set up pins 2 to 13 as outputs
  for (int i = 2; i <= 13; i++) {
    pinMode(i, OUTPUT);
  }
  pinMode(1, INPUT);
  effet=1;
}

void effect1()
{
  for(int i=2;i<13; i=i+2){
  digitalWrite(i,HIGH);
  delay(40);
  }
  for(int i=13;i>2; i=i-2){
  digitalWrite(i,HIGH);
  delay(40);
  }
  for(int i=2;i<13; i=i+2){
  digitalWrite(i,LOW);
  delay(40);
  }
  for(int i=13;i>2; i=i-2){
  digitalWrite(i,LOW);
  delay(40);
  }
}

void effect2()
{
  for(int i=2;i<14; i++){
  digitalWrite(i,HIGH);
  delay(20);
  digitalWrite(i,LOW);
  delay(20);
  }
}

void effect3()
{
  for(int i=2;i<14; i++){
  digitalWrite(i,HIGH);
  delay(20);
  digitalWrite(i,LOW);
  delay(20);
  }
  for(int i=13;i>1; i--){
  digitalWrite(i,HIGH);
  delay(20);
  digitalWrite(i,LOW);
  delay(20);
  }
}

void effect4()
{
  j=8;
  for(int i=7;i>1; i--){
  digitalWrite(i,HIGH);
  digitalWrite(j,HIGH);
  delay(50);
  digitalWrite(i,LOW);
  digitalWrite(j,LOW);
  delay(50);
  j=j+1;
  }
  
}

void effect5()
{
  j=8;
  for(int i=7;i>1; i--){
  digitalWrite(i,HIGH);
  digitalWrite(j,HIGH);
  delay(50);
  j=j+1;
  }
  j=13;
  for(int i=2;i<8; i++){
  digitalWrite(i,LOW);
  digitalWrite(j,LOW);
  delay(50);
  j=j-1;  
  }
}

void effect6()
{
  for(int k=1;k<5; k++){
    j=3;
    for(int i=2;i<14; i+=2){
    digitalWrite(i,HIGH);
    digitalWrite(j,LOW);
    j=j+2;
    }
    delay(100);
    j=3;
    for(int i=2;i<14; i+=2){
    digitalWrite(i,LOW);
    digitalWrite(j,HIGH);
    j=j+2;
    }
    delay(100);
  }
  for(int i=2;i<14; i++){
    digitalWrite(i,LOW);
  }
    delay(300);
  for(int i=2;i<14; i++){
    digitalWrite(i,HIGH);
  }
  delay(300);
  for(int i=2;i<14; i++){
    digitalWrite(i,LOW);
  }
    delay(300);
  for(int i=2;i<14; i++){
    digitalWrite(i,HIGH);
  }
  delay(300);
    for(int i=2;i<14; i++){
    digitalWrite(i,LOW);
  }
    delay(300);
  for(int i=2;i<14; i++){
    digitalWrite(i,HIGH);
  }
  delay(300);
  for(int i=2;i<14; i++){
    digitalWrite(i,LOW);
  }
  delay(300);   
}

void effect7()
{
  if(k<2)
  {
  j=13;
  for(int i=2; i<13;i=i+2){
    digitalWrite(i, HIGH);
    digitalWrite(j,HIGH);
    delay(70);
    digitalWrite(i, LOW);
    digitalWrite(j,LOW);
    j=j-2;
  }
  }
  else{}
  
  j=5;
  for(int i=10; i>1;i=i-2){
    digitalWrite(i, HIGH);
    digitalWrite(j,HIGH);
    delay(70);
    digitalWrite(i, LOW);
    digitalWrite(j,LOW);
    j=j+2;
  }
  j=11;
  for(int i=4; i<13;i=i+2){
    digitalWrite(i, HIGH);
    digitalWrite(j,HIGH);
    delay(70);
    digitalWrite(i, LOW);
    digitalWrite(j,LOW);
    j=j-2;
   }
   
   k=5;
}

void effect8()
{
  j=13;
  k=2;
  for(int i=2; i<14;i++){
    while(k<j+1){
      digitalWrite(k,HIGH);
      delay(50);
      if(k!=j){
      digitalWrite(k,LOW);
      }
      else {}
      k=k+1;
      }
    digitalWrite(j,HIGH);
    delay(50);
    j=j-1;
    k=2;
    }
  for(int i=2; i<14;i++){
    digitalWrite(i,LOW);
    delay(50);
  }

  //pareil dans l'autre sens
  j=2;
  k=13;
  for(int i=2; i<14;i++){
    while(k>j-1){
      digitalWrite(k,HIGH);
      delay(50);
      digitalWrite(k,LOW);
      k=k-1;
      }
    digitalWrite(j,HIGH);
    delay(50);
    j=j+1;
    k=13;
    }
  for(int i=13; i>1;i--){
    digitalWrite(i,LOW);
    delay(50);
  }
}

void effect9(){
  for (int i=2; i<14; i++){
    digitalWrite(i, HIGH);
  }
  delay(500);
}


void loop()
{
 etat = digitalRead(bouton);
 if (etat==LOW){
  effet++;
  }
 else{}
 
 if (effet==1){
  effect1();}
 else if (effet==2){
  effect2();}
 else if (effet==3){
  effect3();}  
 else if (effet==4){
  effect4();}
 else if (effet==5){
  effect5();}
 else if (effet==6){
  effect6();}
 else if (effet==7){
  effect7();}
 else if (effet==8){
  effect8();}
 else if (effet==9){
  effect9();}
 else{
  effet=0;}
}

Merci pour vos réponses. Voici mon code.
C’est vrai que tout réécrire serait un peu long.

Je viens justement de voir la fonction attachInterrupt sur internet, par contre je ne suis pas sûr d’avoir compris la méthode avec une variable mise à false et true…

Comme indiqué dans les réponses tu peux réécrire en supprimant les délais et en réécrivant le code sous forme d’automate.
Mais ça risque d’être compliqué et (très) fastidieux.

Je te propose une méthode qui implique le minimum de modifications sur le programme.
Il s’agit de tester les boutons pendant les delay(). Pour cela on remplace le delay() par une fonction qui fait effectue un delay tout en testant le bouton. Si le bouton est enfoncé on effectue un long jump qui retourne au début de la loop().

#include <setjmp.h>

#define t   30
#define t1  20
#define t2  100
#define t3  50

int j;
int k;
int i;
int bouton = 1;
int etat;
int effet;

// fonction pour remplacer delay()
#define delay(d) _delay(d)

jmp_buf jBuffer;

void _delay(unsigned long d)
{
  for (unsigned long start = millis(); millis() - start < d;)
  {
    if (digitalRead(bouton) == LOW)
      longjmp(jBuffer, 1);  // retourne en début de loop
  }
}

void setup() {
  // set up pins 2 to 13 as outputs
  for (int i = 2; i <= 13; i++) {
    pinMode(i, OUTPUT);
  }
  pinMode(bouton, INPUT_PULLUP);
  effet = 1;
}

void effect1()
{
  for (int i = 2; i < 13; i = i + 2) {
    digitalWrite(i, HIGH);
    delay(40);
  }
  for (int i = 13; i > 2; i = i - 2) {
    digitalWrite(i, HIGH);
    delay(40);
  }
  for (int i = 2; i < 13; i = i + 2) {
    digitalWrite(i, LOW);
    delay(40);
  }
  for (int i = 13; i > 2; i = i - 2) {
    digitalWrite(i, LOW);
    delay(40);
  }
}

void effect2()
{
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, HIGH);
    delay(20);
    digitalWrite(i, LOW);
    delay(20);
  }
}

void effect3()
{
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, HIGH);
    delay(20);
    digitalWrite(i, LOW);
    delay(20);
  }
  for (int i = 13; i > 1; i--) {
    digitalWrite(i, HIGH);
    delay(20);
    digitalWrite(i, LOW);
    delay(20);
  }
}

void effect4()
{
  j = 8;
  for (int i = 7; i > 1; i--) {
    digitalWrite(i, HIGH);
    digitalWrite(j, HIGH);
    delay(50);
    digitalWrite(i, LOW);
    digitalWrite(j, LOW);
    delay(50);
    j = j + 1;
  }

}

void effect5()
{
  j = 8;
  for (int i = 7; i > 1; i--) {
    digitalWrite(i, HIGH);
    digitalWrite(j, HIGH);
    delay(50);
    j = j + 1;
  }
  j = 13;
  for (int i = 2; i < 8; i++) {
    digitalWrite(i, LOW);
    digitalWrite(j, LOW);
    delay(50);
    j = j - 1;
  }
}

void effect6()
{
  for (int k = 1; k < 5; k++) {
    j = 3;
    for (int i = 2; i < 14; i += 2) {
      digitalWrite(i, HIGH);
      digitalWrite(j, LOW);
      j = j + 2;
    }
    delay(100);
    j = 3;
    for (int i = 2; i < 14; i += 2) {
      digitalWrite(i, LOW);
      digitalWrite(j, HIGH);
      j = j + 2;
    }
    delay(100);
  }
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, LOW);
  }
  delay(300);
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, HIGH);
  }
  delay(300);
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, LOW);
  }
  delay(300);
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, HIGH);
  }
  delay(300);
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, LOW);
  }
  delay(300);
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, HIGH);
  }
  delay(300);
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, LOW);
  }
  delay(300);
}

void effect7()
{
  if (k < 2)
  {
    j = 13;
    for (int i = 2; i < 13; i = i + 2) {
      digitalWrite(i, HIGH);
      digitalWrite(j, HIGH);
      delay(70);
      digitalWrite(i, LOW);
      digitalWrite(j, LOW);
      j = j - 2;
    }
  }
  else {}

  j = 5;
  for (int i = 10; i > 1; i = i - 2) {
    digitalWrite(i, HIGH);
    digitalWrite(j, HIGH);
    delay(70);
    digitalWrite(i, LOW);
    digitalWrite(j, LOW);
    j = j + 2;
  }
  j = 11;
  for (int i = 4; i < 13; i = i + 2) {
    digitalWrite(i, HIGH);
    digitalWrite(j, HIGH);
    delay(70);
    digitalWrite(i, LOW);
    digitalWrite(j, LOW);
    j = j - 2;
  }

  k = 5;
}

void effect8()
{
  j = 13;
  k = 2;
  for (int i = 2; i < 14; i++) {
    while (k < j + 1) {
      digitalWrite(k, HIGH);
      delay(50);
      if (k != j) {
        digitalWrite(k, LOW);
      }
      else {}
      k = k + 1;
    }
    digitalWrite(j, HIGH);
    delay(50);
    j = j - 1;
    k = 2;
  }
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, LOW);
    delay(50);
  }

  //pareil dans l'autre sens
  j = 2;
  k = 13;
  for (int i = 2; i < 14; i++) {
    while (k > j - 1) {
      digitalWrite(k, HIGH);
      delay(50);
      digitalWrite(k, LOW);
      k = k - 1;
    }
    digitalWrite(j, HIGH);
    delay(50);
    j = j + 1;
    k = 13;
  }
  for (int i = 13; i > 1; i--) {
    digitalWrite(i, LOW);
    delay(50);
  }
}

void effect9() {
  for (int i = 2; i < 14; i++) {
    digitalWrite(i, HIGH);
  }
  delay(500);
}


void loop()
{
  int val = setjmp(jBuffer);  // on revient ici en cas d'appui
  etat = digitalRead(bouton);
  if (etat == LOW) {
    effet++;
    for (unsigned long start = millis(); millis() - start < 20; ); // anti rebond ne pas utiliser delay
    while (digitalRead(bouton) == LOW); // attente relachement
  }

  if (effet == 1) {
    effect1();
  }
  else if (effet == 2) {
    effect2();
  }
  else if (effet == 3) {
    effect3();
  }
  else if (effet == 4) {
    effect4();
  }
  else if (effet == 5) {
    effect5();
  }
  else if (effet == 6) {
    effect6();
  }
  else if (effet == 7) {
    effect7();
  }
  else if (effet == 8) {
    effect8();
  }
  else if (effet == 9) {
    effect9();
  }
  else {
    effet = 0;
  }
}

Il s’agit de tester les boutons pendant les delay(). Pour cela on remplace le delay() par une fonction qui fait effectue un delay tout en testant le bouton.

C’est sans doute plus simple à comprendre que les interruptions.

Mais pas forcément plus simple à comprendre avec des jmp qui ne sont pas dans l’esprit des blocs du C

Il est possible de faire un mix intéressant, faire une fonction _delay():

void _delay(unsigned long d)
{
  start = millis();
  while (millis() - start < d)
  {
    if (digitalRead(bouton) == LOW)
      suite = true;
  }
}

Merci pour toutes vos réponses.
Le code de kamill marche parfaitement!

Maintenant il me reste plus qu'à le comprendre :slight_smile:

Et merci vileroi pour ta proposition, je vais voir si je peux l'utiliser aussi.

Bonne soirée

En général quand on a un code qui fonctionne, on a intérêt à ne plus y toucher! Les deux approches sont assez semblables. Garde la première.

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