tableau de caractères

bonjour, il y a quelques semaine j’ai fais un post pour avoir de l’aide sur mon projet, j’ai réussi a avancer.
Maintenant j’ai un tableau et je dois faire le checksum Xor de mon tableau. Mon programme fonction et fais se que j’attends de lui lorsque j’écris au préalable dans les déclaration de variables :

unsigned char message[10] = Hello;

mais se que j’ai besoin, c’est de pouvoir modifier ce tableau avec le moniteur série, voici mon code :

char message[10];
 unsigned char checksum = 0;
 unsigned char check = 0x74;
 
 
 void setup () {
  Serial.begin(9600); //Début de la liaison série sur les Serial
  Serial1.begin(9600); //Début de la liaison série sur les Serial 1
 }

 void loop () {
      
  //Envoie des données seulement si il en reçoit
  Serial.available ();
    message[10] = Serial.read(); //message prend la valeur reçu
    checksum = check ^ message[0] ^ message[1] ^ message[2] ^ message[3] ^ message[4] ^ message[5] ^ message[6] ^ message[7] ^ message[8] ^ message[9];

     Serial1.print("<ID00><L1><PA><FE><MA><WC><FE>"); // on envoie en première partie les codes non variant utile pour l'afficheur
     Serial1.print(message);  // on envoie le texte lu dans le moniteur série
     Serial1.print(checksum); // on envoie la valeur du checksum calculer 
     Serial1.println("<E>"); //commande de fin d’envoi de données pour l'afficheur
     Serial.print(checksum);// permet de vérifier sur le moniteur série si le checksum calculer est le bon
  }
  delay(2000);
 }

mais la le code ne fonctionne plus du tout…
comment faire pour que

message[10]

prenne la “valeur” que j’écris dans le moniteur série?
cette “valeur” peux être un mot comme “Hello” ou “test” ou des chiffres comme “123”
Chimorin

Chimorin:
comment faire pour que
message[10]
prenne la "valeur" que j'écris dans le moniteur série?
cette "valeur" peux être un mot comme "Hello" ou "test" ou des chiffres comme "123"

message[10] c'est un unique caractère, comme 'a' ou 'b', ce n'est pas une chaîne de caractère comme "Hello" ou "Test"...

donc soit vous lisez un par un les caractères en provenance du port série (bonne option), soit vous utilisez des méthodes comme ReadString() (avec les soucis qui vont avec sur le timing etc) pour lire un lot de caractères et vous utilisez par exemple strcpy() pour copier ce qui a été lu dans votre buffer.

J-M-L:
donc soit vous lisez un par un les caractères en provenance du port série (bonne option)

comment je peux lire un par un mes caractères?
Chimorin

Bonjour,

Pour lire la chaine de caractère que tu reçoit du moniteur série tu as deux méthodes

  • soit tu lis caractère par caractère sur la liaison série et tu les range au fur et à mesure dans message

  • soit tu utilises la fonction de lecture d'une suite de caractère ce qui donne

 if (Serial.available())
  {
    int lg=Serial.readBytes(message, sizeof message-1);
    message[lg]=0;        // marque la fin de la chaine

    // --- suite du traitement ici ---- //
  }

L'inconvénient est que si tu reçois moins de 9 caractères, tu va être bloqué jusqu'à échéance du time-out
Pour faire les choses bien, il faudrait que la chaine envoyée se termine par un caractère connu par exemple fin de ligne (lf)

j'ai utilisé et remanié ton code pour qu'il soit conforme au mien, il affiche bien se que je lui demande mais le checksum est faux
il devrait m’afficher 36 mais la il m'affiche 3C
d'où peux venir cette faute?

en mode pas beau, à ne pas faire

const byte tailleMax = 50;
char message[tailleMax + 1];


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

void loop() {

  message[0] = '\0'; // on vide le buffer
  Serial.println(F("Entrez une phrase:"));

  while (!Serial.available()); // on attend une entrée

  strncpy(message, Serial.readString().c_str(), tailleMax); // pas beau ! ne faites pas ça. timeout de 1 sec, usage de le classe String (on pourrait aussi utiliser Serial.readBytes
  message[tailleMax] = '\0'; // au cas où..

  Serial.print(F("vous avez saisi:"));
  Serial.println(message);
}

en mode où vous contrôlez ce qu'il se passe finement:

const byte tailleMax = 50;
char message[tailleMax + 1];
byte position = 0;

void setup() {
  Serial.begin(115200);
  message[0] = '\0'; // on vide le buffer
  Serial.println(F("Entrez une phrase:"));
}

boolean lireEntreeJusque(char marqueDeFin)
{
  int c;

  if (Serial.available()) {
    c =  Serial.read();
    if ((c != -1) && (c != marqueDeFin)) {
      message[position++] = (char) c;
      message[position] = '\0';
      if (position >= tailleMax) position = tailleMax - 1; // évite de déborder
    }
    return (c == marqueDeFin); // renvoie vrai si on a détecté le caractère de fin de chaine
  }
  return false;
}

void loop() {
  if (lireEntreeJusque('\n')) {
    Serial.print(F("vous avez saisi:"));
    Serial.println(message);
    position = 0; // on se prépare à saisir une nouvelle entrée
    message[0] = '\0';
    Serial.println(F("Entrez une phrase:"));
  }
}

Tu calcules le checksum sur 10 caractères alors que tu en as sans doute moins

Il faut que tu calcules le chk avec une boucle qui prend en compte le nombre de caractères
Pour plus de lisibilité tu peux faire une fonction
par exemple:

byte crc(char message[], int lg)

@kamill, lorsque je demande un checksum de tous les caractères, même si j’en est moins de 10, ca ne medifie pas mon résultat car 0x74^0x00=0x74 donc ce n’est pas gênant d’avoir de la place en plus.
la mon afficheur fais se que je lui demande, quand j’écris un mot dans mon moniteur série cela s’affiche, mais le checksum n’est pas celui attendu et le plus bizzare c’est que même avec un checksum faux mon afficheur affiche se que je lui demande avec avec un carré plein a la suite du mot.
le code :

 char message[21];
 unsigned char checksum = 0;
 unsigned char check = 0x74;
 
 
 void setup () {
  Serial.begin(9600); //Début de la liaison série sur les Serial
  Serial1.begin(9600); //Début de la liaison série sur les Serial 1
 }

 void loop () {
      
  //Envoie des données seulement si il en reçoit
  if (Serial.available())
  {
    int lg=Serial.readBytes(message, sizeof message-1);
    message[lg]=0;        // marque la fin de la chaine
    
    checksum = check ^ message[0] ^ message[1] ^ message[2] ^ message[3] ^ message[4] ^ message[5] ^ message[6] ^ message[7] ^ message[8] ^ message[9] ^ message[10] ^ message[11] ^ message[12] ^ message[13] ^ message[14] ^ message[15] ^ message[16] ^ message[17] ^ message[18] ^ message[19] ^ message[20];

     Serial.print("<ID00><L1><PA><FE><MA><WC><FE>"); // on envoie en première partie les codes non variant utile pour l'afficheur
     Serial.print(message);  // on envoie le texte lu dans le moniteur série
     Serial.print(checksum, HEX); // on enoie la valeur du checksum calculer 
     Serial.println("<E>"); //commande de fin d'envoie de données pour l'afficheur
     Serial1.print("<ID00><L1><PA><FE><MA><WC><FE>"); // on envoie en première partie les codes non variant utile pour l'afficheur
     Serial1.print(message);  // on envoie le texte lu dans le moniteur série
     Serial1.print(checksum, HEX); // on enoie la valeur du checksum calculer 
     Serial1.println("<E>"); //commande de fin d'envoie de données pour l'afficheur
     
  
  delay(2000);
 }
 }

Comme tu n'initialises pas le buffer avant réception, il peut contenir n'import quoi après les caractères reçus (sauf peut être la première fois car le framework arduino semble initialiser la mémoire à 0).

Comment tu sais que ton checksum est incorrect?

car j'ai effectuer le checksum avec 2 valeurs :"Hello" et "test" sur papier et j'ai ensuite envoyer dans l'afficheur directement la trame d'initialisation de l'afficheur suivie de l'une de ses valeurs et le checksum associer et cela à fonctionner.
Mais la je met des variables a la place de "Hello" et du checksum car je dois écrire un mot sur le moniteur série et le checksum dois etre calculer automatiquement en fonction du mot écris et quand je test avec "Hello" ou "test", les valeurs de checksum donner par l'arduino et les valeurs que j'ai calculer a la main ne sont pas identiques.
mais ce problème la est résolut car j'ai 6 de trop a chaque fois (ex : je dois trouver 36 et j'ai 3C ou je dois trouver 62 et j'ai 68) j'ai donc rajouter :

 checksum = checksum - 0x06;

et c'est bon
Maintenant mon nouveau problème c'est que j'ai un carré plein qui suit se que j'ai écris sur l'afficheur...

C'est bizarre ce que tu dis car pour moi
Hello -> crc 0x42
test -> crc 0x16

elle est configuré comment votre console série ? envoyez vous \r \n à la fin de la ligne? est-ce que par hasard vous n'auriez pas le \r qui est aussi enregistré dans le buffer?

Bien vu J-M-L! Je pense aussi qu'il y a un \n à la fin du message

effectivement, le fait d'appuyer sur entré ou de cliquer sur envoyer dans le moniteur série du logiciel arduino, ça me rajoute un caractère ! je vais l'enlever

J'avais un autre soucis, c'est que l'afficheur me donnais un carré en plus après le mot écrit mais c'est juste que si le mot ne prenait pas les 10 places qui lui était attribuer, le code me fais un carré en plus, maintenant tout est régler

Merci à tous!!

Chimorin

je suppose que vous voulez dire que vous allez enlever le CR et/ou LF de la fin de la chaîne? le pb avec les fonctions toutes faites de lecture du port série c'est que s'il n'y a pas de caractère marquant la fin d'une saisie, vous dépendez du timeout pour décider que tout a été envoyé... ça ralentit l'experience utilisateur c'est pour cela qu'il vaut mieux faire cela à la main.