Problème de lecture d'un tableau

Bonjour,

Je viens enregistrer dans une première boucle while des caractères dans un tableau, lorsque j’affiche ce tableau dans cette même boucle (en même temps que je les enregistre) ça marche nickel et ma trame de caractère s’affiche correctement sur le moniteur série.

Le problème survient lorsque je veux lire ce tableau dans une autre boucle (boucle for), cette fois-ci des des mauvais caractères s’affichent sur le moniteur série et je ne comprends pas vraiment pourquoi.

Voici le code :

#include <SoftwareSerial.h>
#define startFrame 0x02
#define endFrame 0x03
#define lineFeed 0x0A
#define horizontalTab 0x09
#define carriageReturn 0x0D

int flag = 0;

char trameTIC[100] = {};
char ADCO[12] = {};
char ISOUSC[2] = {};
char BASE[9] = {};
char IINST[3] = {};
char IMAX[3] = {};

SoftwareSerial* cptSerial;

void setup() {

  Serial.begin(115200);
  cptSerial = new SoftwareSerial(8, 9);
  cptSerial->begin(1200);
}

char enregistrementTIC()
{
  int i = 0;
  char charIn = 0;
  while(charIn != startFrame)
  {
    charIn = cptSerial->read()& 0x7F;
  }
  while(charIn != endFrame)
  {
    if(cptSerial->available())
    {
      charIn = cptSerial->read()& 0x7F;
      if ((charIn !=startFrame) && (charIn !=endFrame) && (charIn !=lineFeed) &&(charIn != ' ')&& (charIn !=carriageReturn))
        {
          trameTIC[i] = charIn;
          Serial.print(trameTIC[i]);
        }          
    }
    i++;
  }
}

void lectureTIC()
{
    for(int i=0; i<100; i++)
  {
    Serial.println(trameTIC[i]);
  }
}

void loop() {
  
  enregistrementTIC();
  lectureTIC();
}

Si vous avez des idées de ce qui va mal dans le code, je suis preneur.

Merci d’avance.

Bonjour,

Tu incrémentes i même si tu ne stocke rien dans trameTIC

[i]
Il faut que tu incrémentes i uniquement quand tu fais trameTIC[i] = charIn;

Bonjour,

En effet, c'est chose résolue, j'incrémente maintenant le i au bon endroit mais il n'y a toujours rien lorsque je veux afficher le tableau avec la fonction lectureTIC().

Salut , il ne peut pas y avoir de probleme avec :

void lectureTIC()
{
    for(int i=0; i<100; i++)
  {
    Serial.println(trameTIC[i]);
  }
}

Sauf bien sur , si les caracteres enregistrées dans “trameTIC*” ne sont pas bon !*
A mon avis le probleme doit venir de cette ligne :
* *if ((charIn !=startFrame) && (charIn !=endFrame) && (charIn !=lineFeed) &&(charIn != ' ')&& (charIn !=carriageReturn))* *
peut etre que des caracteres necessaires ( comme les espaces ) sont supprimés alors qu ’ il ne faut pas .
et puis c ’ est pas :
* *if ((charIn !=startFrame) && (charIn !=endFrame) && (charIn !=lineFeed) &&(charIn != ' ')&& (charIn !=carriageReturn))* *

mais :
* *if ((charIn !=startFrame) || (charIn !=endFrame) || (charIn !=lineFeed) ||(charIn != ' ')|| (charIn !=carriageReturn))* *

  • !!*
    enleve les “&&” et remplace par des “||” , teste et dis moi .

@iznobe merci pour ta réponse, seulement je veux justement “filtrer” les caractères espace, linefeed, carriage retrurn etc… pour ne garder et n’enregistrer dans mon tableau seulement les lettres, chiffres et symboles, j’ai fais la modif que tu as conseillée,et avec cette modif les caractères que je veux filtrer s’enregistre quand même dans mon tableau (ce qui est logique car l’opérateur || n’aura besoin que d’une condition pour rentrer dans le if et donc ne rien filtrer).

Je pense que le problème viens d’ailleurs mais là je sèche vraiment.

essaie ce que je te dis , tu verras que ca fera ce que tu veux !

toi tu fais si pas d ' espace + si pas de + si pas de machin alors j ' enregistre .

alors qu il faut faire : si il n ' y a pas d' espace OU qu il n ' y a pas de machin OU qu ' il n ' y a pas de bidule alors j ' enregistre

emboite les if alors et tu verras bien que le probleme est là :

if ((charIn !=startFrame) {
	if (charIn !=endFrame) {
		if (charIn !=lineFeed) {
			if (charIn !=carriageReturn)){
			// enregistrement
			}
		}
	}
}

@iznobe comme je l’ai déjà dis, j’ai essayé ce que tu m’a dis, d’une part ça ne résous rien au problème de base qui est : je n’arrive pas à lire le tableau en dehors de la boucle dans laquelle j’enregistre les caractère dans celui-ci

et d’une autre part quand je lis le tableau dans la première boucle while j’obtiens quand même les caractères que je veux filtrer, ils ne sont donc pas filtré avec la méthode que tu propose, mais avec celle que j’utilise ils le sont, je joins des screenshot au cas ou tu continuerai à ne pas me croire.

kamill:
Bonjour,

Tu incrémentes i même si tu ne stocke rien dans trameTIC

[i]

Il faut que tu incrémentes i uniquement quand tu fais trameTIC[i] = charIn;

tu n ’ as meme pas fait ce qu ’ as dis kamill , ca sert a quoi qu on essaie de t ’ aider si tu ne fais pas ce qu on te dis …

#include <SoftwareSerial.h>
#define startFrame 0x02
#define endFrame 0x03
#define lineFeed 0x0A
#define horizontalTab 0x09
#define carriageReturn 0x0D

int flag = 0;

char trameTIC[100] = {};
char ADCO[12] = {};
char ISOUSC[2] = {};
char BASE[9] = {};
char IINST[3] = {};
char IMAX[3] = {};

SoftwareSerial* cptSerial;

void setup() {

  Serial.begin(115200);
  cptSerial = new SoftwareSerial(8, 9);
  cptSerial->begin(1200);
}

char enregistrementTIC()
{
  int i = 0;
  char charIn = 0;
  while(charIn != startFrame)
  {
    charIn = cptSerial->read()& 0x7F;
  }
  while(charIn != endFrame)
  {
    if(cptSerial->available())
    {
      charIn = cptSerial->read()& 0x7F;
      if ((charIn !=startFrame) && (charIn !=endFrame) && (charIn !=lineFeed) &&(charIn != ' ')&& (charIn !=carriageReturn))
        {
          trameTIC[i] = charIn;
          Serial.print(trameTIC[i]);
		  i++;
        }         
    }
  }
}

void lectureTIC()
{
    for(int i=0; i<100; i++)
  {
    Serial.println(trameTIC[i]);
  }
}

void loop() {
 
  enregistrementTIC();
  lectureTIC();
}

essaie ce que je te dis , tu verras que ca fera ce que tu veux !

non non ce sont bien des && qu'il faut car il ne fait pas == mais !=

ce serait bien de tester le débordement du buffer
est-ce bien de l'ASCII que vous recevez ? (et à 1200 bauds ? Notez que Software Serial n'est pas super stable à bas débit)

@iznobe je pense, sans vouloir être méchant que tu ne lis pas les réponses, j'ai clairement dis au dessus que j'avais changé l'emplacement de l'incrémentation de i et que ça ne changeait rien au problème.

elkilleros:
@iznobe je pense, sans vouloir être méchant que tu ne lis pas les réponses, j'ai clairement dis au dessus que j'avais changé l'emplacement de l'incrémentation de i et que ça ne changeait rien au problème.

peut etre mais tu ne l' as pas mis au bon endroit .

dans mon post precedent , je te l ' ai mis ou il faut ... teste le et met un karma a kamill :smiley:

if ((charIn !=startFrame) && (charIn !=endFrame) && (charIn !=lineFeed) &&(charIn != ' ')&& (charIn !=carriageReturn))
        {
          trameTIC[i] = charIn;
          Serial.print(trameTIC[i]);
		  i++;
        }

ca c ' est bon .

@iznobe euhh je dois être aveugle ou je ne sais pas, mais tu l'a mis exactement au même endroit que moi, si tu regarde les screenshot, il est au même emplacement sauf que le tiens et indenté à savoir juste après le ligne Serial.print(trameTIC*);*

@iznobe je viens de voir que tu as changé ton post au dessus en me conseillant d'emboiter les if(), alors d'une part ça ne résoud absolument pas le problème et ça reviens strictement au même que ma solution avec les &&, je ne vois pas en quoi ça peut poser problème. Je le rappel juste au cas ou car j'ai bien l'impression que tu ne lis pas mes réponses car c'est la 3eme fois que tu me conseil quelque chose que j'ai déjà fais ou quelque chose à coté de la plaque, mais le problème de base est le suivant :

Je n'arrive pas à lire le tableau de la première fonction dans une autre fonction !

Voilà le problème je pense honnêtement que ça n'a rien à voir avec cette histoire de if et de && car je lis très bien le tableau dans cette première boucle avec les if

si je lis bien , mais je me suis basé sur le code poster au depart , passur le screenshoot .

la boucle et le print de la fonction d’ affichage est vraiment basique et est codé normalement pas d’ erreur .

essaie ce code , pour voir si le tableau n’ est pas trop petit comme l’ a dit @J-M-L , il se peut qu il y ait plus de 100 caracteres de trame avant la fin et que ca produise un debordement de tableau .

#include <SoftwareSerial.h>
#define startFrame 0x02
#define endFrame 0x03
#define lineFeed 0x0A
#define horizontalTab 0x09
#define carriageReturn 0x0D

int flag = 0;

char trameTIC[1000] = {};
char ADCO[12] = {};
char ISOUSC[2] = {};
char BASE[9] = {};
char IINST[3] = {};
char IMAX[3] = {};

SoftwareSerial* cptSerial;

void setup() {

  Serial.begin(115200);
  cptSerial = new SoftwareSerial(8, 9);
  cptSerial->begin(1200);
}

char enregistrementTIC()
{
  int i = 0;
  char charIn = 0;
  while(charIn != startFrame)
  {
    charIn = cptSerial->read()& 0x7F;
  }
  while(charIn != endFrame)
  {
    if(cptSerial->available())
    {
      charIn = cptSerial->read()& 0x7F;
      if ((charIn ==startFrame) || (charIn !=endFrame) || (charIn !=lineFeed) || (charIn != ' ')&& (charIn !=carriageReturn))
        {
          trameTIC[i] = charIn;
          Serial.print(trameTIC[i]);
		  i++;
        }         
    }
  }
}

void lectureTIC()
{
    for(int i=0; i<1000; i++)
  {
    Serial.println(trameTIC[i]);
  }
}

void loop() {
 
  enregistrementTIC();
  lectureTIC();
}

ce lien t ' interressera surement et pourra peut etre t ' aider car il traite du meme sujet :

Pour gérer un possible dépassement de tableau, tu peux changer
while(charIn != endFrame)en

while(charIn != endFrame && i < 1000)

ou changer le
i++;en

if (i < 999) i++;

iznobe:
nleve les "&&" et remplace par des "||" , teste et dis moi .

Mais non, pas du tout. J-M-L a raison. Il faut employer &&
Si tu mets des ||, que se passe-il si 'startFrame' arrive ?
le test

(charIn !=startFrame)

est faux, mais le test (charIn !=endFrame) et les suivant sont vrais.
Combinés avec des "ou", le résultat est vrai.
Donc on stocke l'octet 'startFrame', ce qu'on ne veut pas.
En fait avec des || on stocke tous les octets.

Bon avant de faire compliqué, faites simple pour voir si la réception fonctionne:

testez ce code et regardez dans le moniteur série ouvert à 115200 bauds

#include <SoftwareSerial.h>
const uint8_t RxPin = 8;  // 8 connnecté à Tx de l'autre appareil
const uint8_t TxPin = 9;  // 9 connnecté à Rx de l'autre appareil
SoftwareSerial cptSerial(RxPin, TxPin); // 8 connnecté à Tx , 9 à Rx de l'autre appareil

enum : uint8_t {startFrame = 0x02, endFrame = 0x03, lineFeed = '\n', horizontalTab = '\t', carriageReturn = '\r'};

void setup() {
  Serial.begin(115200);
  cptSerial.begin(1200);
  Serial.println(F("\nDEBUT ECOUTE"));
}

void loop() {
  int recu = cptSerial.read();
  if (recu != -1) {
    switch ((uint8_t) recu) {
      case startFrame:
        Serial.println(F("START FRAME"));
        break;
      case endFrame:
        Serial.println(F("END FRAME"));
        break;
      case lineFeed:
        Serial.println(F("SAUT DE LIGNE"));
        break;
      case horizontalTab:
        Serial.println(F("TABULATION"));
        break;
      case carriageReturn:
        Serial.println(F("RETOUR CHARIOT"));
        break;
      default:
        Serial.print(F("Ox")); Serial.print(recu, HEX);
        Serial.write('\t'); Serial.println((char) recu);
        break;
    }
  }
}

dites nous ce que vous voyez (j’ai tapé ça ici donc il y a peut être des petites erreurs - je suppose que vous voyez le principe)

Si ça ne fonctionne pas faudra nous en dire plus sur vos appareils.
quel arduino ? quel type d’élément connecté sur le port Software Serial ?
même tension des 2 côtés ? GND connectés ? débit bien à 1200 bauds ?
fils de bonne qualité ? test de continuité ? etc