Go Down

Topic: Domotique à base d'Arduino: XAP et XPL (Read 2 times) previous topic - next topic

Gromain59

Bonjour à tous,

je m'intéresses à XPL et XAP, deux protocoles ouverts orientés domotique. Y-a-t-il des membres du forum qui auraient entrepris quelques choses sur ce thème ?
Laser. a déjà fait quelque chose sur XAP.

Gromain59
"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

Benchi

Attendant ma première Arduino, je n'ai rien fait dessus pour le moment.
Mais ayant un projet orienté domotique avec Arduino et foxboard, le thème XPL m'intéresse beaucoup !
Si tu as des infos, je suis plus que preneur  :)

Gromain59

Bonjour,

j'ai avancé sur le sujet du XPL.
j'ai d'abord écrit un sketch permettant de décoder la partie "header" d'un message XPL ainsi que le type de schéma.
C'est un peu poil gourmand en ressource mémoire RAM (nécessite au minimum un arduino 328) mais ça fonctionne.

Comme j'ai enfin un Mega et son shield Ethernet, j'ai également testé la réception de message XPL (UDP) et son décodage.

Bilan: ça marche bien avec un XPL hub sous windows, c'est un peu moins satisfaisant avec le hub en java (?!)
Mais ca ne résiste pas bien à un bombardement de message XPL (genre 4-5 message par seconde). L'arduino fini par planter. Je penche pour un problème de libération de la mémoire RAM... peut-être qu'en utilisant l'instruction malloc() ?

Donc je continue mes tests et j'espère obtenir un bon résultat rapidement  ;D

Pour ceux qui utilisent XPL dans le leur installation domotique, j'aimerai avoir une idée du nombre de message XPL qui peut circuler sur le réseau ?

Gromain
"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

karistouf

#3
Sep 22, 2010, 06:52 pm Last Edit: Sep 22, 2010, 06:54 pm by karistouf Reason: 1

je ne connais pas la taille en bytes de ton protocole, mais
4-5 messages par seconde, c est ridicule et ca ne devrait pas bloquer. Tu dois envoyer et recevoir en mode non bloquant pour augmenter la cadence.


y a t il un lien pour aller voir ce protocole en détail , et quelles en sont actuellement les applications ?

Gromain59

C'est le protocole XPL qui utilise l'UDP: l'arduino demande au shield Ethernet d'écouter un port. Ensuite il reçoit au fur et à mesure les données.
Typiquement, ce sont des datagrammes d'environ 200 octets, dont 42 pour l'en-tête UDP et au minimum 100 octets de données. Ce sont ces derniers que je décode.
Je penchais d'abord pour un plantage du shield Ethernet (Wiznet), mais c'est bel et bien le sketch qui plante...

lien vers une description du protocole XPL:
http://xplproject.org.uk/wiki/index.php?title=XPL_Specification_Document
"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

karistouf

je ne me suis pas penché du tout sur l ethernet en arduino ( ca ne saurait tarder), mais typiquement ca sent un overflow de données, ou une erreur d initialisation de ta partie serveur, qui devrait être en udp. essaye d envoyer en unicast d abord ( vers une adresse précise).
le protocole est très léger, tu peux monter sur des cadences à 50 envosi secondes sans souci

peux tu poster ton sketch ? à++

Gromain59

Voici le sketch, sans la partie décodage, que j'intégrerai quand la réception sera optimal.

Code: [Select]
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>

/* UdpReceiveRaw.pde: Example how to receive packets over UDP using UdpRaw library
* prints received packet to serial port
* bjoern@cs.stanford.edu 12/30/2008
*/

/* ETHERNET SHIELD CONFIGURATION  
* set MAC, IP address of Ethernet shield, its gateway,
* and local port to listen on for incoming packets
*/
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address to use
byte ip[] = { 192, 168, 1, 177 }; // Arduino's IP address
byte gw[] = { 192, 168, 1, 1 };   // Gateway IP address
int localPort = 3865; // local port to listen on

#define MAX_SIZE 300 // maximum packet size
byte packetBuffer[MAX_SIZE]; //buffer to hold incoming packet
int packetSize; // holds received packet size
byte remoteIp[4]; // holds recvieved packet's originating IP
unsigned int remotePort; // holds received packet's originating port
boolean donnees= false;
int i;

/* SETUP: init Ethernet shield, start UDP listening, open serial port */
void setup() {
 Ethernet.begin(mac,ip,gw);
 Udp.begin(localPort);
 Serial.begin(38400);
}
/* LOOP: wait for incoming packets and print each packet to the serial port */
void loop() {  
 
 // if there's data available, read a packet
 if(Udp.available()) {
   
   packetSize = Udp.readPacket(packetBuffer,MAX_SIZE,remoteIp,(uint16_t *)&remotePort);
   
     Serial.print("Received packet of size ");
     Serial.println(abs(packetSize));

     Serial.print("From IP ");
     for(i=0; i<3; i++) {
       Serial.print(remoteIp[i],DEC);
       Serial.print(".");
     }
     Serial.print(remoteIp[3],DEC);
     
     Serial.print(" Port ");
     Serial.println(remotePort);
     
     if(packetSize < 0) {
       // if return value <0 the packet was truncated to fit into our buffer
       Serial.print("ERROR: Packet was truncated from ");
       Serial.print(packetSize*-1);
       Serial.print(" to ");
       Serial.print(MAX_SIZE);
       Serial.println(" bytes.");
     }
     
     Serial.println("Contents:");
     for(i=0; i<min(MAX_SIZE,abs(packetSize)); i++) {
       Serial.print(packetBuffer[i],BYTE);
     }
 }
 //wait a bit
 delay(10);  
}



Le type de message que je reçois:

Quote
Received packet of size 139
From IP 192.168.1.2 Port 3476
Contents:
xpl-stat
{
hop=1
source=cdp1802-xplnet.00000102o27kn
target=*
}
config.app
{
interval=5
port=3475
remote-ip=192.168.1.2
version=1.4.7144
}


Le hub XPL  envoie ce message en broadcoast, donc ça va être un peu compliqué pour moi d'envoyer en unicast.

En tout cas, ça a l'air de planter à la sortie du traitement du message, aux environs du delay(10).
"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

karistouf

essaye à la place
de

 
Code: [Select]

   packetSize = Udp.readPacket(packetBuffer,MAX_SIZE,remoteIp,(uint16_t *)&remotePort);
   

Code: [Select]

if(packetSize = Udp.readPacket(packetBuffer,MAX_SIZE,remoteIp,(uint16_t *)&remotePort))>0)
{

...
}
   

Gromain59

Merci karistouf de tes suggestions.

Après avoir épluché le datasheet du contrôleur Ethernet (W5100) et les lib Udp, Socket et W5100 de l'arduino, je pense que la lib udp ne gère pas correctement le buffer du W5100: si un 2nd datagramme arrive avant la fin du traitement du 1er, la lib ne sait pas détecté le header et ça part en sucette.
Du coup, j'ai modifié la lib Udp pour lui ajouter une méthode "stop" qui ferme le socket à l'arrivée d'un datagramme. Je le rouvre après avoir acquis les données.
Ainsi, je loupe peut-être un datagramme s'il est vraiment proche du précédent, mais au moins ça ne plante plus...

Gromain
"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

karistouf

#9
Sep 24, 2010, 10:55 am Last Edit: Sep 24, 2010, 10:56 am by karistouf Reason: 1
hello gromain, peux tu eventuellement attacher ici ta modif de lib ?

pas encore regardé de pres la lib udp ( ... ). mais ca me parait bizarre.
par essence on se permet de perdre des paquets en udp.

tu peux aussi regarder ce genre de sources:
http://bitbucket.org/bjoern/arduino_osc/src/tip/libraries/Ethernet/

Gromain59

#10
Sep 24, 2010, 11:44 am Last Edit: Sep 24, 2010, 11:45 am by Gromain59 Reason: 1
Salut,

Quote
hello gromain, peux tu eventuellement attacher ici ta modif de lib ?


dans Udp.h:
Code: [Select]

public:
 void begin(uint16_t);                        // initialize, start listening on specified port
 int available();                                                // has data been received?
 void stop(void);                        // close the socket <== ajout


dans Udp.cpp

Code: [Select]
void UdpClass::begin(uint16_t port) {
 _port = port;
 _sock = 0; //TODO: should not be hardcoded
 socket(_sock, SnMR::UDP, _port, 0);
}

/* Close UDP socket */
void UdpClass::stop(void) {  <== ajout
 close(0);                      <== ajout
}                                 <== ajout


Quote
pas encore regardé de pres la lib udp ( ... ). mais ca me parait bizarre.
par essence on se permet de perdre des paquets en udp.


Oui, on utilise UDP quand on peut se permettre de perdre des paquets, ou qu'on a besoin de rapidité.
Je pense que le problème n'est pas dans la capacité du chip wiznet à récupérer les datagrammes, il le fait très bien. Il est plutôt du côté de la lib UDP qui ne semble pas être prévu pour détecter les 8 octets de l'en-tête UDP dans le buffer du chip. Cette lib se base sur la notification d'arrivée de données, récupére les 8 premiers octets pour connaitre les IP et ports, puis le reste est considéré comme des données. Du coup, si un datagramme vient s'empiler dans le buffer du chip, ça plante.
Je contourne le problème en fermant le socket le temps de vider le buffer.

Quote

tu peux aussi regarder ce genre de sources:
http://bitbucket.org/bjoern/arduino_osc/src/tip/libraries/Ethernet/

C'est cette lib que j'utilise. Depuis la version 19 de l'IDE elle est intégrée aux lib Ethernet.

Gromain
"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

karistouf

#11
Sep 24, 2010, 12:04 pm Last Edit: Sep 24, 2010, 12:08 pm by karistouf Reason: 1
hum hum .... got it...
et tu ne peux pas décaller l écriture du buffer de 8 bytes vers la droite ?

merci en tout cas pour les infos, j arriverais certainement sur le forum avec plein d au secours du meme type quand j y mettrais les doigts ....

j essayerais certainement cette lib:
http://arduino-powered.blogspot.com/2009/07/using-udp-with-arduino.html

NB: la 019 est sortie pour windows?

Gromain59

Oui, la version 19 pour windows est sortie...

Quote
et tu ne peux pas décaller l écriture du buffer de 8 bytes vers la droite ?

ça doit être faisable, mais pour ça il faut connaitre l'adresse du 1er octet du datagramme. Pas certain qu'on est l'info à l'heure actuelle.
"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

karistouf

tu peux splitter la chaine après. et décoder le reste

Ferllings

@Gromain59: J'ai le code arduino de Vincent (forum xplproject), je sais que tu était interessé aussi.
J'ai pas le temps de le tester en ce moment (trop de boulot sur Domogik), mais si toi ou qqu d'autre est interessé pour le faire, envoyer moi votre email en MP, et je ferais suivre.

Go Up