de l'aide pour un débutant

j'essaie de mettre en place un truc avec arduino mais je galère beaucoup. J'ai fait plein de test etc etc mais j'ai du mal à avoir une vision d'ensemble et je suis super débutant.

J'essaie d'allumer deux led mais qui interagiraient entre elles.
il y a une led verte et une rouge commandées chacune par des boutons disons boutonvert et boutonrouge

  • Si la led verte est allumée et qu' on enclenche boutonrouge, il s'allume, si on l'enclenche à nouveau, il reste allumé et la led verte reste toujours allumée.
  • Si la led verte est allumée quand la led rouge est allumée si on appuie sur boutonvert, la led rouge s'eteind et la led verte reste allumée
  • Si la led verte est allumée et la led rouge est eteinte et qu'on appuie sur boutonvert, le led verte s'éteint.
  • Si la led verte est éteinte et qu'on appuie sur boutonrouge, la led rouge s'allume et si on rappuie dessus elle reste allumée et la led verte reste éteinte

J'ai l'impression que cette description est presque le code que je cherche mais j'y arrive pas.
j'ai essayé de modifier un code des tuto arduino et ca marche pas.

le voici (sans les modifs puisqu'aucune ne marche):

void loop()
{
  reading = digitalRead(inPin);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();    
  }

  digitalWrite(outPin, state);

  previous = reading;
}

Si quequ'un peut m'aider :-[ :-/ :cry:

Aller une petite piste.

Le code que tu as copié permet de gérer un poussoir.
Si tu le dupliques et que dans chacune des copies tu suffixes le nom des variables avec Vert et Rouge tu auras à la fin stateVert et stateRouge.
En faisant quelques tests sur les états de stateRouge et stateVert tu devrais arriver à réaliser la fonction que tu veux.

j'ai déjà fais ça, en dupliquant la fonction une pour rouge et une pour vert et j'ai rajouté des conditions dans la fonction associée au vert mais une fois allumée la led verte reste allumée quoique je fasse.
J'ai aussi tenté d'imbriquer des "if" dans :

if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
******
ICI
******
    else
      state = HIGH;

Mais ça ne marche pas non plus.

Ce serait plus facile si tu postais l'ensemble du code et non pas des morceaux.

Ben pour le moment je peux pas puisque je ne suis pas chez moi.
Mais je ne sais pas si ça vaut tellement le coup puisque je n'ai fait que copier celui de l'exemple, changer les variables selon si c'est la led verte ou rouge ou le boutonvert ou boutonrouge en gros ça devait être ça :

void loop()
{
  reading = digitalRead(inPin);
  reading2 = digitalRead(inPin2);

  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH){
      if(state2 == HIGH){
         state = HIGH;
         state2 = HIGH;
   }
      if(state2 == LOW){
        state2 == HIGH;
        state = HIGH;
  }
}else{
      state = HIGH;
}
    time = millis();    
  }


  if (reading2 == HIGH && reading==HIGH && previous2 == LOW && millis() - time > debounce) {
    if (state2 == HIGH)
      state2 = LOW;
    else
      state2 = HIGH;

    time = millis();    
  }

  digitalWrite(outPin, state);
  digitalWrite(outPin2, state2);

  previous = reading;
  previous2 = reading2;

}

en gros mais il n'est pas fini puisque même ça , ça ne va pas.

est ce que "switch" ne fonctionnerai pas?

if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();    
  }

Ce morceau de code teste le changement d'état du poussoir d'entrée et il vérifie qu'un certain temps c'est écoulé pour être certain que le contact ne rebondisse plus.
C'est ce bloc qu'il faut dupliquer et toute les variables de ce bloc doivent être unique même la variable time.
Pour chacun des poussoirs, la variable reading contient l'état courant, la variable previous l'état précédent la variable state l'état courant après filtrage (debounce).
Avec ces 3 variables pour chacun des poussoirs tu dois pouvoir gérer la logique que tu avais décrite au début de ce fil. Cette logique doit être située après les deux blocs de codes qui déterminent l'état des poussoirs

Cette logique doit être située après les deux blocs de codes qui déterminent l'état des poussoirs

tu veux dire que je dois déclarer comment se comportent mes pushbuttons et après ça, je dois déclarer des conditions selon lesquelles telle ou telle led s'allume?
du genre:

if (...)
code du bouton vert

if (...)
code du bouton rouge

if (...)
conditions selon lesquelles le rouge ou le vert s'allument ou pas

ou alors j'ai pas compris.

tu veux dire que je dois déclarer comment se comportent mes pushbuttons et après ça, je dois déclarer des conditions selon lesquelles telle ou telle led s'allume?

C'est l'idée.

Il faudrait réaliser une petite machine à état qui en fonction de l'état actuel des sorties et des boutons décrive le nouvel état des sorties. C'est le seul moyen de gérer simplement un automate avec plusieurs entrées et plusieurs sorties.

D'ailleurs avant même d'écrire du code il est bon de faire un petit diagramme qui décrit les états et les conditions qui font passer d'un état à l'autre. C'est la manière la plus sûre de vérifier que l'on a bien pris en compte toutes les conditions et que quelque soit l'état où on se trouve une action sur l'un des boutons amènera bien vers l'état voulu. Le plus simple c'est de partir de l'état d'initialisation avec les voyants éteints et de dire si j'appuie sur tel bouton qu'est-ce que je fais et si j'appuie sur l'autre qu'est-ce que je dois faire. Et on répète pour chacun des nouveaux états.

Je te remercie, je ne peux pas essayer aujourd'hui encore malheureusement. Mais je tenterai avec cette méthode et je te donnerai des nouvelles.

il faut que tu crées un tableau de stockage

bool mes_boutons[6];
bool mes_boutons_etat_precedent[6]

pourquoi mets tu [6], ça veut dire que je peux stocker 6 variantes de mes_boutons?

tu crées des tableaux. comme un tableau excel à une seule ligne.

une procedure en for i=.... te permet de travailler sur plusieurs boutons et d'alléger ton code , cad de ne pas rajouter des if des else etc... pour chacun des boutons ( ce qui généralement amène des erreurs classiques de parenthèse et de syntaxe)

for(int i=0;i<6;i++)
{
mes_boutons_etat_precedent[i]=mes_boutons[i];//tu stockes l etat precedent, cela te permet de comparer et de savoir si quelqu un appuye, ou relache le bouton
mes_bouton[i]=digitalRead[i];//tu lis tes boutons et tu stockes dans ce tableau
}

après tu peux toujours inclure dans cette boucle for(int i=....)
des trucs commes:

if(mes_boutons==1 && mes_boutons_etat_precedent*==0)
_
{_
_
//action si tu appuyes sur le bouton: allumer une led, revenir au debut d un morceau de musique, etc*_
}
else if(mes_boutons*==0 && mes boutons_etat_precedent==1)
_{
//la c est si tu relaches ton bouton ce que tu fais*
}
Dans un precedent message, quelqu un te suggerait de faire un arbre logique.
Avec des boutons, c est le plus simple: l etat est soit 0 soit 1. Et toute la logique de ce que tu veux faire dépend du choix des conditions.
Telle valeur==1 , je fais ceci, sinon celà ( le else n est pas obligé)
Il vaut mieux commencer avec des if et des else, avant de s attaquer au switch.
Grosso modo tous les ifs vont être lus par arduino:
if ( condition 1){...}
if (condition 2){...}
etc...
ce qui prend tu temps au processeur.
le switch permet de voir si une condition est remplie, alors il execute le troncon de code. Celà veut dire que par exemple si tu teste des conditions, tu peux avoir plus de deux scenarios, peut etre 16 ou 20, le if va beaucoup te manger de temps processeur.
le switch te permet d executer moins de tests de conditions
tu peux t en passer au debut. surtout si ce que tu veux faire est léger._

Ok ok , je vais tenter ça. Je me sens en général (débutant oblige) assez mal à l'aise avec les "assignations automatiques" comme dans ton exemple avec la boucle "for" même si je comprends tout à fait l'utilité , mais il va falloir que j'y arrive.

Tu peux faire quelque chose comme ça

#define LED_ROUGE_ON 1
#define LED_ROUGE_OFF 0
#define LED_VERTE_ON 2
#define LED_VERTE_OFF 0

char EtatLedVerte=0;
char EtatLedRouge=0;
char EtatCourant=0;


EtatCourant = EtatLedRouge | EtatLedVerte;  // Nouvel état
switch (EtatCourant){
   case 0:
      if (condition à définir) // si je suis dans cet état et que mes entrées sont comme décrit dans le if alors ...
           EtatLedRouge= LED_ROUGE_ON; // exemple
           EtatLedVerte =  LED_VERTE_OFF;  // exemple
     else  (condition à définir)
           EtatLedRouge= LED_ROUGE_ON;
           EtatLedVerte =  LED_VERTE_OFF;
     }
     break;
   case 1:
      if (condition à définir)
           EtatLedRouge= LED_ROUGE_OFF;
           EtatLedVerte =  LED_VERTE_OFF;
     else  (condition à définir)
           EtatLedRouge= LED_ROUGE_ON;
           EtatLedVerte =  LED_VERTE_ON;
    }
    break;
    case 2:
       ...............
    case 3:
       ...............
}
digitalWrite(ledVerte,...
digitalWrite(ledRouge,...

L'état courant dépend de l'état des LED et les conditions dans les if sont celles que tu as déterminées dans le diagramme des états dont je parlais dans un post précédent

je vais m'atteler à ça au plus vite et j'essaierai de pouvoir vous montrer ce qu'il en sort, quelque chose de plus concret que ce que j'ai donné dans le début du topic.
merci en tout cas.

j'ai essayé de faire ça :

#define LED_ROUGE_ON 1
#define LED_ROUGE_OFF 0
#define LED_VERTE_ON 1
#define LED_VERTE_OFF 0

bool bouton[2];
bool statebouton[2];

char EtatLedVerte=0;
char EtatLedRouge=0;
char EtatCourant=0;
int ledVerte = 12;
int ledRouge = 11;
int bouton1 = 6;
int bouton2 = 5;
int reading;
int previous = LOW;

long time = 0;
long debounce = 100;

void setup(){
  pinMode(bouton1,INPUT);
  pinMode(bouton2,INPUT);
  pinMode(ledVerte,OUTPUT);
  pinMode(ledRouge,OUTPUT);  
  digitalWrite(bouton1, HIGH);      
  digitalWrite(bouton2, HIGH); 
}

void loop(){

for(int i=0;i<2;i++)
{
statebouton[i]=bouton[i];//tu stockes l etat precedent, cela te permet de comparer et de savoir si quelqu un appuye, ou relache le bouton
bouton[i] = digitalRead[i];//tu lis tes boutons et tu stockes dans ce tableau
} 

int reading = digitalRead(button[i]);

if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (statebouton[i] == HIGH)
      statebouton[i] = LOW;
    else
      statebouton[i] = HIGH;

    time = millis();    
  }

  
EtatCourant = EtatLedRouge | EtatLedVerte;  // Nouvel état
switch (EtatCourant){
   case 0:
      if (bouton1 == LOW && bouton2 == HIGH){ // si je suis dans cet état et que mes entrées sont comme décrit dans le if alors ...
           EtatLedRouge = LED_ROUGE_ON; // exemple
           EtatLedVerte =  LED_VERTE_OFF;  // exemple
     break;
      }
   case 1:
      if (bouton1 == HIGH && bouton2 == HIGH){ // si je suis dans cet état et que mes entrées sont comme décrit dans le if alors ...
           EtatLedRouge= LED_ROUGE_OFF; // exemple
           EtatLedVerte =  LED_VERTE_ON;  // exemple
     break;
      }


}
digitalWrite(ledVerte,EtatLedVerte);
digitalWrite(ledRouge,EtatLedRouge);
}

mais ça ne compile pas
ça m'écrit :

In function 'void loop()':
error: pointer to a function used in arithmetic

accolade mal placée :wink: du coup le compilateur ne comprend pas les fonctions demandées

switch (EtatCourant){
   case 0:
      if (bouton1 == LOW && bouton2 == HIGH){ // si je suis dans cet état et que mes entrées sont comme décrit dans le if alors ...
           EtatLedRouge = LED_ROUGE_ON; // exemple
           EtatLedVerte =  LED_VERTE_OFF;  // exemple
     break;
      }  // << l erreur
   case 2:

à sa place il faut faire:

switch (EtatCourant){
   case 0:
      if (bouton1 == LOW && bouton2 == HIGH){ // si je suis dans cet état et que mes entrées sont comme décrit dans le if alors ...
           EtatLedRouge = LED_ROUGE_ON; // exemple
           EtatLedVerte =  LED_VERTE_OFF;  // exemple
    } //<< tu fermes le if ici, dans le case 0 sinon il pense que le switch est fermé
     break;
    case 1:
    blablabala
   break;
      ...
}//fin du switch

#define LED_ROUGE_ON 1
#define LED_ROUGE_OFF 0
#define LED_VERTE_ON 1
#define LED_VERTE_OFF 0

Ce n'est pas ce que j'avais mis.
Pour LED_VERTE_ON j'avais mis 2. Cela permet d'obtenir les 4 états possibles d'EtatCourant en faisant le ou avec LED_VERTE_ON et LED_VERTE_OFF

D'ailleurs pour rendre la chose plus clair il serait préférable de remplacer le chiffre dans les case par cela

case LED_ROUGE_OFF | LED_VERTE_OFF:
  ........
case LED_ROUGE_ON | LED_VERTE_OFF:
  ........
case LED_ROUGE_OFF | LED_VERTE_ON:
  ........
case LED_ROUGE_ON | LED_VERTE_ON:
  ........

Concernant l'erreur de compilation elle vient de cette ligne:

bouton[i] = digitalRead[i];//tu lis tes boutons et tu stockes dans ce tableau

digitalRead c'est une fonction donc on ne peut pas utiliser les crochets
Il faut corriger comme cela

bouton[i] = digitalRead(i);//tu lis tes boutons et tu stockes dans ce tableau

Ensuite il y a 2 ou 3 autres erreurs qui sortent.
Après correction on arrive à ça:

#define LED_ROUGE_ON 1
#define LED_ROUGE_OFF 0
#define LED_VERTE_ON 2
#define LED_VERTE_OFF 0

bool bouton[2];
bool statebouton[2];

char EtatLedVerte=0;
char EtatLedRouge=0;
char EtatCourant=0;
int ledVerte = 12;
int ledRouge = 11;
int bouton1 = 6;
int bouton2 = 5;
int reading;
int previous = LOW;

long time = 0;
long debounce = 100;

void setup(){
  pinMode(bouton1,INPUT);
  pinMode(bouton2,INPUT);
  pinMode(ledVerte,OUTPUT);
  pinMode(ledRouge,OUTPUT);
  digitalWrite(bouton1, HIGH);
  digitalWrite(bouton2, HIGH);
}

void loop(){

for(int i=0;i<2;i++)
{
statebouton[i]=bouton[i];//tu stockes l etat precedent, cela te permet de comparer et de savoir si quelqu un appuye, ou relache le bouton
bouton[i] = digitalRead(i);//tu lis tes boutons et tu stockes dans ce tableau


int reading = bouton[i];

if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (statebouton[i] == HIGH)
    statebouton[i] = LOW;
    else
    statebouton[i] = HIGH;

    time = millis();
  }
}

EtatCourant = EtatLedRouge | EtatLedVerte;  // Nouvel état
switch (EtatCourant){
   case LED_ROUGE_OFF | LED_VERTE_OFF:
    if (bouton1 == LOW && bouton2 == HIGH) // si je suis dans cet état et que mes entrées sont comme décrit dans le if alors ...
         EtatLedRouge = LED_ROUGE_ON; // exemple
         EtatLedVerte =  LED_VERTE_OFF;  // exemple
     break;
    
   case LED_ROUGE_ON | LED_VERTE_OFF:
    if (bouton1 == HIGH && bouton2 == HIGH) // si je suis dans cet état et que mes entrées sont comme décrit dans le if alors ...
         EtatLedRouge= LED_ROUGE_OFF; // exemple
         EtatLedVerte =  LED_VERTE_ON;  // exemple
     break;
    


}
digitalWrite(ledVerte,EtatLedVerte >> 1);
digitalWrite(ledRouge,EtatLedRouge);
}

Je ne suis pas chez moi, et je n'ai pas d'Arduino sous la main donc le code n'est pas testé

j'ai enfin réussi mais en faisant autrement que ce que vous m'avez dit.
Si vous avez des suggestion d'améliorations elles seront les bienvenues.
voilà le code:

const int playPin = 5;        
const int playLed = 12;
const int recPin = 6;
const int recLed = 11;

volatile int playState = LOW;      
volatile int playReading;           
volatile int playPrevious = HIGH;

volatile int recState = LOW;      
volatile int recReading;           
volatile int recPrevious = HIGH;

volatile int play;
volatile int rec;
volatile int playpause = 0;
volatile int playstart = 0;

long playTime = 0;         
long playDebounce = 300;  
long recTime = 0;         
long recDebounce = 200; 


void setup()
{
  pinMode(playPin, INPUT);
  digitalWrite(playPin, HIGH);
  pinMode(playLed, OUTPUT);
  pinMode(recPin, INPUT);
  digitalWrite(recPin, HIGH);
  pinMode(recLed, OUTPUT);
  
  Serial.begin(300);
}


void loop()
{

playReading = digitalRead(playPin);

if (playstart > 0){
if (playReading == HIGH && playPrevious == LOW && millis() - playTime > playDebounce) {
   play += 1;
   playTime =  millis();
}
}

recReading = digitalRead(recPin);
if (recReading == HIGH && recPrevious == LOW && millis() - recTime > recDebounce) {
  rec += 1;
  recTime = millis();    
}

  

if (rec != 0){
recState = 1;
}else{
recState = 0;
}

if (rec != 0){
  playstart = 1;
}

if (play != 0){
playState = 1;
}else{
playState = 0;
}
  
if (playpause == 0){
  if (rec > 0 && play > 0){
    rec = 0;
    play = 1;
    playpause = 1;  
  }
}

if (playpause == 1){
  if (rec > 0 && play > 1){
    play = 1;
    rec = 0;
  }
  
  if (rec == 0 && play > 1){
    play = 0;
    rec = 0;
  }
  if (rec == 0 && play == 0){
    playpause = 2;
  }
}

if (playpause == 2){
  if (rec > 0 && play > 0){
    rec = 0;
    play = 1;
    playpause = 1;
  }
  if (rec == 0 && play == 2){
    rec = 0;
    play = 0;
  }
}

  
digitalWrite(playLed, playState);
digitalWrite(recLed, recState);
playPrevious = playReading;
recPrevious = recReading;
  
Serial.print(rec);
Serial.print(play);
Serial.println(playpause);
}