Reception chaine de caractère Port Série et Affichage LCD ???

Salut salut,

j'avance mon projet doucement mais surement,
ça fait quelques jours que je bloque sur un bout de programme après pas mal de recherche et de test effectué j'avoue que j'ai besoin d'un coup de main.

Depuis mon interface VB (forms) j'envoie une chaine de caractère via une TextBox sur le Port Série, cette chaine de caractère contient en réalité le pseudo d'un joueur, Pour l'envoi pas de soucis.

Private Sub validez_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles validez.Click
        Dim pseudo As String
        pseudo = TextBox1.Text
        SerialPort1.Write(pseudo)
    End Sub

voici un bout de mon programme qui fonctionne très bien, j'attribue une couleur par équipe,

ce que je voudrais maintenant, c'est donc de recevoir le pseudo du joueurs sur le port série et l'afficher sur mon LCD brancher à l'Arduino,

j'ai bien compris que Serial.read(); ne lit qu'un seul caractère à la fois et qu'il faudrait donc créer une boucle mes j'ai vraiment beaucoup de mal à la mettre en œuvre sans détruire le reste de mon code

void loop()
{


//choix des couleurs d'équipes;
 while (Serial.available() > 0) {
   int index=Serial.read(); // lire un premier caractère
   
   
   
  


   // filtrer : il doit etre une lettre minuscule ou majuscule
   if(index >= 'A' && index <= 'z'){
     int valeur = Serial.parseInt();
     
     // controle eventuel de la valeur
     //Serial.print("valeur : "); Serial.println(valeur);


     // traitement equipe Orange;
     switch(index){ 
     case 'O': 
       if(valeur > 0){
         digitalWrite(ledR1,HIGH);
         digitalWrite(ledR2,HIGH);
       }
       else {
         digitalWrite(ledR1,LOW);
         digitalWrite(ledR2,LOW);
       }
       break;
       

    // traitement equipe Bleu;
     case 'B': 
       if (valeur > 0){
        digitalWrite(LED,HIGH);
         digitalWrite(LED2,HIGH);
     }
      else {
         digitalWrite(LED,LOW);
         digitalWrite(LED2,LOW);
       }
    }
 }
 delay(10); 
}

Merci à vous

Petit up ^^

Tu peux commencer par scinder tes différentes actions en fonctions dédiées. Par exemple, dans le loop, tu teste s'il y a des données à lire. Si oui, tu appelles une fonction lireDonnees(), dans laquelle tu place la boucle while de lecture. Ainsi cette fonction ne sera appelée que lorsque qu'elle est nécessaire.
Dans cette fonction, tu peux aussi définir un marqueur, tel que bool donneesRecues. Déclaré avant le setup, tu le mets par défaut à 0, et tu le passe à 1 lorsque tu as reçu une donnée complète.

Ensuite, dans la boucle loop(), tu teste ce marqueur donneesRecues, s'il vaut 1 alors tu déclenche la mise à jour de ton affichage. De préférence dans une fonction dédiée également. Ca n'est pas forcément nécessaire, mais ce sera plus confortable lorsque ton programme avancera et se complexifiera.

troisiemetype:
Tu peux commencer par scinder tes différentes actions en fonctions dédiées. Par exemple, dans le loop, tu teste s'il y a des données à lire. Si oui, tu appelles une fonction lireDonnees(), dans laquelle tu place la boucle while de lecture. Ainsi cette fonction ne sera appelée que lorsque qu'elle est nécessaire.
Dans cette fonction, tu peux aussi définir un marqueur, tel que bool donneesRecues. Déclaré avant le setup, tu le mets par défaut à 0, et tu le passe à 1 lorsque tu as reçu une donnée complète.

Ensuite, dans la boucle loop(), tu teste ce marqueur donneesRecues, s'il vaut 1 alors tu déclenche la mise à jour de ton affichage. De préférence dans une fonction dédiée également. Ca n'est pas forcément nécessaire, mais ce sera plus confortable lorsque ton programme avancera et se complexifiera.

Merci pour ta réponse mais je doit t'avouer que sans exemple j'ai un peu de mal à capter

Quelque chose de ce genre-là:

//Cette variable va nous permettre de savoir si des données reçues sont prêtes à être utilisées
bool dataReady = false;

//Cette variable stocke le pseudo reçu
String playerName = "";

void setup(){
	Serial.begin(115200);
}

void loop(){
	//Si on a des données disponibles, on va les traiter
	if(Serial.available()){
		//On récupère la valeur renvoyée par la fonction
		dataReady = receiveData();
	}

	//Si nous avons un nom de joueur complet, on met à jour le LCD.
	//Autrement, rien, le loop se termine et recommence.
	if(dataReady){
		updateLcd();
	}

}

bool receiveData(){
	//tant que l'on a des données, on les ajoute à la chaine playerName
	//On vérifie aussi que l'on n'a pas des données arrivées mais non encore traitées
	while(Serial.available() && !dataReady){
		char receivedChar = Serial.read();
		//Si nous avons un caractère alphabétique, nous l'ajoutons à la chaine playerName
		if(receivedChar >= 'A' && receivedChar <= 'z'){
			playerName += Serial.read();
		}
		//Si nous avons une fin de ligne, le nom a été complètement reçu
		if(receivedChar == '"\r' || receivedChar == '"\n'){
			//On renvoie true
			return true;
		}
	}
	//Si les données reçues n'ont pas permis de trouver une fin de ligne, c'est qu'il faudra en recevoir encore.
	//On renvoit false
	return false;

}

void updateLcd(){
	//Ici tu mets le code qui te permet de mettre à jour ton écran.
	//Une fois la mise à jour réalisée, il est important d'effacer la variable contenant le nom,
	//pour préparer la réception suivante
	playerName = "";
	//Et également de remettre à zero dataReady, pour que la boucle de réception puisse à nouveau tourner.
	dataReady = false;

}

A adapter à ton besoin, bien entendu. NB: je n'ai pas testé ce code, il est donc à prendre pour ce qu'il est: un exemple de structure.

Franchement merci, j'ai réussi à recevoir et afficher la chaine en écrivant simplement ceci, du coup pourquoi ce casser la tête à faire des boucles alors qu'en 3 lignes c'est réglé.

       String str = Serial.readString();
        lcd.setCursor(1,1);
        lcd.print(str);

Ah oui, bien vu. je suis tellement habitué à faire les choses moi-même que j'en oublie qu'il y a des fonctions dédiées... :slight_smile:

Cela dit, l'inconvénient de Serial.readString() est que c'est une fonction bloquante, en tout cas dans la limite du timeout spécifié avec setTimeout(). Par défaut 1 seconde pour chaque caractère lu, ou moins si explicitement spécifié.
Après, ça n'est un problème que si le temps est précieux dans ton programme, ce qui n'est pas forcément le cas!

Parcontre maintenant si je veux choisir la couleur de l'équipe, je clique sur bleu par exemple dans mon interface VB, ce dernier envoi la valeur B3 qui correspond à l'allumage des Led pour l'équipe bleu,

je c'est pas pourquoi ça ne fonctionne pas, de plus la valeur donc B3 ou (O2 pour équipe orange) s'affiche sur mon LCD lorsque je clique dessus .

//Variable globale:
int réception = Serial.available();

void setup ()
//Serial.begin (9600);

void loop()
{
 if (reception > 0){
    String str = Serial.readString();
        lcd.setCursor(1,1);
            lcd.print(str);
}

//choix des couleurs d'équipes;
 while (Serial.available() > 0) {
   int index=Serial.read(); // lire un premier caractère


   // filtrer : il doit etre une lettre minuscule ou majuscule
   if(index >= 'A' && index <= 'z'){
     int valeur = Serial.parseInt();
     
     // controle eventuel de la valeur
     //Serial.print("valeur : "); Serial.println(valeur);


     // traitement equipe Orange;
     switch(index){ 
     case 'O': 
       if(valeur > 0){
         digitalWrite(ledR1,HIGH);
         digitalWrite(ledR2,HIGH);
       }
       else {
         digitalWrite(ledR1,LOW);
         digitalWrite(ledR2,LOW);
       }
       break;
       

    // traitement equipe Bleu;
     case 'B': 
       if (valeur > 0){
        digitalWrite(LED,HIGH);
         digitalWrite(LED2,HIGH);
     }
      else {
         digitalWrite(LED,LOW);
         digitalWrite(LED2,LOW);
       }
    }
 }
 delay(10); 
}

Faudrait lire un manuel de C ou C++...

Quand vous déclarez int réception = Serial.available(); en variable globale vous avez une seule initialisation à ce que retourne available() à ce moment... donc quand dans la boucle vous faites if (reception > 0){ ça ne va pas appeler nouveau la fonction available()...

Il faut tout revoir votre gestion de la communication série, laisser tomber la classe String au passage et gérer vous même le protocole de communication

Une bonne source c'est de lire et pratiquer ce qu'il y a à ici (en anglais)