Go Down

Topic: communication série entre deux Arduino (Read 12483 times) previous topic - next topic

jfs

Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

julien@pobot.org

#16
Mar 19, 2009, 12:29 am Last Edit: Mar 19, 2009, 12:32 am by julien@pobot.org Reason: 1
Non, 0x36.

0x363 vaut en binaire 0000 0011 0110 0011
donc un décalage vers la droite (>>) de 4 va donner le binaire suivant : 0000 0011 0110 soit 0x036.

(Parenthèse, pour décoder une trame ASCII en nombre, plutôt que de passer par des multiplications par 1 000 000, il vaut mieux multiplier par 10. j'ai fait un petit exemple : http://www.pobot.org/Interface-ligne-de-commande-pour.html)





jfs

#17
Mar 19, 2009, 07:28 am Last Edit: Mar 19, 2009, 07:36 am by jfs Reason: 1
Ah! oui effectivement,j'ai pas fait mon décalage comme ça.. là je comprends mieux.

Pour le 0xFF pourquoi est'il dans trois lignes et à quoi sert le & dans les deux dernières ?


(Intéressant ton article).
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

julien@pobot.org

#18
Mar 19, 2009, 01:27 pm Last Edit: Mar 19, 2009, 11:15 pm by julien@pobot.org Reason: 1
La première ligne, il a le même rôle que ton 'T', il est là pour identifier le début d'une trame (3 octets, le premier FF est non significatif).

Pour la présence du FF dans les deux lignes suivantes, je ne sais pas vraiment, c'est une habitude que j'ai vu.

EDIT : j'ai les réponses d'un des membres de Pobot

Quote

> Serial.print( (val >> 8) & 0xff, BYTE);

Cela sert à être certain d'avoir un résultat après décalage sur un byte au cas où val ait été déclaré signé et que le bit de signe soit propagé par le shift.

> Serial.print( val & 0xff, BYTE);

Cela sert à être certain d'avoir un résultat après décalage sur un byte.

En principe ça ne semble pas indispensable puisqu'on spécifie à print() que la donnée est sur un byte. Mais ça ne mange pas de pain au cas où on utilise autre chose comme fonction et qu'on oublie de forcer la taille de la donnée envoyée.

jfs

Merci pour ces précisions.

Est-ce possible d'envoyer un "long" par la même méthode (4 octets) ?
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

jfs

#20
Mar 21, 2009, 03:34 pm Last Edit: Mar 21, 2009, 03:48 pm by jfs Reason: 1
J'ai fait quelques essais.

Sur la carte Rx :

Code: [Select]
long val = 0x74CBB1;

Serial.print(0xff, BYTE); // la valeur envoyée est 0xFF
Serial.print((val >> 24) & 0xFF, BYTE); // la valeur envoyée est 0x0
Serial.print((val >> 16) & 0xFF, BYTE); // la valeur envoyée est 0x74
Serial.print((val >> 8) & 0xFF, BYTE); // la valeur envoyée est 0xCB
Serial.print(val & 0xFF, BYTE); // la valeur envoyée est 0xB1


Si je remplace BYTE par HEX, sur le moniteur série j'ai FF074CBB1, donc jusque là ça va.

Sur la carte Tx, je pensais qu'avec ce code j'arriverais à récupérer mes valeurs :

Code: [Select]
while (Serial.available() >= 5) {  //  5 = 1 octet pour FF + 4 octets
   if (Serial.read() == 0xff) { // le premier octet, équivalent à ton T
val = ((Serial.read() << 24) |(Serial.read() << 16))|((Serial.read() << 8) |(Serial.read()));

Serial.println(val,DEC);
 
       


mais cela ne fonctionne pas, la valeur retournée est -19969.

Pour voir ce que j'avais dans le flux, j'ai essayé de faire :

Code: [Select]
Serial.println(serial.read(),HEX)

Les 100 premières lignes j'ai :

Code: [Select]
FF
74
CB
B1
FF
74
CB
B1
FF
74
CB


Et ensuite je n'ai plus qu'une valeur qui est retournée :

Code: [Select]

CB
CB
CB
CB
CB
CB
CB
CB
CB
CB
CB
CB

Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

jfs

#21
Mar 22, 2009, 12:22 am Last Edit: Mar 22, 2009, 07:55 am by jfs Reason: 1
Si j'utilise directement le Serial.read avec les bitwises , ça ne fonctionne pas, par contre en faisant comme cela, ça marche  :D :

Code: [Select]
void loop()
{
while (Serial.available() >= 5) {
   if (Serial.read() == 0xff) {
val = Serial.read();
val2 = Serial.read();
val3 = Serial.read();
val4 = Serial.read();

Serial.flush();

valeur=((val4<<24)|(val3<<16)|(val2<<8)|(val));

 Serial.println(valeur);
       
   }
 }
}


Depuis la carte Rx j'envoie 987654321 et en lisant la carte Tx avec le moniteur la variable "valeur" affiche 987654321.
Si je fais "valeur+10" j'ai 987654331.  :)

Par contre si quelqu'un a un tuyaux pour raccourcir tout ça  ;).
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

jfs

#22
Mar 22, 2009, 10:12 am Last Edit: Mar 22, 2009, 10:13 am by jfs Reason: 1
Je viens de remarquer quelques chose, si j'envoie un nombre avec une série de F comme 7FAFFAF, la lecture n'est pas juste à chaque fois, je pense qu'il prend le FF du milieu comme balise de départ.

Comment remédier à ce problème ?
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

julien@pobot.org

utilise deux caractères comme séquence de départ.

jfs

Ce que je voulais dire c'est que j'envoie d'abord FF et ensuite mon nombre.
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

julien@pobot.org

Oui, pas de problème. Normalement il n'y a pas de raison qu'il perde des caractères, mais si c'est le cas, il ne fera pas de distinction entre le FF du début et le FF en plein milieu.

Donc si j'ai bien compris, tu peux envoyer ceci :

FF 01 FF 32 1E
FF 04 23 60 AD
FF 03 C6 FF F3

mais si le premier octet n'est pas passé, il va jeter le 01 et tu vas te retrouver avec

FF 32 1E FF 04 --> faux
23 60 AD --> supprimé
FF 03 C6 FF F3 --> récupéré par chance

Il y a deux solutions :

- allonger la chaine de reconnaissance et diminuer la probabilité de retrouver cette même séquence : soit FF FF, soit FA FA ou tout autre chaine selon les valeurs que tu envoie

- utiliser un "CRC", une formule de vérification qui t'oblige à envoyer une valeur supplémentaire, et à faire un calcul sur les octets reçus puis comparer et ainsi vérifier que c'est toujours correct.

jfs

Tu as bien cerné le problème, c'est exactement ça.

Un contrôle de redondance cyclique serait bien, mais plus complexe à mettre en place.
Pas d'aide par MP !!!

Concernant le fonctionnement du forum tout se trouve dans les messages épinglés en tête de page.

Go Up