Le moniteur série rajoute un caractère en deuxième position.

Bonjour à tous

Depuis quelques temps la saisie de texte au moniteur série fait des choses bizarres.

On a l’impression que le moniteur envoie le premier caractère puis fait un autre envoi pour le reste.
ça c’était tant que je recevais avec l’instruction “while Serial.available()”.

En fait le moniteur rajoute en deuxième position un caractère bizarre.
Chargé dans une variable de type char, ça donne (variable,DEC)=-1, et (variable,HEX)=FFFFFFFF.

Comme je n’ai rien trouvé, j’ai fait les mises à jour Java et réinstallé l’IDE. Ce qui n’a rien solutionné.

Voici un extrait de mon code, bien chargé de Serial.print()

//  programme HC12_debug2
//auteur Alain Renon / Mark J. Hugues
//date 13/03/2019
// modifié le
// matériel : arduino uno, HC-12 , LCD 16x2 en I2C
//
//NB Le moniteur de saisie doit être configuré "Nouvelle ligne" (à côté de 9600 baud)
//
//**********************************************************************************
                                        
/* 
HC12 Send/Receive Example Program 2 By Mark J. Hughes for AllAboutCircuits.com 
This code will automatically detect commands as sentences that begin with AT 
and both write them and broadcast them to remote receivers to be written.
Changing settings on a local transceiver will change settings on a remote receiver.
Connect HC12 "RXD" pin to Arduino Digital Pin 4
Connect HC12 "TXD" pin to Arduino Digital Pin 5
Connect HC12 "Set" pin to Arduino Digital Pin 6
Do not power HC12 via Arduino over USB.
*/
String nomPgm="HC12_debug2";
#include <SoftwareSerial.h>
const byte HC12TxdPin = 2; // "TXD" Pin on HC12
const byte HC12RxdPin = 3; // "RXD" Pin on HC12 
const byte HC12SetPin = 6; // "SET" Pin on HC12
char SerialByteIn; // Temporary variable 
char HC12ByteIn; // Temporary variable 
String HC12ReadBuffer = ""; // Read/Write Buffer 1 for HC12
String SerialReadBuffer = ""; // Read/Write Buffer 2 for Serial
boolean SerialEnd = false; // Flag to indicate End of Serial String
boolean HC12End = false; // Flag to indiacte End of HC12 String
// Software Serial ports Rx and Tx are opposite the HC12 Rx and Tx 
// Create Software Serial Port for HC12 
SoftwareSerial HC12(HC12RxdPin, HC12TxdPin);
char caractere='\0';

// écran LCD

#include <Wire.h>
#include <stdlib.h> 
#include <stdio.h> // sprintf
#include<LiquidCrystal_I2C.h>
#define I2C_ADDR 0x3F 
LiquidCrystal_I2C lcd(I2C_ADDR,16,2);


//**************        setup            ********************************************
void setup()
{
  Serial.begin(9600); // Open serial port to computer 
  
  HC12ReadBuffer.reserve(64); // Reserve 64 bytes for Serial message input 
  SerialReadBuffer.reserve(64); // Reserve 64 bytes for HC12 message input
  pinMode(HC12SetPin, OUTPUT); // Output High for Transparent / Low for Command
  digitalWrite(HC12SetPin, HIGH); // Enter Transparent mode
  delay(80); // 80 ms delay before operation per datasheet
  HC12.begin(9600); // Open software serial port to HC12 
  
  pinMode(HC12RxdPin,INPUT);//debug
  pinMode(HC12TxdPin,OUTPUT);//debug
  Serial.print(nomPgm);//debug
  Serial.print(" c'est parti mon kiki");//debug
  Serial.print("   SerialReadBuffer = -");
  Serial.print(SerialReadBuffer);
  Serial.print("-   HC12ReadBuffer = -");
  Serial.print(HC12ReadBuffer);
  Serial.print("-    caractere -");
  Serial.print(caractere,DEC);
  Serial.println("-");
  
// écran LCD
  Wire.begin();
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.begin();
  lcd.print("Hello, Maitre!");// j'aime bien un peu d'obséquiosité
  lcd.setCursor(0,1);
  lcd.print(nomPgm);
}

//***************        loop             *******************************************
void loop()
{
  while (HC12.available())// tant qu'on est en réception, on collecte
  {
    HC12ByteIn = HC12.read(); // Store each character from rx buffer in byteIn 
    Serial.print(" recu de distant : -");
    Serial.print( HC12ByteIn,DEC);
    Serial.println("-");
    HC12ReadBuffer += char(HC12ByteIn); // Write each character of byteIn to HC12ReadBuffer 
    if (!HC12End) HC12End = true; // Set HC12End flag to true 
  }// end while
  
  if (SerialByteIn!="x") SerialByteIn="x";// end if
  if (Serial.available())//tant qu'on a des choses à émettre, on collecte
  { 
    Serial.println("debut de reception");
    while (SerialByteIn!=(10,DEC))
    {
      SerialByteIn = Serial.read(); // Store each character in byteIn 
      Serial.print(" recu de saisie : -");
      Serial.print( SerialByteIn,HEX);
      Serial.println("-");
      SerialReadBuffer += char(SerialByteIn); // Write each character of byteIn to SerialReadBuffer 
      if (!SerialEnd) SerialEnd = true; // Set SerialEnd flag to indicate end of line 
    }// end while
  }//end if

  if (SerialEnd) //après collecte, on émet
  { 
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(SerialReadBuffer);//on affiche ce qu'on émet sur la deuxième ligne
    HC12.print(SerialReadBuffer); // Send local command to remote HC12 before changing settings 
    Serial.print("envoyé à HC12 distant, SerialReadBuffer : -"); // Echo command to serial 
    Serial.print(SerialReadBuffer); // Echo command to serial 
    Serial.println("-");
    if (SerialReadBuffer.startsWith("AT"))// Si c'est un paramétrage
    { 
      digitalWrite(HC12SetPin, LOW); // Exit command / enter transparent mode 
      Serial.print("pour HC12 local, SerialReadBuffer : -");
      Serial.print(SerialReadBuffer); // Echo command to serial 
      Serial.println(  "- "); // Echo command to serial. 
//      Serial.println(); // Echo command to serial 
      HC12.print(SerialReadBuffer); // Send command to local HC12 
      SerialReadBuffer = ""; // Clear SerialReadBuffer 
      delay(500); // Wait 0.5s for a response 
      digitalWrite(HC12SetPin, HIGH); // Exit command / enter transparent mode 
      delay(100); // Delay before proceeding
    }// end if
    if (SerialReadBuffer !="") SerialReadBuffer = "";//end if  Clear SerialReadBuffer 
    SerialEnd = false; // Reset serial end of line flag
  }// end if
  
  if (HC12End)// après réception, on traite
  {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("recu ");
    lcd.setCursor(5,0);
    lcd.println(HC12ReadBuffer);
    if (HC12ReadBuffer.startsWith("AT")) // Check to see if a command is received from remote
    {
      digitalWrite(HC12SetPin, LOW); // Enter command mode 
      delay(100); // Delay before sending command 
      Serial.print("envoyé au HC12 local : -"); // Echo command to serial. 
      Serial.print(HC12ReadBuffer); // Echo command to serial. 
      Serial.println(  "-"); // Echo command to serial. 
      HC12.print(HC12ReadBuffer); // Write command to local HC12 
      HC12ReadBuffer = ""; // Empty buffer 
      delay(500); // Wait 0.5 s for reply 
      digitalWrite(HC12SetPin, HIGH); // Exit command / enter transparent mode 
      delay(100); // Delay before proceeding 
      HC12.println("Remote Command Executed"); // Acknowledge execution mode
    } 
    else
    {
      Serial.print("reçu du HC12 distant : -"); // Echo command to serial. 
      Serial.print(HC12ReadBuffer); // Echo command to serial. 
      Serial.println("-"); // Echo command to serial. 
    }
    HC12ReadBuffer = ""; // Empty buffer 
    HC12End = false; // Reset flag
  }//en if

}// end loop

Je travaille avec un des deux arduino Uno indépendant équipé d’un écran LCD et l’autre connecté à un port de l’ordinateur.

Quand je remplace les HC-12 par une liaison filaire, l’écran LCD me dit recevoir mon texte plus 3 caractères indéterminés.

Quelqu’un connaît-il ce problème ?

Existe-t-il une façon de récupérer des HC-12 qui ne reçoivent plus les communications de l’arduino ? Cette dernière question, je la reposerai éventuellement sur un autre fil de discussion.

Ce bout de codewhile (SerialByteIn!=(10,DEC)) ne fait pas ce que vous pensez...ça compare avec DEC, pas 10 et vous lisez le buffer série sans savoir s’il y a des données

Si vous voulez comprendre comment bien écouter le port série (ou gérer un flux asynchrone genre keypad) vous pouvez jeter un oeil à mon petit tuto sur le sujet

Merci de répondre.
C'est vrai que j'ai encore du mal avec la gestion de caractères, voire avec le C tout court. J'avais déjà lu votre tuto mais je suppose que quelque chose m'a échappé, de plus je ne suis pas très doué en anglais.

J'ai remplacé (10,DEC) par ('\n') et la boucle s'arrête correctement de la même façon, en fin d'émission.

J'en profite pour poser la question induite (je n'ai pas trouvé la réponses dans les descriptions des utilisations de ces variables) quelle est la syntaxe pour comparer un caractère à sa valeur décimale ou hexa du code ascii ?

Revenons à mon problème

voici ce que m'envoie le moniteur quand je tape 123 [entrée] :

debut de reception
recu de saisie : -31-
recu de saisie : -FFFFFFFF-
recu de saisie : -32-
recu de saisie : -33-
recu de saisie : -A-
envoyé à HC12 distant, SerialReadBuffer : -1⸮23

Bonjour,

Tu lis le caractère avant qu'il ne soit effectivement reçu.

A l'intérieur du 'if (Serial.available())' tu as un while() qui lit les caractères sans même attendre qu'ils soient reçus.

Papa22:
quelle est la syntaxe pour comparer un caractère à sa valeur décimale ou hexa du code ascii ?

char toto;

if (toto=='A')   // teste si toto contient la lettre A
if (toto=='\n')   // teste si toto contient le caractère saut de ligne
if (toto==0x0A)   // teste si toto contient la valeur 0x0A hexadécimale, soit 10 en décimal, soit le saut de ligne
if (toto==10)   // teste si toto contient la valeur 10 en décimal, soit le saut de ligne

Pour cette partie, c'est super, merci.
Je vais tester ça d'ici une heure ou deux.

Concrètement quand vous écrivez

  if (Serial.available())//tant qu'on a des choses à émettre, on collecte
  { 
    Serial.println("debut de reception");
    while (SerialByteIn!=(10,DEC)) {
      SerialByteIn = Serial.read(); // Store each character in byteIn 
      ...
    }// end while
  }//end if

vous dites si j’ai au moins un caractère en alors j’en lis plein… => c’est pour cela que ça ne fonctionne pas, votre boucle while va vider le buffer de réception série plus rapidement que les données n’arrivent dedans et quand un read() n’a plus rien à lire, il retourne un entier qui vaut -1 ce qui s’écrit 0xFFFF (ou 0xFFFFFFFF sur une architecture 32 bits)

Il ne faut faire un read que si vous avez quelque chose de dispo ou tenir compte du fait que read retourne -1 s’il n’y avait rien à lire

Ok, les choses se mettent en place.
Mon problème, c'est que dans cette version ou dans la précédente (while (Serial.available()) et lecture), dans les deux cas le moniteur renvoie -1 en deuxième caractère. Donc sur une commande comme
"AT+C004" il envoie "A", -1, "T+C004". D'où mon code pour continuer à lire malgré le -1

En fait, j'aimerai lorsque je tape une phrase sur l'entrée moniteur la récupérer sur une seule série de données, comme ça l'a fait pendant plusieurs années.

Si nécessaire, je récupère une ancienne version de ce programme pour prouver mes dires.

Si tu tiens vraiment à utiliser les String il suffit de faire:

  if (Serial.available())//tant qu'on a des choses à émettre, on collecte
  {
    Serial.println("debut de reception");
    SerialReadBuffer = Serial.readStringUntil('\n');
    SerialEnd = true; // Set SerialEnd flag to indicate end of line
  }//end if

Celle-là je ne la connaissait pas, j'ai pourtant passé des heures sur internet pour résoudre mon problème.

Pour les String, non je ne tiens pas particulièrement à les utiliser plus que les tableaux de caractères, seulement j'avais pris sur un tuto HC12 un programme qui marchait et qui d'un coup s'est mis à ne plus fonctionner correctement.

Toujours est-il que ta solution n'explique pas d'où venait le fait que le message soit systématiquement scindé après le premier caractère, mais elle a l'avantage de fonctionner. Comme j'ai beaucoup d'autres choses à faire je n'explorerai pas plus avant.

Merci beaucoup à tous.

ta solution n'explique pas d'où venait le fait que le message soit systématiquement scindé après le premier caractère

mais si on vous l’a dit, vous ne lisez pas correctement ce qui arrive sur le port série, vous ne pouvez pas aller plus vite que la musique, s’il n’ya Pas encore la donnée suivante reçue sur le port série, vous ne pouvez pas la lire... et si vous essayez alors read() retourne -1

Je ne dois pas avoir les bons neurones en ligne.
J'essaierai de comprendre dès que j'aurai le temps pourquoi un programme qui marche cesse de fonctionner sans avoir été modifié.

Merci pour votre patience

Dans 99% des cas si ton programme cesse de fonctionner c'est qu'il comportait déjà une erreur potentielle et que les conditions de celle ci viennent de se produire.

Papa22:
J'essaierai de comprendre dès que j'aurai le temps pourquoi un programme qui marche cesse de fonctionner sans avoir été modifié.

c'est qu'il ne marche pas en fait...

Je dirais qu'il était tombé en marche

  while (HC12.available())// tant qu'on est en réception, on collecte
  {
    HC12ByteIn = HC12.read(); // Store each character from rx buffer in byteIn
    Serial.print(" recu de distant : -");
    Serial.print( HC12ByteIn,DEC);
    Serial.println("-");
    HC12ReadBuffer += char(HC12ByteIn); // Write each character of byteIn to HC12ReadBuffer
    if (!HC12End) HC12End = true; // Set HC12End flag to true
  }// end while

Dans cette boucle il n'y a pas de test avant chaque read. Mais, coup de bol, il y a pas mal de print qui ralentissent l'exécution du programme donc ça peut passer. Le ralentissement causé par les print peut donner le temps au caractère suivant d'arriver.
Il suffit d'un changement dans l'optimisation du code et suite à une recompilation ça peut ne plus fonctionner.
Ou si l'OS (ou le driver série) suite à une mise à jour du PC ne gère plus tout à fait pareil le flux sur le port série de la même manière.
Enfin, bref, le code n'était pas sûr.

Je pense que c'est suite à une des constantes mises à jour de Windows 10 que ça a cessé de fonctionner.
D'ici peu je me pencherai plus sérieusement sur ce type de communications. D'autant plus que pour les projets en cours un octet peut me suffire, il n'y a que pour les paramètres des HC12 que j'en avais besoin de plusieurs.

C'est que quand on commence les arduino il y a pas mal de choses à étudier en même temps. Et il arrive un âge où les choses se mettent en place moins vite qu'avant.
Merci à tous et à bientôt.