Question de syntaxe (!=i)

Bonjour tout le monde !

Je profite du dimanche pour bricoler un petit jeu interactif avec des lampes, et je bute sur un problème de syntaxe.

J’ai plusieurs lampes (“led” dans le code) qui ont chacune un interrupteur (un capteur capacitif en fait, “capteur” dans le code).
Pour allumer la lampe i, il faut que la lampe i-1 soit allumée, et caetera. Jusque là pas souci, j’ai mon code et il fonctionne :slight_smile:

Sauf que je me suis rendu compte que si on active tous les capteurs simultanément, tout s’allume et on perd l’intérêt du jeu.
Du coup j’ai pensé ajouter une condition du type “si le capteur i est HIGH et que les autres capteurs sont LOW, la lampe i s’allume”. Problème, ma syntaxe est fausse, et je ne trouve pas comment formuler la condition autrement (la ligne 19 dans le code suivant) :

int led[] = {3, 4, 5, 6, 7, 8, 9, 10};
int capteur[] = {25, 27, 29, 31, 33, 35, 37, 39};
int etat_led[] = {false, false, false, false, false, false, false, false};
const int NUMLED = 8;

void setup() {
  Serial.begin(9600);
  int i;
  i = 0;
}

void loop() {
  int i;
  i = 0;

  while(i < NUMLED) {
    if (digitalRead(capteur[i]) == HIGH){
      delay(150);
     if ((digitalRead(capteur[i]) == HIGH) && (digitalRead(capteur[!=i])== LOW)){
      if (i == 0){
        Serial.println(String(i) + " OK");
        etat_led[i] = true;
        digitalWrite(led[i], HIGH);
      }
      else {
        if (etat_led[i-1] == true){
           etat_led[i] = true;
           digitalWrite(led[i], HIGH);
        }
        else {
          int j;
          j = 0;
          while (j < NUMLED){
            etat_led[j] = false;
            digitalWrite(led[j], LOW);
            j = j + 1;
          }
        }
        }
      }
    }
    i = i + 1;
  }

Est-ce que vous auriez une idée de formulation différente ?
Merci à vous et bon bricolage ce dimanche :slight_smile:

Tu peux utiliser le fait que HIGH vaut 1 et LOW vaut 0 :

Si tu veux vérifier si tous les capteurs autres que i valent LOW, donc 0, tu fais la somme de tous tes capteurs autres que i et tu compares cette somme à 0.
La somme de tous les capteurs sauf i, c'est la somme de tous les capteurs (y compris 'i') moins la valeur du capteur i.

Merci pour ta réponse lesept, ça pourrait tout à fait marcher !

Je n'ai utilisé les tableaux que dans des cas basiques pour le moment, donc ma tentative suivante est peut-être hasardeuse (en plus de mon vocabulaire)
Du coup, je réfléchis en écrivant ; il faut que j'additionne les valeurs contenues dans mon tableau capteur. Je peux créer une int k :

int k = capteur[0] + capteur[1] + capteur[2] + capteur[3] + capteur[4] + capteur[5] + capteur[6] + capteur[7] - i

Si k==0 alors on passe à la suite
Si k!=0 alors on recommence

Par contre encore une fois j'hésite sur la syntaxe pour "lire" les cases de mon tableau, est-ce que je peux écrire ça simplement capteur[1] par exemple ? Qu'en dis-tu ?

étant donné que vous avez 8 LEDs, l'état pourrait tenir sur un seul octet. le bit 0 correspond à la LED à la position 0, le bit 1 correspond à la LED à la position 1, etc

N'oubliez pas les pinMode() dans le setup()

J-M-L:
étant donné que vous avez 8 LEDs, l'état pourrait tenir sur un seul octet. le bit 0 correspond à la LED à la position 0, le bit 1 correspond à la LED à la position 1, etc

N'oubliez pas les pinMode() dans le setup()

Merci pour votre remarque, j'ai bien rajouté les pinMode() de led et de capteur.
Par contre étant vraiment en train de débuter, je ne suis pas sûre de comprendre ce qu'implique le fait que l'état puisse tenir sur un seul octet (ou plutôt comment utiliser cette idée dans mon code) ?

ça fait gagner de la place en mémoire. et pour voir si rien n’est appuyé il suffit de regarder si ça vaut 0
vous pouvez aussi simplement comparer avec l’état précédent pour voir si quelque chose à changé en comparant 2 valeurs (la valeur courante avec celle précédente) au lieu de tout le tableau

const byte ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10};
const byte capteurPins[] = {25, 27, 29, 31, 33, 35, 37, 39};
const byte nbcapteurs = 8;

byte lireEtat(byte &etat)
{
  byte compte = 0;
  etat = 0;
  for (byte i = 0; i < nbcapteurs; i++)
    if (digitalRead(capteurPins[i]) == LOW) {
      bitSet(etat, i);
      compte++;
    }
  return compte;
}

void setup()
{
  Serial.begin(115200);
  for (byte i = 0; i < nbcapteurs; i++) {
    pinMode(ledPins[i], OUTPUT);
    pinMode(capteurPins[i], INPUT_PULLUP);
  }
}

void loop()
{
  byte etat;
  byte total = lireEtat(etat);
  Serial.print(F("Nombre de capteurs actifs: "));
  Serial.println(total);
  Serial.print(F("Etat des capteurs: "));
  Serial.println(etat, BIN);
}

dans ce code la fonction lireEtat() va remplir son paramètre avec des 1 sur les bits où le capteurs est actif (ici j’ai décidé à LOW, INPUT_PULLUP) et vous retourne le nombre de capteurs actifs en même temps.

La solution de J-M-L est très bonne et frugale en mémoire. Je corrige ce que tu as fait sur ma proposition :

int k = capteur[0] + capteur[1] + capteur[2] + capteur[3] + capteur[4] + capteur[5] + capteur[6] + capteur[7] - capteur[i]

Bonjour à tous. :slight_smile:

Voilà, je débute dans le monde de l'Arduino avec 2 éditions "pour les nuls" dont une qui s'appel "Programmez en s'amusant". Mais voilà, j'ai beau relire le code, je vois pas l'erreur.

Ma question est donc :
Cela vient de moi ? (si c'est le cas, dans ce cas je chercherai moi même mon erreur)
Ou ça vient du livre ? (parce que bon, si je passe la journée à chercher un erreur qui vient du livre, je vais perdre mon temps pour une erreur qui ne vient pas de moi.

Voici le message d'erreur :

'PrecH' does not name a type

Et voici le code en question :

byte LED1 = 11; // U = Unite
byte LED2 = 10; // D = Deuzaine
byte LED3 = 9; // Q = Quatraine
byte LED4 = 6; // H-8 = Huitaine

byte AnaOUI = 100;
byte AnaNON = 0;

boolean etatU, etatD, etatQ, etatH = 0;
boolean PrecU, PrecD, PrecQ, PrecH = 0;  // Ajout

void setup(){
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
}

void agir(byte broche, boolean valeur) {
  if (valeur) analogWrite(broche, AnaOUI);
  else        analogWrite(broche, AnaNON);
}

void loop() {
  // LED UNITE
  PrecU = etatU;
  if ( !etatU ) { etatU = 1; }
          else  { etatU = 0; }
  agir(LED1, etatU);
  delay(50);  // DELAI PEDAGOGIQUE

// LED DEUZAINE
PrecD = etatD;
if ( (!etatU) && (PrecU) ) {
  etatD = !etatD;
  agir(LED2, etatD);
}
delay(50);

// LED QUATRAINE
PrecQ = etatQ;
if ( (!etatD) && (PrecD) ) {
  etatQ = !etatQ;
  agir(LED3, etatQ);
}
delay(50);
}

// LED HUITAINE
  PrecH = etatH;    // Utile si extension 8 bits
if ( (!etatQ) && (PrecQ) ) {
  etatH = !etatH;
  agir(LED4, etatH);
}
delay(500);
}

En vous remerciant d'avance pour votre réponse mais surtout, pour tout ses partages et conseils des membres qui sont d'une utilité sans nom.

EDIT : C'est fait. merci

corrigez votre post ci dessus et rajoutez les code tags autour du code:

[code]

[color=blue]// votre code ici[/color]

[/code]

.

ça doit ressembler à cela:

// votre code ici

(faites aussi ctrl-T (PC) or cmd-T (Mac) dans l'IDE avant de copier le code pour qu'il soit indenté correctement)

--> une fois indenté vous verrez le souci...

--> une fois indenté vous verrez le souci...

Merci du conseil. C'est clairement plus pratique en effet. Par contre, concernant l'erreur, si il s'agit des balises ([/b]) sur l'erreur, c'était volontaire de ma part pour la refaire sortir.

C'est de cela que tu parlais ? Merci.

EDIT : je les ai ôté. Merci.

Vérifie les couples d'accolades... et compare avec ton livre

comme dit plus haut "--> une fois indenté vous verrez le souci..."

@lesept Malheureusement plus rien ne s'allume quand j'utilise cette syntaxe !

@J-M-L Merci pour votre réponse. Je ne sais pas utiliser byte, je vais donc prendre quelques jours pour l'apprendre (je ne comprends pas votre code ni ne saurais l'intégrer au mien et l'adapter pour mon problème).

Vérifie les couples d'accolades... et compare avec ton livre

Merci.

comme dit plus haut "--> une fois indenté vous verrez le souci..."

Effectivement. Merci.

Puis désolé pour le dérangement. :confused: (...)

Bonne fin de soirée à tous.

J’ai tenté le coup… Comme je le pensais, ne pas comprendre ce qu’on écrit ne donne jamais de bons résultats ::slight_smile: Je pense avoir compris que “total” me permettra de savoir combien de capteurs sont actifs. J’ai donc tenté de l’utiliser comme condition (si plus d’un capteur est actif, alors éteins la lampe). Ca ne fonctionne pas pour le moment.

Si vous avez un peu de temps et l’envie d’y jeter un oeil :

int led[] = {3, 4, 5, 6, 7, 8, 9, 10};
int capteur[] = {25, 27, 29, 31, 33, 35, 37, 39};
int etat_led[] = {false, false, false, false, false, false, false, false};
const int NUMLED = 8;
const int GACHE = 11;
const byte ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10};
const byte capteurPins[] = {25, 27, 29, 31, 33, 35, 37, 39};
const byte nbcapteurs = 8;

byte lireEtat(byte &etat)
{
  byte compte = 0;
  etat = 0;
  for (byte i = 0; i < nbcapteurs; i++)
    if (digitalRead(capteurPins[i]) == HIGH) {
      bitSet(etat, i);
      compte++;
    }
  return compte;
}

void setup() {
  Serial.begin(9600);
  for (byte i = 0; i < nbcapteurs; i++) {
    pinMode(ledPins[i], OUTPUT);
    pinMode(capteurPins[i], INPUT_PULLUP);
  }
  int i;
  i = 0;
    
  while(i < NUMLED){
    pinMode(led[i], OUTPUT);
    pinMode(capteur[i], INPUT);
    i = i + 1;
  }

  pinMode(GACHE, OUTPUT);
  digitalWrite(GACHE, HIGH);
}

void loop() {
  int i;
  i = 0;
  byte etat;
  byte total = lireEtat(etat);
  Serial.print(F("Nombre de capteurs actifs: "));
  Serial.println(total);
  Serial.print(F("Etat des capteurs: "));
  Serial.println(etat, BIN);

  while(i < NUMLED) {
    if ((digitalRead(capteur[i]) == HIGH) && (digitalRead(total) < 1)){
      delay(150);
      if ((digitalRead(capteur[i]) == HIGH) && (digitalRead(total) < 1)){
      if (i == 0){
        Serial.println(String(i) + " OK");
        etat_led[i] = true;
        digitalWrite(led[i], HIGH);
      }
      else {
        if (etat_led[i-1] == true){
           etat_led[i] = true;
           digitalWrite(led[i], HIGH);
        }
        else {
          int j;
          j = 0;
          while (j < NUMLED){
            etat_led[j] = false;
            digitalWrite(led[j], LOW);
            j = j + 1;
          }
        }
        }
      }
    }
    i = i + 1;
  }
  if (etat_led[NUMLED - 1] == true){
    digitalWrite(GACHE, LOW);
  }
}

eh… faut un peu réfléchir quand même :)J’ai changé cela

 int led[] = {3, 4, 5, 6, 7, 8, 9, 10};
int capteur[] = {25, 27, 29, 31, 33, 35, 37, 39};

en cela pour avoir des noms plus parlants

const byte ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10};
const byte capteurPins[] = {25, 27, 29, 31, 33, 35, 37, 39};

c’est pas la peine d’avoir les 2…

const ça veut dire qu’une variable ne va pas changer
byte ce n’est pas vraiment un type officiel, un raccourci Arduino, en C ou C++ on écrirait uint8_t, c’est à dire un entier non signé qui tient sur un octet. Vous aviez pris des int mais ça mange de la place en mémoire pour rien puisque un int est sur 2 octets et que les pins ne vont jamais dépasser 255 donc on peut se contenter de 1 octet.

Donc quand je fais

  for (byte i = 0; i < nbcapteurs; i++) {
    pinMode(ledPins[i], OUTPUT);
    pinMode(capteurPins[i], INPUT_PULLUP);
  }

ce n’est pas la peine de le refaire avec vos pins à vous en faisant

  int i;
  i = 0;
  while(i < NUMLED){
    pinMode(led[i], OUTPUT);
    pinMode(capteur[i], INPUT);
    i = i + 1;
  }

Bon moi j’avais mis un INPUT_PULLUP → comment sont câblés vos capteurs ? avec une résistance externe de PULL DOWN?

sinon ma fonction lireEtat() va aller lire pour vous tous les capteurs qu’elle vous rend dans son paramètre (etat) et la valeur retournée c’est le nombre de capteurs actifs. donc pas la peine de refaire tout votre grand “bazar” et je ne vois pas à quoi pourrait correspondre un digitalRead(total) puisque total n’est pas un numéro de pin… (mais le nombre de capteurs actifs)

Un octet c’est 8 bit. Chaque bit peut prendre la valeur 0 ou 1.
Dans ma fonction, si le bit n de etat est à 1 ça veut dire que le capteur N° n était activé. (si en INPUT_PULLUP car je compare avec LOW. Pour vous donc ce serait inversé)

On peut lire des bits dans un octet en utilisant bitRead()