protocole de communication série bi-directionnel entre carte

Bonjour,

Je change de registre ayant résolu une partie de mon problème.

J'ai un tableau de caractère nommé "commande[32]".

Il contient une chaine du style toto;titi. J'aimerais placer cette unique chaine en deux parties dans un tableau ou bien dans deux String en vue de faire des tests dessus.

Je placerais le tout dans une fonction afin d'y faire appel à chaque fois que j'en ai besoin. executeCommande(commande);

Dans executeCommande(char commande), je ferais ceci:

  • Parser en deux -> mise en place dans titi, de la valeur titi, mise en place dans toto de la valeur de toto.
  • Si titi = cas 1 -> exécuter ceci avec toto
  • Si titi = cas 2 -> exécuter cela avec toto
    ... Ainsi de suite.

Merci d'y pensé.
Geeks.

http://arduino.cc/en/Tutorial/StringIndexOf ?

Non, mauvaise pioche !

C'est fait pour une String, j'ai un tableau de caractères :grin:

Bonjour,

La fonction strtok est tiptop pour ce que tu veux faire :wink:

http://www.cplusplus.com/reference/clibrary/cstring/strtok/

Geeks:
Non, mauvaise pioche !

Pas si mauvaise pioche que ça,tu peux facilement affecter un tableau de char à un objet String.

char tChar[] = "maChaine"
String str = tChar;

Dans le lien que je t'ai donner sur l'autre post il y a aussi tout ce qu'il te faut pour manipuler les chaines avr-libc: <string.h>: Strings, il y en a d'autre comme l'exemple de sky , tout dépend si tu veux t'amuser avec pointeurs, etc, ou utilisé un objet String qui sera sans doute plus lourd mais plus facile à manipuler.

Une chaine de caractère est une string c'est la même chose ... La classe string est juste une simplification

Ok !

Bon avec tous ces renseignement, j'ai essayer ceci:

//Fonction qui exécute la commande
void executeCommande() {
//Serial.println(commande); //Pour le débug

char * parse;

parse = strtok(commande, ";");

if(strcmp(parse[0], "Out13")==0) {
digitalWrite(13, parse[2]);
}

//Serial.println(parse[0]); //Pour le débug
//Serial.println(parse[2]); //Pour le débug
}

J'ai bien mes valeurs correct lorsque je fais mes Serial.println().
Mais ça ne compile pas dans min if, bien sûr !

Mini02___Sous_marin.cpp: In function ‘void executeCommande()’:
Mini02___Sous_marin.cpp:58: erreur: invalid conversion from ‘char’ to ‘const char*’
Mini02___Sous_marin.cpp:58: erreur: initializing argument 1 of ‘int strcmp(const char*, const char*)’

Si j'ai bien compris, il y a un problème de conversion entre char et char*. J'aimerais comprendre ce point.

Merci d'y pensé.

A la place de ça :

if(strcmp(parse[0], "Out13")==0) {

C'est pas plutôt ça :

if(strcmp(parse[0], "Out13")=='') {

Ah tien, j'ai pas la même erreur :cold_sweat:

Mini02___Sous_marin.cpp:58:33: erreur: constante caractère vide
Mini02___Sous_marin.cpp: In function ‘void executeCommande()’:
Mini02___Sous_marin.cpp:58: erreur: invalid conversion from ‘char’ to ‘const char*’
Mini02___Sous_marin.cpp:58: erreur: initializing argument 1 of ‘int strcmp(const char*, const char*)’

Ou alors :

==""

strktok est une fonction glissante qui s'appelle en plusieurs fois, elle retourne une chaine de caractéres et non un tableau de chaine :wink:

Donc :

//Fonction qui exécute la commande
void executeCommande() {
  char * parse[4];
  
  parse[0] = strtok(commande, ";");
  parse[1] = strtok(NULL, ";");
  parse[2] = strtok(NULL, ";");
  parse[3] = strtok(NULL, ";");

  if(strcmp(parse[0], "Out13") == 0) {
    int val = atoi(parse[2]);
    digitalWrite(13, val);
  }
}

@J-F: strcmp() retourne 0 si les deux chaines sont équivalentes, ou une valeur != 0 si les chaines sont différentes (retourne l'ordre alphabétique des chaines).

Ok Skywodd... j'le f'rais plus M'sieur XD

Bon et bien, je comprends mieux maintenant 8)
Merci pour ces précisions XD

Par contre, j'ai remarqué une chose bizarre!
Si je passe ceci Out13;HIGH, pour le Out13, ok, ça fonctionne. Mais pour le HIGH:

®½üOďÍU·¯Ç¾?³>?>?oõð?ߝïþ_ÿ÷û-Ðÿå¬?öNÏÊÿûòoïNãþ»ù­ÿúÝý Ñ¿ïÊ?üyÝöÝ:ýú9ÿ[VÉzzeó׳¼ËÔ[g^¯ïêÝWè»?î?ÿZôò{ºäÿ?óý/«?kº}÷?[¿ãÍìaÿ»µ'Ïßæ?ßZ_ï=§ªÿù<Æ}[oÕý2úT~;ê·ù]¾¥}X»^?åÚÎ7¶z?¾ë¨ýo_þß¿ï Öf¨þPoçîG÷Ü'»Þ2uÍÿWòu¬Óß$ç:ö»úÕ¹?Óö>_uüúÛ·ï¶íï?ûÝC?í]·ãwüÐÛß ?Þ÷¸?´ù?ÿm]?ûÿc6TáÜ®?ë{ûÃtíڏûeÖ̧íO<ÖWî¾ÿ'VOÛ¦·ÿÏâ_¾êýnÿÜ®ûíÛÞÎï¦é9?¾Ä?ÿçnøÙ{{s~~ö)3oÝmjª×½Ë.ùoxΧõú¥èm|ÿ~ÿ¶ûÛ
ø?Pÿ³ß½üÿ2¾è¸ú³°îÓê]{°??g½7kß«¯+¿û«}ú×àjÿGyÿî?ð~ùð}ÿ^ó£K#qÿ?½Ü³7W¨,ÿóïWÝ
ìJ¹æ??ã¯ÜÿýC/ÍóÌ×O×?¿D?¾³ÿqþP×/4§zà8s9ïÏj?ü·Ô;Mü-Çû·{w÷ÚgWt[Ý?ksÒw÷õÇØmØß«ý}½wý"×ÿÜÒ%%·úþßþC^LZ¯Õÿ;\¿Û}?ÅÛ«}·Êõð}Ysþ{ù¬úóÕcÝ:ÞþÎ-MÅ|¶wû,¯??¢V­%f??µ]ÞlG^S¼øý÷9_ÿù¨eõôü~???·?m?9ÇûÿëÞd|íêçõ¾?ïkêj¾×-öý
òWíKþ?=ÿ÷þéÆÏX'ÂíÛ»¢î?=üñÅS®~}}<ï2ùó¯þÿÛ¯°¿ûOñ×þßÿþ«}?×ì?£7;~¶¹ÿè}n?ß«?öÕéýÿ#÷ÿ¹¸oX^?÷ãv ÷V×Æé'×ä_ïÒü}?íɯÛÚøNËoþ?G®?Oý{»ÝwþÙÙ=x?-}û?­3

Avec ce code en mode débug pardi:

//Fonction qui exécute la commande
void executeCommande() {
  //Serial.println(commande);  //Pour le débug
  
  char * parse[2];
  
  parse[0] = strtok(commande, ";");
  parse[1] = strtok(NULL, ";");
  
  if(strcmp(parse[0], "Out13") == 0) {
    //int val = atoi(parse[2]);
    //digitalWrite(13, atoi(parse[2]));
    Serial.println(parse[2]);  //Pour le débug
  }
  
  //Serial.println(parse[0]);  //Pour le débug
  //Serial.println(parse[2]);  //Pour le débug
}

Bon, beaucoup de choses sont en commentaire car je voulais comprendre pourquoi j'avais pas une exécution correct de la pin13. En voyant le résultat brut, j'ai vite été fixé, je n'ai pas de HIGH. J'ai tester avec le int, et de la même façon, la pin ne réagit pas :cold_sweat:

Merci d'y pensé

Geeks:

Mini02___Sous_marin.cpp: In function ‘void executeCommande()’:
Mini02___Sous_marin.cpp:58: erreur: invalid conversion from ‘char’ to ‘const char*’
Mini02___Sous_marin.cpp:58: erreur: initializing argument 1 of ‘int strcmp(const char*, const char*)’

Si j'ai bien compris, il y a un problème de conversion entre char et char*. J'aimerais comprendre ce point.

Ici la fonction te demande une chaine de caractère constante (const char* ) .
Lorsque tu fais:

strcmp(parse[0], "Out13")

parse[0] tu lui donne la valeur du char ce situant à l'adresse [ 0 ], pour lui donner la première adresse du tableau (donc la chaine) tu dois faire

strcmp(parse, "Out13")

Vu qu'il est demander une chaine constante, un petit cast devrait marcher.

strcmp((const char*)parse, "Out13")

Entre () "out13" est une chaine constante.

B@tto:
Une chaine de caractère est une string c'est la même chose ... La classe string est juste une simplification

Pour être plus précis la classe String possède en attribut un tableau de char sur lequel elle effectue les opérations, manipulations.

Geeks:
Par contre, j'ai remarqué une chose bizarre!
Si je passe ceci Out13;HIGH, pour le Out13, ok, ça fonctionne. Mais pour le HIGH:

Tu utilise HIGH et LOW ? Bon du coup il faudra faire un autre if(strcmp(parse[1], "HIGH') ==0) car les valeurs HIGH et LOW que tu passe à digitalWrite ne sont pas des chaines de caractéres mais des macro que le compilateur remplace par 0 (LOW) ou 1 (HIGH).

//Fonction qui exécute la commande
void executeCommande() {
  char * parse[2]; // Tableau de deux pointeur donc parse[0] et parse[1]
  
  parse[0] = strtok(commande, ";");
  parse[1] = strtok(NULL, ";");
  
  if(strcmp(parse[0], "Out13") == 0) {
    //int val;
    //(strcmp(parse[1], "HIGH') == 0) ? val = HIGH : val = LOW;
    //digitalWrite(13, val);
    Serial.println(parse[2]);  //Pour le débug // pourquoi parse[2] tu dépasse la limite du tableau -> bug
  }
}

Geeks:
Bon, beaucoup de choses sont en commentaire car je voulais comprendre pourquoi j'avais pas une exécution correct de la pin13. En voyant le résultat brut, j'ai vite été fixé, je n'ai pas de HIGH. J'ai tester avec le int, et de la même façon, la pin ne réagit pas :cold_sweat:

HIGH et LOW sont des constante, elles ont pour valeur 1 pour HIGH et 0 pour LOW .
!!! Encore une mauvaise manipulation des tableau:

  parse[0] = strtok(commande, ";");
  parse[1] = strtok(NULL, ";");

parse[0] et parse[1], il s'agit de la valeur d'UN caractère de ta chaine situé à l'adresse [ 0 ] ou [ 1 ] et non une chaine, strtok,retourne un pointeur d'un emplacement de ta chaine ce n'est pas la même chose.
Revoir ce que sont les pointeurs, tableaux, chaines, etc, ne serait pas une mauvaise chose ...

Hey, ho, je débute ein !

Bon en même temps, lorsque je test il me mange des commandes.

Donc il faut que je face autrement mais ça coûtais rien d'essayer :grin:

Une idée ?

Geeks:
Hey, ho, je débute ein !

Il n'y a aucune agression ni rien dans nos explication, le problème c'est qu'il va falloir s'investir un minimum si tu es débutant sinon tu ne t'en sortiras jamais, on es tous passé par là.

Geeks:
Une idée ?

Le mieux c'est de suivre mon dernier conseil, sinon tu risque de ne jamais y arrivé.

osaka:
Revoir ce que sont les pointeurs, tableaux, chaines, etc, ne serait pas une mauvaise chose ...

j'ai déjà regardé ces histoire de pointeurs, désolé, je comprends pas...

Pour moi, un pointeur connais l'endroit d'une case contenant quelque-chose. Jamais su les utilisés.

En même temps je suis aussi ce qui m'est proposé, donc voila quoi !

AlienArea51:
Bonjour à tous
Désolé d'arriver comme un cheveu dans la soupe ,mais je trouve ce post très très interessant .

Ca n'a pas de cheveux un alien. :grin:

AlienArea51:
Je vois ça:

Revoir ce que sont les pointeurs, tableaux, chaines, etc, ne serait pas une mauvaise chose ...

Personnellement je me base par rapport à la référence Arduino ,depuis pas mal de temps , donc je comprend mieux pourquoi des fois je galère :smiley:
d'ou l'interet de faire une rubrique Tutoriels et cours,la plupart d'entre vous bourlinguez sur AVR depuis pas mal de temps et donc vous avez tous les atouts en main :wink:

Le problème c'est que la référence Arduino n'est valable que pour elle même, temps qu'on s'en contente ça va, mais si on va plus loin (ce qui arrive souvent) on fini toujours avec la tête entière dans la soupe (sans poils :grin:).

AlienArea51:
je vois ça :

strktok est une fonction glissante qui s'appelle en plusieurs fois, elle retourne une chaine de caractéres et non un tableau de chaine

c'est bien ,mais inconnu au bataillon dans la référence :wink:

Tu vois ça commence déjà. :stuck_out_tongue:

AlienArea51:
Donc tout ça pour trouver ce lien :
avr-libc: <string.h>: Strings

Je me réfère aux maximum à la lib avr pour être certain de l'optimisation et la compatibilité entre fonctions qui sont surement mieux adapté (construit) aux µc avr.

AlienArea51:
Ne serait-il pas judicieux de votre part ,de donner un lien sur les subtilités voire compléments à la référence Arduino ?? avec des explications simples et comprehensibles .
et toutes ces subtilités sont-elles facilement intégrable sur l'IDE Arduino (0022 par exemple) ??

Le problème c'est que les pointeurs et tableau par exemples sont loin d'être facile à expliqué et difficile de ce faire comprendre.
La meilleur référence pour débutant http://www.siteduzero.com/tutoriel-3-14189-apprenez-a-programmer-en-c.html 100% compatible sauf la partie concernant la sdl.
Il y a quelques liens tuto en post-it mais il faut fouiller (ce que peux font). :~

AlienArea51:
Certainement loin d'avoir les connaissances de Mr Geeks , mais je le rejoint sur ça :

Pour moi, un pointeur connais l'endroit d'une case contenant quelque-chose. Jamais su les utilisés.

Be c'est bien ça, mais ce que tu donnes dans la fonction c'est une valeurs et non l'adresse de cette valeurs, en locurence ici ce qui est demandé c'est la première adresse d'un tableau.

parse // donne moi la première adresse de mon tableau
parse+1 // donne moi la première adresse de mon tableau+1 (+1 sur l'adresse même), donc la seconde ([1]). 
&parse[0] // donne moi l'adresse de la première (0) valeur de mon tableau.
&parse[0]+1 // donne moi l'adresse de la première (0) valeur de mon tableau+1 (+1 sur l'adresse même), donc la seconde ([1]).
parse[0] // donne moi la valeur ce situant à la première (0) adresse de mon tableau
parse[0]+1 // donne moi la valeur ce situant à la première (0) adresse de mon tableau et +1 sur cette valeur.

http://www.siteduzero.com/tutoriel-3-14005-a-l-assaut-des-pointeurs.html
http://www.siteduzero.com/tutoriel-3-14015-les-tableaux.html