Go Down

Topic: envoyer variable float sur xbee (Read 4575 times) previous topic - next topic

hppp

Salut à tous,

Je suis en train de récupérer la valeur d'une température dans une variable float et je voudrais l'envoyer par un module xbee end-device vers un cordinator mais je n'y arrive pas.

J'ai essayé avec un union ( http://streylab.com/blog/2012/10/14/sending-humidity-and-temperature-data-with-zigbee.html ) mais il semble mal convertir les données. Par exemple quand j'envoie 19.4 il me le convertie en  33 33 B3 41 se qui correspond pas du tous à la data de départ d'après la table ASCII.

Aurez-vous une solution facile de convertir mon float pour l'envoyé avec les Xbee?

Merci de votre aide

skywodd

Bonjour,

Il faut faire la différence entre transferts binaires et transferts textuels, ici tu fait des transferts binaires donc la table ASCII n'as rien à voir la dedans.
C'est quoi ce "cordinator" ?
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

hppp


Bonjour,

Il faut faire la différence entre transferts binaires et transferts textuels, ici tu fait des transferts binaires donc la table ASCII n'as rien à voir la dedans.
C'est quoi ce "cordinator" ?


Le coordinateur est le Xbee connecté avec la platine USB sur mon pc. Ensuite j'ai le Arduino qui est connecté sur un Xbee en mode End-Device et qui envoie un relevé de température au coordinateur.

J'utilise pour cela la bibliothèque <xbee.h> et la fonction ZBTxRequest pour fabriquer ma trame avant l'envoie. Mais elle attend comme argument pour la data un uint8_t et moi de l'autre coté ma température est stocké dans un float.

Je viens de voir que dans l'exemple de la libraire qu'il fessait un truc comme ça pour convertir un int :

  payload[0] = temp2 >> 8 & 0xff; ==> décale de 8bits et font ensuite un AND avec 11111111
  payload[1] = temp2 & 0xff; ==> de nouveau un AND avec 11111111

Enfin je comprends pas trop le principe la.

Merci de votre aide en tt cas.  :)


hppp



Bonjour,

Il faut faire la différence entre transferts binaires et transferts textuels, ici tu fait des transferts binaires donc la table ASCII n'as rien à voir la dedans.
C'est quoi ce "cordinator" ?


Le coordinateur est le Xbee connecté avec la platine USB sur mon pc. Ensuite j'ai le Arduino qui est connecté sur un Xbee en mode End-Device et qui envoie un relevé de température au coordinateur.

J'utilise pour cela la bibliothèque <xbee.h> et la fonction ZBTxRequest pour fabriquer ma trame avant l'envoie. Mais elle attend comme argument pour la data un uint8_t et moi de l'autre coté ma température est stocké dans un float.

Je viens de voir que dans l'exemple de la libraire qu'il fessait un truc comme ça pour convertir un int :

  payload[0] = temp2 >> 8 & 0xff; ==> décale de 8bits et font ensuite un AND avec 11111111
  payload[1] = temp2 & 0xff; ==> de nouveau un AND avec 11111111

Enfin je comprends pas trop le principe la.

Merci de votre aide en tt cas.  :)




Je viens de peut être comprendre ...

float est codé sur 32bits, donc en fait sur payload[0] il récupère les 8 premiers bits de poids faible et fait un AND mais la je sais pas pourquoi ...
Et après il récupère  le reste et fait un AND mais pourquoi? je ne sais pas, dites le moi si je me trompe ...

Donc une fois la trame reçu en hexa sur le pc, il faut que je fasse l'opération inverse? Mais la non plus, mais je ne connais pas l'opération inverse pour retrouver mes données ...

hppp

Bon, je suis arrivé à mes fin mais avec un code sale ... si vous avez mieux à proposer je suis ouvert :

Code: [Select]
float temp =22.33;

char ascii[6];

int temp1 = (temp - (int)temp) * 100;
sprintf(ascii,"%0d.%d", (int)temp, temp1);

for (int i = 0; i < 6; i++) {
  payload[i]=ascii[i];
}
xbee.send(zbTx);


En gros l'idéal pour moi est de récupérer de l'autre coté soit un float, soit un char.

Merci

fdufnews

#5
Aug 15, 2013, 06:42 pm Last Edit: Aug 15, 2013, 06:44 pm by fdufnews Reason: 1
Quote
J'ai essayé avec un union ( http://streylab.com/blog/2012/10/14/sending-humidity-and-temperature-data-with-zigbee.html ) mais il semble mal convertir les données. Par exemple quand j'envoie 19.4 il me le convertie en  33 33 B3 41 se qui correspond pas du tous à la data de départ d'après la table ASCII.

La valeur qui te semble bizarre c'est ton float qui est codé. La valeur d'un flottant n'apparaît pas en clair lorsqu'on regarde les octets qui le composent.

Quote
Bon, je suis arrivé à mes fin mais avec un code sale ... si vous avez mieux à proposer je suis ouvert :

L'union fonctionne dans les 2 sens.
A l'émission, tu mets un float dans l'union et tu ressors 4 uint8_t que tu émets.
A la réception, tu entres 4 uint8_t dans l'union et tu ressors un float.

En théorie c'est bon. En pratique si les 2 équipements ne codent pas les float de la même manière cela pourrait ne pas fonctionner.

hppp


Quote
J'ai essayé avec un union ( http://streylab.com/blog/2012/10/14/sending-humidity-and-temperature-data-with-zigbee.html ) mais il semble mal convertir les données. Par exemple quand j'envoie 19.4 il me le convertie en  33 33 B3 41 se qui correspond pas du tous à la data de départ d'après la table ASCII.

La valeur qui te semble bizarre c'est ton float qui est codé. La valeur d'un flottant n'apparaît pas en clair lorsqu'on regarde les octets qui le composent.

Quote
Bon, je suis arrivé à mes fin mais avec un code sale ... si vous avez mieux à proposer je suis ouvert :

L'union fonctionne dans les 2 sens.
A l'émission, tu mets un float dans l'union et tu ressors 4 uint8_t que tu émets.
A la réception, tu entres 4 uint8_t dans l'union et tu ressors un float.

En théorie c'est bon. En pratique si les 2 équipements ne codent pas les float de la même manière cela pourrait ne pas fonctionner.


Le problème c'est que c'est l'arduino qui va coder et l'ordinateur qui va décoder, donc faut éviter l'union d'après ce que tu me dis?

Conclusion, ma solution est sale mais marche ...

skywodd

Solution simple et efficace : conversion en nombre entier (nombre à virgule fixe).
Tu perd en précision mais est-ce bien critique ici ?

Arduino
Code: [Select]
float val = 13.37; // Valeur en virgule flottante
int ival = val * 100; // Valeur en virgule fixe (via un coeff x100)

// Fabrication du payload (int = 2 octets)
payload[0] = ival & 0xFF;
payload[1] = ival >> 8;


PC
Code: [Select]
// Décodage du payload
int ival = payload[0] | (payload[1] << 8);

// Reformatage de ton nombre en virgule flottante
float val = ival / 100.0;
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

hppp


Solution simple et efficace : conversion en nombre entier (nombre à virgule fixe).
Tu perd en précision mais est-ce bien critique ici ?

Arduino
Code: [Select]
float val = 13.37; // Valeur en virgule flottante
int ival = val * 100; // Valeur en virgule fixe (via un coeff x100)

// Fabrication du payload (int = 2 octets)
payload[0] = ival & 0xFF;
payload[1] = ival >> 8;


PC
Code: [Select]
// Décodage du payload
int ival = payload[0] | (payload[1] << 8);

// Reformatage de ton nombre en virgule flottante
float val = ival / 100.0;



Je vais prendre ta solution plus pro ;)

Maintenant je vais m'attaquer à la partie réception des données avec un programme en C, mais j'ai des petits problème avec le port série ...

Merci en tt cas.

hppp

Question si quelqu'un sait. Je veux donc récupérer mes données sur le port série du PC envoyé par le Xbee connecté en USB avec un émulateur de port série.

Avec Minicom pas de problème, je reçois bien mes données et vois passer ma température sous forme de nombre.

Quand je me code un petit programme en C, que j'ouvre le port série et que je fais un Read() je reçois bien quelque chose mais après je fait un boucle pour voir si je reçois un 0x7E qui est le début de ma trame Xbee, mais je ne le vois jamais donc ça boucle indéfiniment.

Quand je fais un :

printf("hexa : %#2x \n",hexa);

effectivement je ne vois jamais passer mon octet 0x7E.

Mon problème c'est que je sais pas dans quel genre de tableau stocker mes données reçu. Pour le moment je les mets dans un char, mais je pense que je dois me planter...

Savez-vous sous quelle forme on reçois les données sur le port série une fois passé l'OS? Char? Hex? bits ?

Merci

fdufnews

#10
Aug 15, 2013, 11:08 pm Last Edit: Aug 15, 2013, 11:16 pm by fdufnews Reason: 1
Quote
Savez-vous sous quelle forme on reçois les données sur le port série une fois passé l'OS? Char? Hex? bits ?

On les reçoit comme on les a envoyées. Le support utilisé pour le transfert est transparent pour l'utilisateur et il ne modifie pas les données. Si tu envoies des char tu reçois des char.
De toutes les façons char hex et bits c'est la même chose.
C'est juste la manière de les afficher qui les présente différemment.
65d= 0x41 = 0b01000001 = 'A'

Go Up