Arduino Forum

International => Français => Topic started by: Skeetch on Feb 03, 2017, 10:25 am

Title: Dimension Array
Post by: Skeetch on Feb 03, 2017, 10:25 am
Salut salut,

Etant assez nouveau sur Arduino et en particulier avec les tableaux, j'ai besoin d'un peu d'aide !

J'essaie d'extraire des données précises d'une trame RS232 provenant d'une station météo dont voici une trame d'exemple :
Code: [Select]
ULTIMETER WEATHER REPORT 02/03/17 08:14
Wind:     Cur   0.6M/S 253Deg, 1mAvg   1.0M/S,  1mPeak   2.1M/S 305Deg
           Hi   4.0M/S 180Deg
WChill:   Cur   7.5C, Lo   6.2C
Temp Out: Cur   7.5C, Hi  20.5C, Lo   7.5C
Temp In:  Cur  21.7C, Hi  21.7C, Lo  19.6C
Rain:   Today   0.00in, Since 01/01/09:    0.00in


(Je voudrais avoir la date, heure, et plusieurs autres données)

Jusqu'ici rien de sorcier me direz vous !
Pour la méthode de réception j'ai choisi le tableau, j'ai fais un petit bout de code que voici :
Code: [Select]
char Array[200];
int Dataserial;


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

void loop() {

     while (Serial.available() > 0) {

for(int i=0; i < sizeof(Array); i++)
{

Dataserial = Serial.read();
Array[i]=Dataserial;

Serial.print(Array[i]);
}

J'arrive avec succès a l'afficher dans le port série mais avec des caractères supplémentaires pas vraiment désirable !
Screen : http://imgur.com/xngy7pZ (http://imgur.com/xngy7pZ)

Peut être s'agit-il de données qui reviennent de la station ? peut être !
Mais ce n'est pas le seul problème ; vous voyez dans mon code que j'ai défini le tableau avec 200 caractères (sauf erreurs de ma part), hors j'ai calculé que ma trame faisait dans les 300 caractères au complet. Si je ne me trompe pas, ma trame aurait du être coupée quand je demande l'écriture dans le porte série ?
J'ai essayé en mettant [1] au lieu de [200], les caractères indésirables disparaissent mais la trame est toujours complète ><

Concernant la méthode de transmission Station > Arduino, j'ai un Max202 relié du DB9 de la station vers le port Rx (pin 0) de mon Arduino (+ gnd et 5v)
Title: Re: Dimension Array
Post by: kamill on Feb 03, 2017, 10:31 am
Bonjour,

Tu dépasses la taille de ton tableau
En C/C++ il n'y a pas de vérification si tu écris ou lis en dehors du tableau. S'il n'y a rien derrière ça peut (apparemment) bien se passer, s'il y a des variables après le tableau, ça va les écraser.
Title: Re: Dimension Array
Post by: Skeetch on Feb 03, 2017, 10:36 am
Bonjour,

Merci de ta réponse rapide,
Que me conseillerais tu de faire ? 
Title: Re: Dimension Array
Post by: kamill on Feb 03, 2017, 10:48 am
Il faut attendre le début de trame, par exemple attendre le premier caractère, puis lire les données dans ton tableau en faisant attention à ne pas dépasser la taille.

Par exemple:
Code: [Select]
char Array[300];
int Dataserial;


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

void loop() {
  char c=Serial.read();
  if (c=='U')       // début de trame
  {
    Array[0]=c;
    int length=Serial.readBytes(Array+1,sizeof Array-2);  // lit les données, on réserve un place pour le 0 de fin
    length++;     // pour prendre en compre le premier caractère
    for (int i=0; Array[i]!=0; i++)
      Serial.print(Array[i]);
  }
}
Title: Re: Dimension Array
Post by: Skeetch on Feb 03, 2017, 10:58 am
Impeccable, merci beaucoup !
Je vais essayer ça pour récupérer mes autres données !
Title: Re: Dimension Array
Post by: Skeetch on Feb 08, 2017, 09:06 am
Bonjour,

Je reviens ici avec encore mes tableaux :c

Je dois calculer le checksum d'une trame contenant un message.
La trame complète est sous cette forme :

Code: [Select]
<ID00><L1><PA><FE><MA><WB><FE><CE>"Message""Checksum"<E>

En sachant que l'identifiant et la fin de trame ne doivent pas être pris en compte lors du checksum

Identifiant : <ID00>
Fin de trame : <E>

Le meilleur moyen de calculer le checksum serait de mettre la trame dans un tableau et ensuite faire les ou exclusif ("^=" il me semble) entre chaques caractères.
Sauf que je n'ai aucune idée de la syntaxe à mettre !
D'autant plus que le tableau doit faire la taille de la trame et la longueur de celle ci peut changer du simple au double (en restant dans la limite du raisonnable)

C'est pourquoi je demande un petit peu d'aide ! ;)
Title: Re: Dimension Array
Post by: J-M-L on Feb 08, 2017, 09:21 am
Il faut un tableau assez grand pour vos besoins et savoir combien de caracteres sont dedans - vous ne traitez que cela pour la checksum
Title: Re: Dimension Array
Post by: kamill on Feb 08, 2017, 09:22 am
Bonjour,

Si tu as utilisé un programme du genre de celui que je t'ai proposé pour recevoir les caractères tu as le tableau et sa longueur. Il suffit de faire un ou exclusif pour les octets concernés.
Title: Re: Dimension Array
Post by: Skeetch on Feb 08, 2017, 09:30 am
Justement, la longueur du tableau varie :c mais pas plus de 100 caractère je pense (ce qui fait déjà grand)
Oui uniquement que pour le checksum.

J'ai essayé avec ce que tu m'a donné, avec une trame de test et si j'ai bien compris, ça donne un truc du genre :

Code: [Select]
// trame de test : <ID00><L1><PA><FE><MA><WB><FE><CE>test<E>

char Array[41];

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

void loop() {

char c=Serial.read();
  if (c=='<'){       // début de trame
 
    Array[0]=c;
    int length=Serial.readBytes(Array+6,sizeof Array-4);
    length++;
    for (int i=0; Array[i]!=0; i++)
      Serial.print(Array[i]);

  }
}


?
Title: Re: Dimension Array
Post by: kamill on Feb 08, 2017, 09:35 am
Plutôt quelque-chose de ce genre:
Code: [Select]
void loop() {
  char c=Serial.read();
  if (c=='<')       // début de trame
  {
    Array[0]=c;
    int length=Serial.readBytes(Array+1,sizeof Array-2);  // lit les données, on réserve un place pour le 0 de fin
    length++;     // pour prendre en compre le premier caractère
    for (int i=0; Array[i]!=0; i++)
      Serial.print(Array[i]);

    byte chk=0;
    for (int i=6; i<length-4; i++)
      chk^=(byte)Array[i];
  }
}
Title: Re: Dimension Array
Post by: Skeetch on Feb 08, 2017, 10:00 am
Ok, je reprend tout à zero.
Dans un premier temps avec un tableau de 41 soit la longueur de la trame
Je comprend plus rien là xD

normalement, avec ça il devrait me retourner juste le milieu de la trame (enfin ce que je veux, sans l'ID et la fin) non ?

Code: [Select]
// trame de test : <ID00><L1><PA><FE><MA><WB><FE><CE>test<E>

char Array[41];
byte chk=0;

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

void loop() {
  char c=Serial.read();
 
    Array[0]=c;
    int length=Serial.readBytes(Array+6,sizeof Array-4);
    length++;
   
    int i;
    for (i = 0; i < 41; i = i + 1) {
    Serial.print(Array[i]); 
    }

Title: Re: Dimension Array
Post by: kamill on Feb 08, 2017, 10:10 am
Non, ça ne retourne pas que le milieu de trame.Il faut lire toute la trame et traiter ce qui t'intéresse.
Title: Re: Dimension Array
Post by: Skeetch on Feb 08, 2017, 10:37 am
J'ai finalement réussi a calculer le checksum en décimal puis la conversion en hexa ! avec seulement la partie de la trame qui m'intéresse

Par contre une question, il me le calcul une fois sur deux, voir le screen.

prog :
Code: [Select]
// trame de test : <ID00><L1><PA><FE><MA><WB><FE><CE>mess<E>
char Array[41];
int i;
byte chk=0;
String checksum;

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

void loop() {
char c=Serial.read();
  if (c=='U')       // début de trame
  {
    Array[0]=c;
 
  for (i = 0; i < sizeof(Array) - 1; i++){
  //Serial.write(Array[i]);
  }
  delay(5000);

 
  for (int i=6; i< sizeof(Array)-4; i++)
  chk^=(byte)Array[i];
 
  Serial.print("dec: ");
  Serial.println(chk);
 
  checksum =  String(chk, HEX);
  Serial.println("hex: " + checksum);
 
}


Screen : http://imgur.com/a/HKF0x
Title: Re: Dimension Array
Post by: kamill on Feb 08, 2017, 10:47 am
Dans ton programme, on ne voit pas de lecture de la trame.
Title: Re: Dimension Array
Post by: fdufnews on Feb 08, 2017, 10:50 am
Faudrait penser à remettre chk à zéro avant de commencer le calcul du checksum
Title: Re: Dimension Array
Post by: kamill on Feb 08, 2017, 10:54 am
Oui avec la 'mode' arduino qui consiste à mettre toutes les variables globales, on oublie de les initialiser quand il faut.
Title: Re: Dimension Array
Post by: Skeetch on Feb 08, 2017, 10:55 am
Dans ton programme, on ne voit pas de lecture de la trame.
Que veux tu dire ?

Faudrait penser à remettre chk à zéro avant de commencer le calcul du checksum
Fait !
Title: Re: Dimension Array
Post by: kamill on Feb 08, 2017, 10:57 am
Que veux tu dire ?
Ben, qu'il n'y a pas de réception de la trame dans ton programme.
Title: Re: Dimension Array
Post by: J-M-L on Feb 08, 2017, 11:36 am
faut arrêter avec la classe String partout...
Code: [Select]
  checksum =  String(chk, HEX);
  Serial.println("hex: " + checksum);


il suffit juste de faire un

Code: [Select]
Serial.print("hex: ");
Serial.println(chk, HEX); // sur un seul digit si <= 15


pourquoi passer par une String??
Title: Re: Dimension Array
Post by: Skeetch on Feb 10, 2017, 07:48 pm
Re bonjour et merci de vos réponses !

Surement un question très bête que je pose mais, quand je fais ceci :

 
Code: [Select]
if (Serial.available() > 0){
        incomingByte = Serial.read();

        Serial.println(incomingByte);


il me ressort la valeur décimale de mon caractère ASCIIi, ce qui est désagréable ! J'avais déjà rencontré ce problème et je pensais l'avoir réglé mais apparemment il s'agissait d'un coup de bol ! (voir screen : http://imgur.com/a/jqBFj )

Ma variable incomingByte est déclarée en int
Title: Re: Dimension Array
Post by: kamill on Feb 10, 2017, 08:00 pm
Bonjour,
Est ce que incomingByte est bien un char ?
Sinon, il faut le caster en char
 
Code: [Select]
     Serial.println((char)incomingByte);
Title: Re: Dimension Array
Post by: Skeetch on Feb 10, 2017, 08:16 pm
Ahhh impeccable merci !
Title: Re: Dimension Array
Post by: Skeetch on Feb 10, 2017, 08:30 pm
Ah oui mais héhé, autre problème :c
Est ce qu'il y a moyen de, on va dire, les mettre ensemble dans un String par exemple ?
Parce que du coup il me les sort comme ça : http://imgur.com/a/CAMJp , ce qui est logique pour le coup
Mais je voudrais bien récupérer ce que j'envoie sur le port série en une variable (simplement) pour pouvoir la réutiliser derrière :c
Title: Re: Dimension Array
Post by: kamill on Feb 10, 2017, 08:35 pm
Si tu veux les afficher sans saut de ligne, il suffit de faire Serial.print au lieu de Serial.println

Si tu veux les ranger dans un tableau, ça à fait l'objet des premiers messages. Il faut faire la même chose.
Title: Re: Dimension Array
Post by: Skeetch on Feb 10, 2017, 08:39 pm
Oui, mais c'est pas tellement l'affichage qui m'importe :33
Il me calcul le checksum pour chaque caractères (lien) (http://imgur.com/a/kL8ja) et non en une variable comme je le souhaiterais :c
Tu me conseillerais donc un tableau ?