Partage
  • Partager sur Facebook
  • Partager sur Twitter

problème String avec Serial.readString()

    5 juin 2020 à 22:33:02

    à tous bonjour,

    je fais un essai de transmission Bluetooth avec des HC05.
    je souhaite que le SLAVE envoie une commande vers le MASTER, pour allumer ou éteindre une LED.
    au début, ça fonctionne avec des 'char' quand je tape :

    pour l'ARDUINO qui supporte le SLAVE


    void loop() { if(digitalRead(BOUTON) == LOW) { Serial.print('1'); } if(digitalRead(BOUTON) == HIGH) { Serial.print('0'); } }


    pour l'ARDUINO qui supporte le MASTER


    void loop()
    {
        char texte;
           
        if(Serial.available() > 0)
        {
            texte = Serial.read();
       
            if(texte == '1')
            {
              digitalWrite(LED_pin, HIGH);
            }
                 
            if(texte == '0')
            {
              digitalWrite(LED_pin, LOW);
            }
        }       
    }

    mais si j'essaie avec des "string", avec les codes suivants, rien ne ce passe :


    pour l'ARDUINO qui supporte le SLAVE


    void loop()
    {
        if(digitalRead(BOUTON) == LOW)
        {
          Serial.print("ON");
        }
               
           if(digitalRead(BOUTON) == HIGH)
        {
          Serial.print("OFF");
        }
    }

    pour l'ARDUINO qui supporte le MASTER

    void loop()
    {
        String texte;
           
        if(Serial.available() > 0)
        {
            texte = Serial.readString();
       
            if(texte == "ON")
            {
              digitalWrite(LED_pin, HIGH);
            }
                 
            if(texte == "OFF")
            {
              digitalWrite(LED_pin, LOW);
            }
        }       
    }
    • Partager sur Facebook
    • Partager sur Twitter
      Staff 6 juin 2020 à 18:23:35

      Le problème, c'est que ton master émet l'état en permanence.

      Avec des caractères, tu vas te retrouver avec quelque chose dans ce style :

      111111111111111100000000011111111111111111111110000000

      Vu que tu lis caractères par caractères dès qu'il y en a un de disponible, cela fonctionne correctement.

      Par contre, avec des strings, tu vas te retrouver avec quelque chose dans ce style :

      ONONONONONONONONONONONONONONOFFOFFOFFOFFOFFONONONONONONON

      Mais la fonction readString ne peut pas deviner quand s'arrêter de lire la string.

      Dans l'exemple précédant, où commencerait chaque commande ? Pas évidant à dire non ? (est-ce "ON" ? ou "NON" ? ou "ONONON" ?)

      D'ailleurs, c'est écrit dans la doc : cette fonction s'arrête de lire après un timeout qui est de 1 seconde par défaut.

      Vu que le master émet en permanence, la fonction readString ne s'arrête jamais.

      Une solution simple serait de mettre un delay de 1500ms après chaque write dans le master, pour n'envoyer des données que toutes les 1.5s et donc laisser le temps à readString d'atteindre le timeout.

      Mais cela rendra ton programme beaucoup moins réactif.

      Une autre solution consiste à utiliser un caractère délimiteur (un saut de ligne par exemple) et de lire les données jusqu'à ce délimiteur.

      ////////// MASTER //////////
      
      void loop()
      {
          if(digitalRead(BOUTON) == LOW)
          {
            Serial.print("ON\n");
          }
          if(digitalRead(BOUTON) == HIGH)
          {
            Serial.print("OFF\n");
          }
      }
      
      ////////// SLAVE //////////
      
      string texte; // Variable globale, c'est important !
      
      void loop()
      {
      	if(Serial.available() > 0)
      	{
      		char c = Serial.read();
      		if ( c == '\n' ) {
      			if(texte == "ON") {
      				digitalWrite(LED_pin, HIGH);
      			}
      			if(texte == "OFF") {
      				digitalWrite(LED_pin, LOW);
      			}
      			texte = "";
      		} else {
      			texte += c;
      		}
      	}
      }





      -
      Edité par lorrio 6 juin 2020 à 18:25:38

      • Partager sur Facebook
      • Partager sur Twitter
        7 juin 2020 à 18:57:53

        effectivement ça marche mieux comme ça.

        d'autant plus que j'ai mis une émission uniquement au changement d'état des boutons.

        merci.

        • Partager sur Facebook
        • Partager sur Twitter
          Staff 7 juin 2020 à 20:07:56

          Émettre uniquement au changement d'état, c'est bien mais risqué si il n'y a pas d’acquittement.

          Si la transmission radio est perturbée au moment de l'envoie, le récepteur ne recevra pas le message et ne prendra donc pas en compte le changement.

          Émettre à interval régulier permet de s'affranchir de ce problème.

          Et le top du top pour s'assurer de la transmission tout en évitant de spammer les ondes radio, c'est de mettre en place un système d’acquittement.

          Lorsque le destinataire reçoit un message, il renvoie un acquittement (du genre "OK") à l'émetteur, ce qui permet de lui indiquer que le message a bien été reçu.

          Si l'émetteur ne reçoit pas l’acquittement, il en déduit que le message a été perdu et peut donc prendre l'initiative de le renvoyer un peu plus tard.

          • Partager sur Facebook
          • Partager sur Twitter

          problème String avec Serial.readString()

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          • Editeur
          • Markdown