Arduino, X-Bee, Array & integer, besoin d'aide

Bonjour tous,

J'ai une portion de code à modifier pour récupérer des données série via X-Bee :

Le code original sans utilisation XBee est :

if (Serial.available() > 0) {
incomingChar = Serial.read();

if(incomingChar == startChar){
inFrame = 1;
}
if(inFrame && (incomingChar == endChar)){

inFrame = 0;
hasLine = 1;
}

if(inFrame){
commandLine[charIndex] = incomingChar;
charIndex++;
if(charIndex > maxFrameLen){
brokenFrame = 1;
hasLine=1;
}
}
}

J'ai commencé à le modifier mais je bloque à un endroit :

if ( Serial.available() > 0) { // if there are bytes waiting on the serial port
char inByte = Serial.read(); // read a byte
int len;
len = Serial.available();//defining the length of the Byte - On ne connait pas la longueur à l'avance
char inString[len]; // declare string variable
for (int i = 0; i < len; i++) {
inString = Serial.read();

  • }[/color]*
    // A partir d'ici, je ne m'en sors plus mais je ne dois pas être bien loin.
    // J'ai une erreur de compil, je comprends pourquoi mais n'ai pas le moyen de la contourner.
  • if (inString == inString[0]){*
  • inFrame = 1;*
  • }*
    _ if(inFrame && (inString == inString*)){_
    _
    inFrame = 0;_
    _
    hasLine = 1;_
    _
    }_
    _
    if(inFrame){_
    _
    commandLine[charIndex] = incomingChar;_
    _
    charIndex++;_
    _
    if(charIndex > maxFrameLen){_
    _
    brokenFrame = 1;_
    _
    hasLine=1;_
    _
    }_
    _
    }_
    _
    }[/color]*_
    Voilà, je précise que je ne bricole sur Arduino que depuis 2 jours, j'avance vite mais il me manque 2 ou 3 connaissances qui viendront avec le temps. Votre aide me serait précieuse.
    Merci d'avance.
    Nestor.

je ne commprend pas pourquoi tu a mis des quotes dans

if (inString == 'inString[1]'){

au lieu de if (inString == inString[1]){

les indices de tableaux commence a zero donc ici tu test le deuxieme caractere de inString je suppose si c'est ce que tu cherche a faire.

le 1er cartere du tableau est inString[0] etc

tu ne peux pas comparer aussi inString = ... car c'est un tableau de caractere sinon il faut que tu utilise un pointeur qui pointe sur ton tableau de char.

Peut être que tu veux comparer si le premier caractere de inString est un caractere particulier ?

en ces cas la il faudrait faire

char starChar;

starChar = 'A'; //ceci est un exemple
if (inString[0] == starChar)
{
<-- ici ton code
}
a quel endroit il te met l'erreur dans arduino au niveau de la ligne ?

Bonjour Andromeda.

Exact, pour les quotes, c'était un dernier essai que j'avais fait avant de poster ici. Je viens de modifier mon message ci-dessus car mon pépin ne vient pas de là.

Le message d'erreur de compil, c'est :
error: ISO C++ forbids comparison between pointer and integer Ca c'est pour if (inString[0] == inString)
error: name lookup of 'i' changed for new ISO 'for' scoping
error: using obsolete binding at 'i'
error: ISO C++ forbids comparison between pointer and integer

Tu as raison aussi sur l'indice, je me suis planté, il s'agit bien du 1er caractère que je veux (enfin je crois bien...)
J'ai donc re-modifié mon message ci dessus en tenant compte de ça.

J'ai déduis très basiquement que :

if(incomingChar == startChar)
pouvait devenir théoriquement :
if (inString == inString[0])

et que
if(inFrame && (incomingChar == endChar)
pouvait devenir théoriquement :
if(inFrame && (inString == inString*)[/color]*
Sauf que ça ne fonctionne évidemment pas.
Si je connaissais les valeurs possibles des 1ers et derniers caractères, ce serait simple, comme dans ton exemple, sauf que ce n'est pas le cas.
Je re-précise bien que je ne suis pas programmeur, juste un pov' bidouilleur. Mon souhait, c'est de reproduire le code du dessus qui fonctionne en filaire mais qui n'est pas compatible X-Bee.
Voili voilou, je passe mon temps sur les forums en quête d'un exemple similaire mais je ne trouve pas et ça m'empêche de dormir :wink:
Merci du coup de main.

======================
Le message d'erreur de compil, c'est :
error: ISO C++ forbids comparison between pointer and integer
error: name lookup of 'i' changed for new ISO 'for' scoping
error: using obsolete binding at 'i'
error: ISO C++ forbids comparison between pointer and integer

=> l'erreur te dit que tu compare un pointeur avec un caractere et ce n'est pas possible, tu dois faire

if (inString[0] == inString[0]) mais en ces cas la je ne vois pas a quoi sa sert de comparer le premier caractere de ta chaine avec ce meme premier caractere de ta chaine

tu devrais le comparer a une variable de type char qui doit te dire si le premier caractere de ta chaine inString[0] commence par un caractere special d'apres le code.

par exemple:

char startChar;
startChar = '!';
if (inString[0] == startChar) { ..

inString[0] signifie le premier caractere de ta chaine inString mais ne veux pas dire que c'est le premier caractere que tu recoit du port serie Le premier caractere venant du port serie serait plutot

car = Serial.read();

===============
J'ai déduis très basiquement que :

if(incomingChar == startChar)
pouvait devenir théoriquement :
if (inString == inString[0])

=> non ce n'est pas la meme chose, dans le code
if(incomingChar == startChar), il test si le caractere provenant du port serie est egal a un caractere special startChar qui surement a ete definie au debut du code.

alors que dans ta deuxiemme ligne:
if (inString == inString[0])
tu compare instring avec le premier caractere de inString qui est inString[0] de ta chaine, qui ne marchera pas d'ailleurs car tu auras l'erreur de comparaison d'un pointeur avec un caractere.

==============================
et que
if(inFrame && (incomingChar == endChar)
pouvait devenir théoriquement :
if(inFrame && (inString == inString*)*
=> pareil ici tu compare un pointeur ave un des caractere de ta chaine inString.
detail ce que tu veux faire exactement dans ton programe, pour que je puisse t'orienter sur le code.
d'apres le bout de code que tu as mis j'ai l'impression que tu recoit une trame du port serie et que tu souhaite detecter le premier caractere recu du port serie pour traiter cette trame et aussi de detecter la fin de la trame.

Dam !!, je commence à comprendre beaucoup mieux...
Je n'imaginais pas que startChar et endChar étaient défine dans le programme, pour moi, c'était nativement le premier et le dernier caractère d'une trame.

La tu m'as fais faire un bond en avant, effectivement, dans un fichier inclus, j'ai :
const char startChar='#';
const char endChar='\r';
Ca explique.

J'ai à présent un code modifié comme suit :
if (inString[0] == startChar){
inFrame = 1;
} // Jusque là tout va bien
if(inFrame && (inString == endChar)){

  • inFrame = 0;*
  • hasLine = 1;*
  • }[/color]*
    Ca marche mieux mais pas encore :slight_smile:
    Message d'erreur :
    error: name lookup of 'i' changed for new ISO 'for' scoping Ca concerne cette ligne là : if(inFrame && (inString == endChar))[/color]
    error: using obsolete binding at 'i'
    Et là, je ne comprends pas vraiment ce que le message me dit.
    Je crois comprendre ne pas pouvoir utiliser "inString*" comme valeur du dernier caractère*
    Sympa tes explications, c'est clair.
    ...
    En écrivant ceci, j'ai donc essayé de remplacer inString par inByte (inByte est forcément le dernier caractère reçu non ?)
    Ca fait : if(inFrame && (inByte == endChar))
    Ca compile mais le programme ne marche pas, j'ai fais une boulette ou ça vient d'ailleurs ?
    Nestor.

inByte ce doit etre le dernier caractere lu dans le port serie, tu doit avoir un truc du genre

inBytes = Serial.read();

mais n'est pas forcement le dernier caractere dans ta trame inString.

si la longueur de la trame fait par exemple 20, le dernier caractere serait inString[19].

le programme compile mais il n'a pas d'erreur mais je pense que le test avec inBytes = endChar ne se passe pas.

ce devrait etre un truc du genre inString == endChar mais tu as une erreur parceque la variable i ne doit pas varier ou ne se trouve pas dans une boucle for.
si le programe se trouve dans le void loop() de arduino il doit y avoir une variation de la variable i tel que i++ ou i = i +1.
Dans une boucle for de type:
for (i = 0; i < 20; i++)
{
...
}
....
apres le for le contenu de la variable i est egal a 20;
comme i est deja utilisé peut etre qu'en utilisant une autre variable tel que j qui s'occuperai de la postion du caractere dans la trame inString[j] ...
cette variable s'incrementerai une fois que as detecte le premier caractere de la trame. comme ca tu auras inString[j] le caractere courant a traité.
en fait tu aurais apres juste apres le caractere de debut de ta trame (startChar) inString[0] donc j = 0; et juste avant le caractere de fin de ta trame (endChar) tu auras le derniere caractere de ta trame dans inString[j], eveidement j variera a chaque lecture d'un caractere de la trame.

Merci pour ta réponse andromeda, mais je ne vois pas bien pourquoi mettre une variable "j" quelque part et j'avoue aussi ne pas trop comprendre où.

j'ai déjà la variable "len" qui me donne le nombre de caractère du String, j'ai donc essayé :

if(inFrame && (inString[len] == endChar)){
inFrame = 0;
hasLine = 1;
}

Ca compile bien mais ça ne fonctionne toujours pas.
Je crois que je vais laisser tomber, c'est un très chouette projet qui fonctionne en filaire ou en module BlueTooth, qui nécessite malheureusement qques adaptations pour les X-Bee mais il me manque trop de bases pour pouvoir y parvenir. J'y ai passé + de 15h00 sans parvenir à faire fonctionner ce truc, mes C.I sont faits, tout est prêt, mais je me suis sur estimé. Ca m'énerve, je suis vaincu et je dois bien admettre ne pas pouvoir être bon en tout.

Pour ton info perso, les sources (v1.1) et l'explication de son utilité sont là :
http://www.altapix.com/technique/altastation.html

Merci quand même.

j'ai regarde un peu le code en fait il lit le port serie donc en filaire j'imagine pour le traitement, mais ce code existant devrai fonctionner soit en bluetooth ou en xbee la seul difference au lieu de lire en filaire sur le port serie tu dois lire sur les lignes rx et tx de ton xBee.

si tu as un com2 sur ta platine arduino ta juste a connecte tes pin RX et TX du xBee sur l'arduino dans le com2 par exemple et modifie le Serial.begin(9600) si ton xBee est en 9600 en Serial2.begin(9600) ainsi que le Serial.available() en Serial2.available() et ca devrait fonctionner.

si tu n'a pas de port com2 sur ta platine tu peux utiliser NewSoftSerial qui te permet d'utiliser n'importe quel entree sortie de ta platine comme des ports series standard.

et par rapport a ce que tu souhaite faire pour ton projet, de faire du nettoyage du code, c'est a dire de supprimer ce que tu n'utilise pas par exemple.

L'arduino est un nano, pas de COM2, j'utilise NewSoftSerial, l'auteur du projet l'a implémenté puisqu'il utilise un écran LCD sur le port COM1

L'auteur du projet n'a aucun pépin pour le faire fonctionner, d'autres utilisateurs non-plus, ça fonctionne très bien en Bluetooth mais pas en X-Bee. Je ne suis pas le seul à avoir ce problème.

Mon X-Bee est connecté proprement, là dessus je suis sur de moi, quand je programme l'arduino avec un autre soft qui m'affiche les données reçues brutes de n'importe quelle trame, j'ai bien qqch, donc, là dessus ça va, c'est la transmission X-Bee le pépin.

Mes X-Bee sont bien configurés, ils fonctionnent entre le PC et le modèle réduit et échangent des données.

J'ai lu je ne sais plus où que les X-Bee ne pouvaient pas utiliser la méthode d'origine de ce programme pour une histoire de buffer qui serait lu en une seule fois, voilà pourquoi je souhaitais changer ces paramètres pour égrener un par un les datas reçus.

Je suis convaincu qu'il n'y a que ça à faire.