Traitement données après lecture port série

Bonjour,
débutant sur Arduino, je ne comprends pas pourquoi ce code ne fonctionne pas au niveau du test de valeur.
Merci de bien vouloir m'aider.

/*
 * Réception des données série
 */
  int Datalue;
  int Texte;

void setup() {
  // initialisation du port série
  Serial.begin(9600);
  // Init diode 13
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // lecture du port
  if (Serial.available()) {
    Datalue = Serial.read();
    Serial.write(Datalue);
      }
  // Test valeur lue

  if (Datalue == 1) {  
    digitalWrite(LED_BUILTIN, LOW);
  }
  if (Datalue == 2) {
    digitalWrite(LED_BUILTIN, HIGH);
  }
}

Bonjour,

Tu ne dis pas comment tu envoies les données mais si tu les envoies avec un terminal c'est un code ASCII que tu envoies.
Donc il faut comparer au caractère '1' ou '2'
if (Datalue == '1') {

Bonsoir,

Toujours mettre du code "exclusif" en complément de ce que l'on ne s'attend pas à traiter; à savoir:

  if (Datalue == 1) {  
    digitalWrite(LED_BUILTIN, LOW);
  }
  if (Datalue == 2) {
    digitalWrite(LED_BUILTIN, HIGH);
  }

à remplacer par:

  if (Datalue == 1) {  
    digitalWrite(LED_BUILTIN, LOW);
  }
  else if (Datalue == 2) {
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else {
    Serial.print("Value not expected: [0x");
    Serial.print(Datalue, HEX);
    Serial.println("]");
  }

Nous saurons alors quelle valeur est reçue et pas attendue :wink:

NB1: Maintenant entre nous, 1 et 2 ne sont pas des valeurs de caractères "imprimables" donc difficilement saisissable
NB2: Exécuter l'exemple Serial.read() et revenir vers nous

A suivre...

Bonsoir beber39

Lue comme ceci, Datelue donne 49 qui est le code ASCII du 1.
il faut ôter 48 pour avoir 1 en tant que valeur.
Corriges ton programme ainsi:

    Datalue = Serial.read();
	Datalue -= 48;
    Serial.println(Datalue);

Attention, dans la console, avec Serial.println(Datalue); s'afficherons également les caractères de terminaison que sont \n ou \r ou les 2:

Cordialement
jpbbricole

Merci à vous 3 pour vos réponses.
La solution de jpbbricole fonctionne ; super.
Pour info, par rapport au commentaires de claudius01, j’obtiens :
Avant saisie dans l'éditeur, affiche :

Value not expected: [0x0]
Après saisie de 1 ou 2 ou 3, affiche :
1Value not expected: [0x31]
2Value not expected: [0x32]
3Value not expected: [0x33]
Puis affiche :
Value not expected: [0xA]

Avec Serial.read(), affiche dans l'éditeur :
Après saisie de 1 :
I received: 49
I received: 10
Après saisie de 2 :
I received: 50
I received: 10

L'explication m’intéresse !
Bien cordialement à tous et merci pour votre aide.

Bonsoir beber39

Parce que tu n'as pas soustrait 0x30 au code ASCII pour n'en garder que le chiffre.

0xA (\n) est le caractère de terminaison ajouté lorsque tu fais Enter.

Cordialement
jpbbricole

Merci pour ces explications et encore pour votre aide.
Cordialement.

Bonsoir beber39

Si tu veux aller plus loin dans la commande de ton programme, par la ligne de commande, je peux te faire un exemple.

Cordialement
jpbbricole

Bonsoir jpbbricole,
et bien oui, je vais avoir encore besoin d'aide !
Je n'arrive pas à gérer un signal reçu tel que 45 par exemple, qui arrive en 2 caractères séparés.
Comment concaténer ces caractères pour pouvoir faire un test if sur la valeur ?
J'ai tenté diverses conversions sans succès ...
Merci.

  1. Tu reçois un premier caractère, tu places le nombre après conversion dans une variable.
  2. Tu reçois un second caractère, tu te dis "oh, si j'ai un nouveau caractère c'est que le chiffre reçu avant n'était pas les unités". Donc
    • tu multiplies le contenu de la variable par 10
    • tu ajoutes le nouveau chiffre que tu viens de recevoir
  3. tu répètes l'étape 2 jusqu'á ce que tu ais reçu la fin de ligne.

il va sans dire qu'à chaque fois il faut vérifier que le caractère reçu est bien un chiffre avant de faire l'étape 2

Bonsoir beber39

Je vais te montrer comment faire un traitement de commandes un peu plus "évolué" et qui permet d'aller plus loin dans la commande de ton programme.

A+
Cordialement
jpbbricole

Bonsoir beber39
J'ai fait "légérement" évoluer ton programme du post#1

Tu n'envoies plus de simples chiffres, mais des commandes:
Il y a 2 commandes pour la LED LED_BUILTIN (13);
LED2 pour allumer
LED1 pour éteindre

et 2 commandes pour la LED ledPwm (6), qui permet d'envoyer un paramètre à plusieurs chiffres;
PWMLED255 pour allumer la LED en plein.
PWMLED127 pour allumer la LED à moitié.
PWMLED10 pour allumer la LED un tout petit peu.
PWMLED0 pour éteindre la LED.
Pour commander une LED en PWM, le port de l'Arduino doit avoir cet attribut ~.

Recherches dans les références Arduino la signification de ces fonctions comme:

		DataLue.trim(); // Nettoyage de Datalue
		DataLue.toUpperCase(); // Tout en majuscule

At, surtout, n'hésites pas à poser des questions :wink:

Le programme:

/*
* Réception des données série
*/
String DataLue;
//int Texte;
const int ledPwm = 6; // Pour la LED variable

void setup()
{
	// initialisation du port série
	Serial.begin(9600);
	// Init diode 13
	pinMode(LED_BUILTIN, OUTPUT);
	pinMode(ledPwm, OUTPUT);
}

void loop()
{
	// lecture du port
	if (Serial.available())
	{
		DataLue = Serial.readStringUntil('\n'); // Lecture du port série jusqu'à nouvelle ligne \n
	
		DataLue.trim(); // Nettoyage de Datalue
		DataLue.toUpperCase(); // Tout en majuscule
		Serial.println("Commande recue: " + DataLue);
		
		if (DataLue.startsWith("LED")) // Si commande de la LED
		{
			DataLue.replace("LED", ""); // Supprimer la commande pour ne garder que le paramètre.
			ledCommande(DataLue.toInt());  // Dans le cas d'une commande comme LED3 il ne reste que 3 que l'on transforme en numérique
		}
		else if (DataLue.startsWith("PWMLED")) // Si commande de la luminosité de la LED
		{
			DataLue.replace("PWMLED", ""); // Supprimer la commande pour ne garder que le paramètre.
			int pwmValeur = DataLue.toInt();
			analogWrite(ledPwm, pwmValeur); // Allumage de la LED à pwmValeur
		}
		else
		{
			Serial.println("Commande inconnue " + DataLue);
		}
	}
}

void ledCommande(int Data) // Commander la LED en fonction de Data
{
	if (Data == 1)
	{
		digitalWrite(LED_BUILTIN, LOW);
	}
	if (Data == 2)
	{
		digitalWrite(LED_BUILTIN, HIGH);
	}
}

A+
Cordialement
jpbbricole

Merci grandement, jpbbricole, pour votre aide.

Je vais tester ce programme très complet et comprendre son fonctionnement pour l'adapter.
Mon objectif est de piloter des sorties analogiques en fonction de la valeur reçue sur l'entrée série.

Cordialement.

Bonjour berber39

Alors la commande PWMLED est faite pour toi :wink:

Bonne journée
jpbbricole