newbie led inter code tortueux

bonjour, je débute dans le monde d'Arduino, et je suis assez étranger au C++, je prend donc des chemins tortueux pour arriver à coder un truc simple. Ici mon problème, mais que je peux arriver à coder (ça tiendrait sur 4 pages), est le suivant : j'ai 8 leds avec respectivement 8 interrupteurs à impulsion (inter tout simple, quand j'appuie =continuité, je relache=ouvert) 1 led est allumé à la fois je veux que quand j'appuie sur l'inter 1 ça allume la led 1 et éteigne la led allumé précédemment (s'il y en a une d'allumé) si je réappuie sur l'inter 1 ça éteind la led1 idem avec chaque led ci dessous ma façon empirique de coder (je me suis arrêté pour l'instant à 3 leds ...) je suis sûr qu'il y a une façon beaucoup plus élégante et beaucoup concise de coder ce circuit. si vous pouviez m'aiguiller sur une fonction ou une façon de faire merci à vous

int led3 =4;
int led2=3;
int led1=2;
boolean etat1 = false;//led1 allume ou eteinte
boolean etat2 = false;//led2 idem
boolean etat3 = false;//led3 idem
int bouton1 = 14;//interrupteur 1 (à impulsion)
int bouton2 = 11;//interrupteur 2 idem
int bouton3 = 12;//interrupteur 3 idem


void setup(){
  pinMode (led1, OUTPUT);
  pinMode (led2, OUTPUT);
  pinMode (led3, OUTPUT);
}

void loop() {
  //BOUTON1
  if (digitalRead(bouton1)==HIGH)
  {if(etat1==false)
  {digitalWrite(led1,HIGH);}

  if(etat1==true)
  {digitalWrite(led1,LOW);}
  etat1=!etat1;
  
  if(etat2==true)
   {digitalWrite(led2,LOW);
 etat2=!etat2;}

  if(etat3==true)
   {digitalWrite(led3,LOW);
 etat3=!etat3;} 
  delay (600);
  }
  
  //BOUTON2
   if (digitalRead(bouton2)==HIGH)
  {if(etat2==false)
  {digitalWrite(led2,HIGH);}
  
  if(etat2==true) 
  {digitalWrite(led2,LOW);}
  etat2=!etat2;
  
  if(etat1==true)
   {digitalWrite(led1,LOW);
 etat1=!etat1;}

  if(etat3==true)
   {digitalWrite(led3,LOW);
 etat3=!etat3;}
  delay (600);
  }
  
  //BOUTON3
  if (digitalRead(bouton3)==HIGH)
  {if(etat3==false)
  {digitalWrite(led3,HIGH);}

  if(etat3==true)
  {digitalWrite(led3,LOW);}
  etat3=!etat3;
  
  if(etat2==true)
   {digitalWrite(led2,LOW);
 etat2=!etat2;}
  
  if(etat1==true)
   {digitalWrite(led1,LOW);
 etat1=!etat1;} 
  delay (600);
  }  
}

Salut, Je suis nouveaux aussi. Comme je suis sur d'avoir loupé quelque chose voici ma consigne, ne pas prendre mon code au pieds de la lettre.

void setup() { DDRD = DDRD | B11111100; // registre du port D 0 à 7 arduino uno broche 2 a 7 en sortie DDRB = DDRB | B00000011; // registre du port B 8 à 13 broche 8 et 9 en sortie // total 8 en sortie }

void loop(){ if (digitalRead(BP1) == HIGH && PORTD == B00000000 && PORTB == B00000000) {PORTD = B00000100; PORTB = B00000000; } else {PORTD = B00000000; PORTB = B00000000; }

if (digitalRead(BP2) == HIGH && PORTD == B00000000 && PORTB == B00000000) {PORTD = B00001000; PORTB = B00000000; } else {PORTD = B00000000; PORTB = B00000000; }

if (digitalRead(BP3) == HIGH && PORTD == B00000000 && PORTB == B00000000) {PORTD = B00010000; PORTB = B00000000; } else {PORTD = B00000000; PORTB = B00000000; } }

Le code n'a rien de complet tel quel mais j'ai tester l'écriture et en théorie il ni a pas de faute ... En réalité je suis sur d'être passer a coté d'un trucs ! mais quoi. De toute manière je serai repris sur mon erreur, donc.

Bonjour a vous deux, alors au risque de précédé quelqu'un de plus doué que moi je vais vous aider un peux, la base de tout c'est la machine d'état !! (j'attend barbudor la dessus :p) alors regarde ça:

int led3 =4;
int led2=3;
int led1=2;
boolean etat1 = false;//led1 allume ou eteinte
boolean etat2 = false;//led2 idem
boolean etat3 = false;//led3 idem
int bouton1 = 14;//interrupteur 1 (à impulsion)
int bouton2 = 11;//interrupteur 2 idem
int bouton3 = 12;//interrupteur 3 idem


void setup(){
  pinMode (led1, OUTPUT);
  pinMode (led2, OUTPUT);
  pinMode (led3, OUTPUT);
}

void loop() {

 switch (x)
{
case 1:
etat1=digitalRead(bouton1);
etat2=digitalRead(bouton2);
etat3=digitalRead(bouton3);
x=2;
break;

case 2:
if(etat1==HIGH)
{
etat1=LOW; 
x=3;  
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
}

if(etat2==HIGH)
{
etat2=LOW; 
x=4;  
digitalWrite(led1,LOW);
digitalWrite(led3,LOW);
}

if(etat3==HIGH)
{
etat3=LOW; 
x=5;  
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
}
if (etat1==LOW && etat2==LOW && etat3==LOW)
{x=1;}
break;

case 3:
digitalWrite(led1,HIGH);
x=1;
delay(600);
break;

case 4:
digitalWrite(led2,HIGH);
x=1;
delay(600);
break;

case 5:
digitalWrite(led3,HIGH);
x=1;
delay(600);
break;

}

}

Voila un beau switch case qui va te permettre de passer simplement d'un bouton a l'autre =) , la machine d'état est simple et permet vraiment de réalisé des chose simple comme complexe en conservant une clartée dans ton programme utilise la au maximums c'est une vrai religion ^^

Skizo !

merci! je vais regarder vos codes de plus près et éssayer c'est 2 approches complètement différentes à première vue, je ne comprend pas grand chose de la première qui semble très concise, et la logique de la 2ème m'échappe pour le moment, je vais me concentrer

j’ai bien regardé les codes, je me sens plus proche de la méthode par machine d’état, MAIS je ne pige pas vraiment …
j’ai éssayé ce code il ne fonctionne pas. Auriez vous de la doc ou lien, ou exemples sur ces fameuses machines d’état,
Bien à vous

Yep!

Ici en anglais : http://www.arduino.cc/playground/Code/BitMath

Le tuto existe en français (quelque part) mais il n'est pas aussi complet.

@+

Zoroastre.

Tu fais huit tableaux, avec chacun 8 positions. Chaque position de tableau correspond à 1 led. Chaque inter correspond à 1 tableau.

inter1 >> {1,0,0,0,0,0,0,0} inter2 >> {0,1,0,0,0,0,0,0} etc

Ensuite tu fais un switch case par rapport a l'inter choisis et tu selectionnes le tableau qui va avec cet inter. Le tableau te permet de mettre les pins à l'état haut ou à l'état bas.

Salut,

:astonished: du bitwise, des tableaux multidimensionnel, de la manipulation de port, des machines d’état …
Vous êtes parti dans des trucs hyper compliqué les mecs !

Restons simple, je propose ceci :

const byte broche_bp[] = {A0, A1, A2, A3, A4, A5, 2, 3 }; // Broches des boutons
const byte broche_led[] = {4, 5, 6, 7, 8, 9, 10, 11};     // Broches des leds
static byte valeurs[8] = {LOW};                           // Etat des led à t - 1

void setup() {
  for(byte i = 0; i < sizeof(broche_bp); ++i) {
    pinMode(broche_bp[i], INPUT);
    pinMode(broche_led[i], OUTPUT);
  }
}

void loop() {
  for(byte i = 0; i < sizeof(broche_bp); ++i) { // On scan chaque boutons
    if(digitalRead(broche_bp[i]) == HIGH) {     // Si le boutons est appuyé
      valeurs[i] = !valeurs[i];                 // On inverse l'état de la led
      for(byte j = 0; j < sizeof(broche_bp); ++j)            // Pour chaque leds
        digitalWrite(broche_led[j], (i == j && valeurs[i])); // On "écrit" HIGH si la led est celle correspondante au bouton appuyé et que l'état précédant de la led était LOW.	  
      while(digitalRead(broche_bp[i]) == HIGH); // On attend que le bouton soit relaché
      break;                                    // On quitte le for qui scan les boutons
    }
  }
}

Chouette un concours de simplicité (ou de complexité suivant le point de vue ;))

Voyons si on peut faire plus simple que Skywodd

const byte broche_bp[] = {A0, A1, A2, A3, A4, A5, 2, 3 }; // Broches des boutons
const byte broche_led[] = {4, 5, 6, 7, 8, 9, 10, 11};     // Broches des leds
byte last_pressed = 0;

void setup() {
  for(byte i = 0; i < sizeof(broche_bp); ++i) {
    pinMode(broche_bp[i], INPUT);
    pinMode(broche_led[i], OUTPUT);
  }
}

void loop() 
{
  for(byte i = 0; i < sizeof(broche_bp); ++i)   {      // On scan chaque boutons
    if( digitalRead(broche_bp[i]) == HIGH ) {          // Si le boutons est appuyé
      digitalWrite( last_pressed, LOW );               // on éteint la LED précédente, marche aussi si la précédente est la même que la courante
      if ( i != last_pressed )                         // on allume la led si différente de la précédente
        digitalWrite( broche_led[i], HIGH );
      last_pressed = i;                                // on mémorise la nouvelle led courante
      while ( digitalRead(broche_bp[i]) == HIGH );     // on attend le relaché
      break;                                           // on sort du for
    }
  }
}

Une boucle et un tableau en moins.

barbudor: Chouette un concours de simplicité (ou de complexité suivant le point de vue ;))

C'est pas un concours, je me juste à la place de helios86 qui doit s'arracher les cheveux devant des morceaux de code qu'il ne comprend pas ;) Rien en vaut un bout de code simple et commenté pour comprendre ;)

barbudor: Voyons si on peut faire plus simple que Skywodd

Tu peut largement l'améliorer, j'ai fait au plus simple et au plus compréhensible pour un débutant ;)

j'adore!! merci!!! MAIS le code de Skywodd ne fonctionne pas, rien ne s'allume (je ne fais le teste qu'avec 3 inter 3 leds pour l'instant) et pour celui de Barbudor les leds s'allument mais ne s'éteignent plus ... je creuse, en tout cas j'apprécie les différentes solutions qui m'ouvrent à différentes façon de voir le code (je viens de la programmation modulaire MAX/MSP, et j'avoue que j'ai du mal à me mettre au code)

j'éssai de comprendre, c'est pas forcément évident ... et je vais de plus devoir integrer une temporisation différente pour chaque led (qu'elle s'éteigne si pas éteinte par un inter au bout de x secondes)

helios86: MAIS le code de Skywodd ne fonctionne pas, rien ne s'allume (je ne fais le teste qu'avec 3 inter 3 leds pour l'instant)

Oups !

Une petite erreur semble s'être glissé dans un des digitalWrite :

digitalWrite(broche_led[i], (i == j && valeurs[i]));

->

digitalWrite(broche_led[j], (i == j && valeurs[i]));

(Le j au lieu de i doit être la cause du soucis)

Pareil, le Barbudor s’est fourvoyé.

  • Une erreur de frappe : digitalWrite( last_pressed, LOW ); au lieu de digitalWrite( broche_led[last_pressed], LOW );
    qui empéchait les leds de s’éteindre
  • Une erreur de logique : j’ai oublié de rallumer la led si c’est la meme et qu’elle est éteinte

Donc une version qui marche et qui reste simple à lire (toujours sans 2eme boucle)

byte last_pressed = 0;
byte last_state = 0;

void setup() {
  for(byte i = 0; i < sizeof(broche_bp); ++i) {
    pinMode(broche_bp[i], INPUT);
    pinMode(broche_led[i], OUTPUT);
  }
}

void loop() 
{
  for(byte i = 0; i < sizeof(broche_bp); ++i)   {      // On scan chaque boutons
    if( digitalRead(broche_bp[i]) == HIGH ) {          // Si le boutons est appuyé
      digitalWrite(  broche_led[last_pressed], LOW );  // on éteint la LED précédente, marche aussi si la précédente est la même que la courante
      if ( (i != last_pressed)  || !last_state  ) {    // on allume la led si différente de la précédente OU si le précédent état est éteint
        digitalWrite( broche_led[i], HIGH );
        last_state = true;                             // on mémorise l'état allumé (au moins une led)
      }
      else
        last_state = false;                            // on mémorise l'état eteint (toutes les leds)
      last_pressed = i;                                // on mémorise la dernière led qui a changé
      while ( digitalRead(broche_bp[i]) == HIGH );     // on attend le relaché
      break;                                           // on sort du for
    }
  }
}

Et une version plus compacte mais peut être moins lisible (juste le code central qui change)

    if( digitalRead(broche_bp[i]) == HIGH ) {          // Si le boutons est appuyé
      digitalWrite(  broche_led[last_pressed], LOW );  // on éteint la LED précédente, marche aussi si la précédente est la même que la courante
      last_state = (i != last_pressed)  || !last_state;
      if ( last_state )                                // on allume la led si différente de la précédente OU si le précédent état est éteint
        digitalWrite( broche_led[i], HIGH );
      last_pressed = i;                                // on mémorise la dernière led qui a changé
      while ( digitalRead(broche_bp[i]) == HIGH );     // on attend le relaché
      break;                                           // on sort du for
    }

aucun des 2 codes ne fonctionnent pour l'instant... =( j'y vois peut être plus bien, je vais me coucher et reprendre au grand jour merci messieurs pour votre aide

XD

Et pour faire s’éteindre la led automatiquement au bout de quelques secondes voici une possibilité en modifiant mon précédent code:

#define TEMPO    3000
unsigned long dernier_evenement = millis();


void loop() 
{
  for(byte i = 0; i < sizeof(broche_bp); ++i)   {      // On scan chaque boutons
    if( digitalRead(broche_bp[i]) == HIGH ) {          // Si le boutons est appuyé
      digitalWrite(  broche_led[last_pressed], LOW );  // on éteint la LED précédente, marche aussi si la précédente est la même que la courante
      last_state = (i != last_pressed)  || !last_state;
      if ( last_state )                                // on allume la led si différente de la précédente OU si le précédent état est éteint
        digitalWrite( broche_led[i], HIGH );
      last_pressed = i;                                // on mémorise la dernière led qui a changé
      dernier_evenement = millis();        
      while ( digitalRead(broche_bp[i]) == HIGH );     // on attend le relaché
      break;                                           // on sort du for
    }
  }
  if ( (millis() - dernier_evenement) >= TEMPO )
  {
    digitalWrite( broche_led[last_pressed], LOW );
    last_state = false;
  }
}

Contrairement au 1er code que j’ai pondu en ligne sans le tester (prétentieux que je suis :roll_eyes:),
Le 2nd, je l’ai testé (mais je suis pauvre, j’ai que 2 boutons et 2 leds ;)) et il marche très bien
Y compris la dernière modif avec la tempo.

non en fait un éclair de lucidité m'a traversé! (ça peut arriver, oui oui!) comme je fais l'éssai qu'avec 3 inter, 3 leds, j'ai donc viré du code les entrées sorties manquante. Et donc les 2 exples de Barbudor fonctionnent à merveille, par contre Skywodd le code ne fait pas exactement le boulot, quand une led est allumé, je clic sur un inter il l'éteint MAIS n'allume sa diode correspondante à la place. il faut recliquer pour qu'elle s'allume

Magnifique! c'est nikel, et pour compliqué, une tempo différente pour chaque led ? Pour donner une idée de l'application de ce code, ça peut être sympa, c'est pour fabriquer une boite dans laquelle il y a 8 photos A chaque photos (posé sur du plexi), est attribué une led de 3w, et un inter. (j'attend une commande, pas encore testé) De chaque coté de la boite 2 haut parleur amplifié. Donc quand tu clic sur un inter ça allume la photos, et déclenche un son (une petite histoire). Quand le son est terminé, la led s'éteint. je vais avancer dans arduino pas à pas sur des projets concrets. Encore merci pour votre contribution!!!