Je ne comprends pas pourquoi mon code marche

Bonjour,

c'est une situation un peu bizarre, mais mon code marche sans que je ne comprenne pourquoi :astonished:.
Le but de mon code est d'allumer certaines LEDs en fonction du caractère entré ( formant un caractère selon le code Braille avec la disposition des LEDs ), et tant que l'on a pas entré un nouveau caractère, les LEDs restent allumées.
En effet, je ne m'attendais pas à ce qu'il fonctionne tel que je le voulais et pourtant (j'avais changé certaines valeurs sans trop y croire ) si ! Je crois que c'est à cause des valeurs renvoyées par la librairie Sérial mais je ne comprends absolument pas pourquoi.
La valeur que j'ai changé et qui a rendu mon code fonctionnel est dans la fonction loop ( à la ligne "if(Serial.available()>1)" ).

Si vous pouviez m'éclairer, ce serait vraiment très sympa :slight_smile: Voici le code :

Variables globales :

int ledHG=12; // led en haut à gauche
int ledHD=11; // led en haut à droite
int ledMG=10; // led au milieu à gauche
int ledMD=9;  // led au milieu à droite
int ledBG=8;  // led en bas à gauche
int ledBD=7;  // led en bas à droite
int boutonGauche=5; // bouton à gauche
int boutonDroit=4; // bouton à droite
boolean etat= true ;

Fonction pour éteindre les Leds :

void eteindreLed(){
   digitalWrite(ledHG,LOW); // éteindre les LEDs
   digitalWrite(ledHD,LOW); // éteindre les LEDs
   digitalWrite(ledMG,LOW); // éteindre les LEDs
   digitalWrite(ledMD,LOW); // éteindre les LEDs
   digitalWrite(ledBG,LOW); // éteindre les LEDs
   digitalWrite(ledBD,LOW); // éteindre les LEDs 
}

Fonction pour allumer la LED en fonction du caractère entré :

void allumerLed(char lettre) {
 
    if (lettre>=97 && lettre<=122) // upToLowerCase
    lettre=lettre-32;
    
    switch (lettre){        // Allumer les LEDs
      
    case 65: // A
    digitalWrite(ledHG,HIGH);
    break;
    
    case 66: // B
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledMG,HIGH);
    break;
    
    case 67: // C
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    break;
    
    case 68: // D
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMD,HIGH);
    break;
    
    case 69: // E
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledMD,HIGH);
    break;
    
    case 70: // F
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMG,HIGH);
    break;
    
    case 71: // G
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledMD,HIGH);
    break;
    
    case 72: // H
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledMD,HIGH);
    break;
    
    case 73: // I
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMG,HIGH);
    break;
    
    case 74: // J
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledMD,HIGH);
    break;
    
    case 75: // K
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledBG,HIGH);
    break;
    
    case 76: // L
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledBG,HIGH);
    break; 
    
    case 77: // M
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledBG,HIGH);
    break;
    
    case 78: // N
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMD,HIGH);
    digitalWrite(ledBG,HIGH);
    break;
    
    case 79: // O
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledMD,HIGH);
    digitalWrite(ledBG,HIGH);
    break;
    
    case 80: // P
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledBG,HIGH);
    break;
    
    case 81: // Q
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledMD,HIGH);
    digitalWrite(ledBG,HIGH);
    break;
    
    case 82: // R
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledMD,HIGH);
    digitalWrite(ledBG,HIGH);
    break;
    
    case 83: // S
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledBG,HIGH);
    break;
    
    case 84: // T
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledMD,HIGH);
    digitalWrite(ledBG,HIGH);
    break;
    
    case 85: // U
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledBG,HIGH);
    digitalWrite(ledBD,HIGH);
    break;
    
    case 86: // V
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledBG,HIGH);
    digitalWrite(ledBD,HIGH);
    break;
    
    case 87: // W
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMG,HIGH);
    digitalWrite(ledMD,HIGH);
    digitalWrite(ledBD,HIGH);
    break;
    
    case 88: // X
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledBG,HIGH);
    digitalWrite(ledBD,HIGH);
    break;
    
    case 89: // Y
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledHD,HIGH);
    digitalWrite(ledMD,HIGH);
    digitalWrite(ledBG,HIGH);
    digitalWrite(ledBD,HIGH);
    break;
    
    case 90: // Z
    digitalWrite(ledHG,HIGH);
    digitalWrite(ledMD,HIGH);
    digitalWrite(ledBG,HIGH);
    digitalWrite(ledBD,HIGH);
    break;
    }
    
 }

Fonction setup :

void setup(){
  
Serial.begin(9600);
pinMode (ledHG,OUTPUT);
pinMode (ledHD,OUTPUT);
pinMode (ledMG,OUTPUT);
pinMode (ledMD,OUTPUT);
pinMode (ledBG,OUTPUT);
pinMode (ledBD,OUTPUT);
pinMode (boutonGauche,INPUT);
pinMode (boutonDroit,INPUT);
digitalWrite(boutonGauche,HIGH);
digitalWrite(boutonDroit,HIGH);
 
}

Fonction loop :

void loop (){

char lettre = Serial.read();
do {
  allumerLed(lettre);
  if(Serial.available()>1){
  eteindreLed();
  etat=false;
  }
} while ( etat==true);

etat=true;
}

Je comprends pas trop le rôle de la boucle do. Perso je trouve plus simple et plus clair de faire :

void loop (){

  if(Serial.available()){
     eteindreLed();
     allumerLed(Serial.read());
    }

}

En fait, vu que ca ne marchait, j'ai essayé plein de méthodes différentes pour parvenir à faire ce que je souhaitais.
Et j'ai essayé votre fonction loop :
en entrant un caractère dans le moniteur série, les LEDs correspondant au caractère ( c'est du Braille, les LEDs diffèrent en fonction du caractère entré ) s'allument un dixième de seconde, puis s'éteignent directement.

En fait dans mon code précédent, je ne comprends pas pourquoi ca marche avec "if(Serial.available()>1)" dans la fonction loop et pas if(Serial.available()>0) car logiquement ça devrait être ça non ?

Mais il ne marche pas du tout ou bien ça fait pas ce que tu demandes ?

EDIT : il semble y avoir un soucis puisque mon code ne marche pas, et ce dysfontionnement laisse entendre que 2 caractères arrivent. Ce qui expliquerait pourquoi ton code fonctionne avec >1 et pas >0. Par quoi tu passes pour envoyer ton caractère à l'arduino ?

Ton 1 et ton 0 sont un booléen, ce qui veut dire que 0 à la valeur 0 et tout ce qui est au dessus à la valeur de 1 (2=1, 3447=1... etc)

Donc tu testes ton entrée sérial et si ta valeur est supérieure à 1 ça fonctionne..... car elle est toujours égale à 1

et si tu testes avec 0, ça revient au même car en fait tu testes si quelque chose entre sur le port série.... donc ça teste "vide" ou "plein"

Et toi tu teste plus grand que "vide" ou plus grand que "plein".... ce qui en terme de valeur revient au même :grin:

Serial.available() ne renvoi pas un booleen, mais le nombre byte dispo dans le buffer

Ah ouais, c'est juste :grin: ...... joyeux Noël.... comment ça c'est déjà passé XD

Jean-François:
Ah ouais, c'est juste :grin: ...... joyeux Noël.... comment ça c'est déjà passé XD

bonjour JF
Alors ? "on" a abusé d'humagne ? :grin:

En fait le but de mon programme est le suivant :

lorsqu'on entre une lettre dans le moniteur série ( qui est intégré au compilateur ), certaines LEDs s'allument ( en fonction du code Braille). Et puis elles restent allumées tant que l'on n'entre pas un nouveau caractère. Si on entre un nouveau caractère, les LEDs s'allument en fonction de ce nouveau caractère et restent allumées. Et ainsi de suite ^^

La ce qui me perturbe c'est que lorsqu'on utilise la fonction Serial.read(), la fonction Serial.available() devrait renvoyer 0 ( du moins, si l'on a rentré qu'un seul caractère. Et puis le programme les LEDs et vérifient si il y a d'autres caractères dans le buffer. Logiquement on devrait utiliser if ( Serial.available()>0) mais ca ne marche pas ! Les LEDs s'allument un dixième de seconde puis s'éteignent. Je me casse la tête pour comprendre pourquoi, en vain ! :astonished:

Artouste:
bonjour JF
Alors ? "on" a abusé d'humagne ? :grin:

Salut Artouste,

Non, juste pas beaucoup dormi cette nuit :grin:

@BlackPirate : essaye en rajoutant un delay :

void loop (){

  if(Serial.available()){
Serial.println(Serial.available()); //histoire de voir si c'est bien une question de nombre de caractère
delay(20);
     eteindreLed();
     allumerLed(Serial.read());
    }

}

Alors j'ai essayé ton code :

quand je rentre 1 caractère dans le moniteur série : il affiche 1, saute une ligne, réaffiche 1. Pourtant il ne devrait afficher qu'un seul 1, non ?

Essaye en mettant le delay avant le println

Ca m'affiche :

2
1

Et les LEDs s'allument un dixième de seconde puis s'éteignent. Mais mon code d'avant marchait, le problème n'est pas de faire un code qui marche. Je veux juste savoir pourquoi mettre 1 et pas 0 à la ligne if ( Serial.available()>0). Ca m'intrigue cette histoire ! :grin:

Si tu utilises le moniteur série de l'Arduino, et que tu rentre "1" suivit de "Entrée" alors par défaut le caractère "1" est suivit du caractère de fin de ligne \x0D (appellé Carriage Return)

Tu peux configurer le moniteur série pour envoyer :

  • rien (juste tes caractères)
  • tes caractères suivit de CR (\x0D)
  • tes caractères suivit de CR (\x0D) puis LF (\x0A)

Ceci explique cela

BONNES FETES DE FIN D'ANNEE !!!!!!!

Mystère résolu ! Merci beaucoup à vous tous pour votre aide :slight_smile:

Et bonnes fêtes de fin d'année à vous aussi :slight_smile: