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
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
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
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
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 ?
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
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 ? à++
Voici le sketch, sans la partie décodage, que j'intégrerai quand la réception sera optimal.
#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:
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).
essaye à la place
de
packetSize = Udp.readPacket(packetBuffer,MAX_SIZE,remoteIp,(uint16_t *)&remotePort);
if(packetSize = Udp.readPacket(packetBuffer,MAX_SIZE,remoteIp,(uint16_t *)&remotePort))>0)
{
...
}
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
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/
Salut,
hello gromain, peux tu eventuellement attacher ici ta modif de lib ?
dans Udp.h:
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
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
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.
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
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:
NB: la 019 est sortie pour windows?
Oui, la version 19 pour windows est sortie...
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.
tu peux splitter la chaine après. et décoder le reste
@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.
tu peux splitter la chaine après. et décoder le reste
oui, mais pour cela il faudrait connaitre l'adresse du premier octet du 2eme message
J'ai le code arduino de Vincent (forum xplproject)
oui, je suis interessé. Je pourrais comparer avec ce que j'ai fait. Je t'envoie un MP
Bonjour,
j'ai donc écrit un exemple de décodeur de message xPL (et xAP moyennant quelques adaptations).
les sketchs sont à récupérer ici: http://www.humyo.fr/FXgSdjW/UdpXpl.zip?a=QAlLdaFTljI
UdpXpl.pde => réception et envoi message xpl
parserXpl.pde => traitement du message
Il faut écraser les fichiers Udp.cpp et Udp.h du répertoire libraries Ethernet de l'IDE arduino (~arduino-0019\libraries\Ethernet), par ceux que je fournis. C'est une simple évolution de la lib qui permet de choisir le socket à utiliser. En effet, pour des raisons de performance, j'utilise un socket pour émettre, et un socket pour recevoir.
Avis aux bêta testeurs, si vous avez des axes d'améliorations à proposer, n'hésitez pas !
Testé avec un arduino Mega + shield Ethernet Wiznet. Je sais qu'un arduino 168 ne fonctionnera pas car c'est assez gourmand en RAM. Ca doit passer sur un 328 (si pas, me le remonter)
La partie "parserXpl" peut bien sur fonctionner indépendamment de l'UDP, par une liaison série par exemple.
Enjoy !
Gromain