Effacer la matrice existante lors de lobtention dune nouvelle commande série

Je commence à créer mon premier projet Arduino mais je rencontre des problèmes de communication série.

Jobtiens des données série de la console et je les stocke dans un tableau de caractères appelé « data ».

Ensuite, quand jenvoie un nouveau message de console à lArduino, je veux quil efface le tableau « data » existant et ne stockez que les nouvelles données dans ce tableau.

Je ne comprends pas exactement ce qui ne va pas avec mon code: je crois que ces instructions Serial.available () imbriquées ne fonctionnent pas mais je nai aucune idée sur la façon de corriger le code.

Les données sont correctement stockées par lArduino mais elles concaténent la chaîne la plus récente avec lancienne.

int count = 0; char data[30]; boolean dataComplete = false; void setup() { Serial.begin(9600); } void loop() { if (Serial.available() > 0){ if (dataComplete == true){ Serial.println("There is data already, clearing..."); char data[30]; dataComplete = false; } if (dataComplete == false){ Serial.println("New command, collecting..."); while (Serial.available()>0){ char character = Serial.read(); data[count] = character; count++; } dataComplete = true; } } Serial.print("Command received: "); Serial.println(data); delay(1000); } 

Merci davance!

Réponse

Pour effacer un tableau, vous feriez:

for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0; 

ou

memset(data, 0, sizeof(data)); 

, qui fait la même chose en utilisant une fonction de bibliothèque.

Cependant, parce que les chaînes des caractères (ne faisant pas référence aux objets « String » ici) se terminent par un zéro octet, seul le premier octet doit être remis à zéro:

data[0] = (char)0; 

le fera .

Réponse

Tout dabord, ceci est un excellent exemple de limportance des espaces. Votre code est vraiment difficile à lire tel quel, car le survolant, il semble que la seconde instruction if soit en dehors de la première.

Code fixe:

int count = 0; char data[30]; boolean dataComplete = false; void setup() { Serial.begin(9600); } void loop() { if (Serial.available() > 0){ if (dataComplete == true){ Serial.println("There is data already, clearing..."); char data[30]; dataComplete = false; } if (dataComplete == false){ Serial.println("New command, collecting..."); while (Serial.available()>0){ char character = Serial.read(); data[count] = character; count++; } dataComplete = true; } } Serial.print("Command received: "); Serial.println(data); delay(1000); } 

En outre, il semble quil affiche » Commande reçue: « à chaque itération, quil y ait ou non de nouvelles données (bien que cela puisse être la fonctionnalité prévue).

Comme mentionné, vous n « t effacez pas la variable, vous en créez simplement une nouvelle. Vous devrez effacer et réinitialiser count pour résoudre ce problème. Cependant, la simple réinitialisation de count ne fonctionnera pas si la deuxième commande est plus courte que celle avant.

Aussi, pourquoi compliquez-vous le code avec la variable dataComplete? Jai simplifié le code ci-dessous:

int count = 0; char data[30]; boolean dataComplete = false; void setup() { Serial.begin(9600); } void loop() { if (Serial.available()){ Serial.println("New command, collecting..."); count = 0; data[] = ""; while (Serial.available()){ char character = Serial.read(); data[count] = character; count++; } } Serial.print("Command received: "); Serial.println(data); delay(1000); } 

Réponse

Cela ne « t faites ce que vous avez lintention de faire:

Serial.println("There is data already, clearing..."); char data[30]; 

Votre résultat indique que vous effacez le tableau data, mais vous « ne faites rien de tel. En fait, vous déclarez une nouvelle variable locale appelée data, qui est indépendante du data global ont déjà déclaré en haut de votre programme. Les variables locales nexistent que dans la portée dans laquelle elles sont déclarées (à lintérieur de leur { } englobant le plus proche).

Au lieu de cela, votre variable count garde une trace de la quantité de données que vous avez reçues. Alors peut-être faites ce qui suit:

Serial.println("There is data already, clearing..."); count = 0; 

Ce nest pas la seule chose qui pourrait faire fonctionner votre programme de manière inattendue, mais cela devrait au moins résoudre le problème indiqué dans votre question.

Commentaires

  • Un terminateur nul est également nécessaire pour les données: ajoutez data[count]='\0'; après dataComplete = true;
  • Oui, cela ‘ est vrai, mais le plus gros problème est quil ny a aucun moyen pour lexpéditeur indiquer la fin dune transmission de données autre quune pause. Et comme il sagit de séries, il va y avoir une pause assez longue entre chaque caractère transmis.
  • Merci à vous deux. Mon code était erroné et le changer en  » count = 0  » a fonctionné. Jai également ajouté un délimiteur pour indiquer la fin dune commande dentrée et cela fonctionne comme prévu maintenant. Cependant, la seule façon qui fonctionnait pour vider le tableau de  » data  » était dutiliser une boucle for comme indiqué par @JRobert: de cette façon plus récente les commandes fonctionnent même si elles sont plus courtes que les plus anciennes.

Réponse

Pour parler du point de la question , et ce que lauteur essayait daccomplir.

Aucun de ce code ne fonctionne réellement dans son ensemble. Les données seraient écrasées et continueraient à tourner en continu … de toute façon, voici un exemple de travail du code original.

Cette méthode, je préfère effacer un tableau:

 for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0; 

Voici un exemple fonctionnel. (Assurez-vous de sélectionner Retour chariot sur le moniteur série)

 char message[32]; uint8_t incomingByte = 0; uint8_t BufferPos = 0; int clearbyte = 0; void setup() { Serial.begin(9600); Serial.println("\n String conversion testing"); } void loop() { if (BufferPos >= 32) { Serial.print("Buffer Full\n"); BufferPos = 00; incomingByte = 0; } if (Serial.available()) { incomingByte = Serial.read(); message[BufferPos++]= incomingByte; switch(incomingByte) { case "\n": case " ": break; case "\r": Serial.println(message); for( int i = 0; i < sizeof(message); ++i ) message[i] = (char)0; BufferPos= 0; incomingByte= 0; } } } 

Réponse

Jai lu tous les commentaires sur cette question, mais tous les codes étaient partagés de manière verbeuse. Après cela, je crée un code avec des fonctions simples et moins de ligne. dans ce cas, je pense que ce code fonctionnera correctement

si vous définissez le débit en bauds sous 115200, il faut ajouter delay () pour enregistrer le message dans le tableau de caractères

void loop() { char data[255]; uint8_t k = 0; while (Serial.available()) { data[k] = Serial.read(); k++; } for (int i = 0; i < k; i++) { Serial.print(data[i]); data [i] = "\0"; } //delay(50); } 

Commentaires

  • char data[] = {}; vous donnera un tableau de longueur nulle. Essayer dy insérer des données est une mauvaise idée.
  • Je suis daccord avec @NickGammon.Veuillez modifier votre réponse pour remplacer  » Je pense que … fonctionnera bien  » par un oui / non définitif, une fois que vous avez testé le code.
  • @NickGammon merci pour la correction, jai révisé mon code

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *