Go Down

Topic: IPAddress et udp.write (Read 1 time) previous topic - next topic

Pac2Kro

Je cherche à faire des "udp.write" avec des variables de type IPAddress.

Code: [Select]
IPAddress monIP(10,0,0,1);

  udp.write(monIP,4); //ne compile pas

  for (i=0;i<4;i++)
  {
    udp.write(&monIP[i], 1); //compile et fonctionne
  }


Il y a t'il une autre manière de faire sans utiliser la boucle "for"?

skywodd

Bonjour,

Faut lire la doc ! Parfois c'est utile ;)

http://arduino.cc/en/Reference/EthernetUDPWrite
Write() attend un octet (ou un tableau d'octet + taille) en paramètre, pas une IP !

C'est beginPaquet() qui prend une IP en paramètre :
http://arduino.cc/en/Reference/EthernetUDPBeginPacket

La 2éme syntaxe marche car l'opérateur IPAddress[] est défini pour retourner un byte correspondant à un morceau de l'ip (index 0 à 3).
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Pac2Kro

Bonjour,

Et merci pour ta réponse hyper rapide.
Je n'ai pas du donner assez de détail dans ma question ou je l'ai peut être mal formulée.
c'est bien monIP que je veux envoyer sous forme de 4 bytes dans la partie data de la trame udp.
C'est donc bien udp.write que je dois utiliser. Je souhaitais juste alléger le code (si c'est possible).

Code: [Select]
udp.beginPacket(monBroadcast, udpPort);
  for (i=0;i<4;i++)
  {
    udp.write(&monIP[i], 1);
  }
  udp.endPacket();

skywodd


c'est bien monIP que je veux envoyer sous forme de 4 bytes dans la partie data de la trame udp.

Ok, désolé j'avais pas compris :smiley-mr-green:


C'est donc bien udp.write que je dois utiliser. Je souhaitais juste alléger le code (si c'est possible).

Une boucle bien utilisé c'est pas dégueulasse, ton code actuel est trés bien ;)

Si tu veut le rendre plus compact :

Code: [Select]
udp.beginPacket(monBroadcast, udpPort);
for (byte i = 0; i < 4; ++i)
  udp.write(monIP[i]);
udp.endPacket();


Après tu peut pas faire mieux ...
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Pac2Kro

Merci.

Code: [Select]
udp.beginPacket(monBroadcast, udpPort);
for (byte i = 0; i < 4; ++i)
  udp.write(&monIP[i]); //sans le & ça ne compile pas
udp.endPacket();


Quote
udp.write(&monIP);


Par contre, je n'ai pas compris pourquoi il fallait mettre un pointeur.

skywodd


Par contre, je n'ai pas compris pourquoi il fallait mettre un pointeur.

Avec un pointeur ça marche mais pas avec une valeur brute ?

Pas normal ça, write() prend que deux type de paramètres :
Code: [Select]
write(byte val);
ou
Code: [Select]
write(byte* buf, int len);

L'opérateur crochet retournant un byte il ne devrait pas y avoir de problème ...

Et quand je regarde dans EthernetUDP.h :
Code: [Select]
// Write a single byte into the packet
  virtual size_t write(uint8_t);

Donc normalement ce & n'as rien à faire là ...
Tu utilise arduino 1.0.1, 1.0.2 ou 1.0.3 ?

Essaye ça :
Code: [Select]
udp.beginPacket(monBroadcast, udpPort);
for (byte i = 0; i < 4; ++i)
  udp.write((uint8_t) monIP[i]);
udp.endPacket();
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Pac2Kro

#6
Jan 02, 2013, 12:10 pm Last Edit: Jan 02, 2013, 12:17 pm by Pac2Kro Reason: 1
Voici le message d'erreur à la compilation.

Code: [Select]
error: invalid conversion from 'unsigned char' to 'const uint8_t*'
error: initializing argument 1 of 'virtual size_t EthernetUDP::write(const uint8_t*, size_t)'


J'utilise l'IDE 1.0.3.

Edit:Je pense que cela vient du type de la variable IPAddress qui ne doit pas être un simple tableau de bytes.

Avec ton code, la compilation fonctionne.

skywodd


Code: [Select]
error: invalid conversion from 'unsigned char' to 'const uint8_t*'
error: initializing argument 1 of 'virtual size_t EthernetUDP::write(const uint8_t*, size_t)'


Attend ...

Tu utilise :
Code: [Select]
udp.write(monIP[i]);
ou
Code: [Select]
udp.write(monIP[i], 1);
Parce que c'est pas du tout la même chose !

La 1er version envoi un octet directement par valeur, la 2ieme version envoi un buffer.
Manisfestement le compilateur utilise la 2iéme version et non la 1er, d'où l'erreur !
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Pac2Kro

Voici les resultats :

Code: [Select]
    udp.write(monIP[i],1); //compile pas
    udp.write(&monIP[i],1); //compile
    udp.write(monIP[i]); //compile
    udp.write((uint8_t) monIP[i]); //compile


donc il faut utiliser :

Code: [Select]
    udp.write(monIP[i]);

skywodd

Code: [Select]
udp.write(&monIP[i],1); //compile
Test et tu verras que ça ne marchera pas une fois exécuté ;)
Le fait de passer un pointeur va t'envoyer l'adresse (enfin une partie) du pointeur et non sa valeur.
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Pac2Kro


Code: [Select]
udp.write(&monIP[i],1); //compile
Test et tu verras que ça ne marchera pas une fois exécuté ;)
Le fait de passer un pointeur va t'envoyer l'adresse (enfin une partie) du pointeur et non sa valeur.


C'est exactement ce que je me disais et j'aurais l'adresse mémoire de la variable mais pas ça valeur.
D'où mon interrogation.

Par contre, je n'ai pas compris pourquoi il fallait mettre un pointeur.


Mais force est de constater que dans la trame UDP, avec ce code, j'ai bien MonIP.

Pac2Kro

Si personne n'a d'idée sur le sujet, c'est qu'il doit s'agir d'un bug du compilateur!!!

skywodd


Si personne n'a d'idée sur le sujet, c'est qu'il doit s'agir d'un bug du compilateur!!!

J'ai bien une idée mais j'en suis pas sûr du tout.

Code: [Select]
&monIP[i]
IPaddress[] est un opérateur de la classe IPaddress = fonction
IPaddress[n] retourne un byte
&IPaddress[n] retourne un pointeur sur le byte retourné par l'opérateur

Je sait pas comment GCC gére ce type de pointeur "temporaire" en interne, mais faut croire que faire un pointeur sur une valeur de retour fonctionne ...
Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Go Up