Transfert de fichier d'une carte S vers un PC par Websocket

Bonjour,
Je souhaiterais réaliser un transfert de fichier provenant dune carte SD par Websocket mais je ne sais absolument pas comment faire.
Quelqu'un aurait il une idée ou un exemple?
Merci d'avance

Juste pour être sur que nous avons la même compréhension : les WebSocket ce sont des points de connexion TCP qui sont géré depuis le navigateur web dans du code HTML5.
Coté Arduino, il faut utiliser EthernetServer
Ensuite il faut te faire un petit protocole pour que la WebSocket demande à l'Arduino le contenu de la carte SD.
L'Arduino traite la requête en lisant la carte SD et en renvoyant le contenu sur EthernetServeur (connecté à l'autre bout à la WebSocket)

Bonjour,

Si par "websocket" tu entends html5 :

Je viens de passer 2 soirs à essayer cette lib.
C'est pas gagné

J'ai des plantages incompréhensibles qui semblent liés à l'utilisation de String.
Ce n'est pas un problème de manque de mémoire car ça par en live assez rapidement et freeMemory() de donne plus de 1KO de dispo.

J'ai du ré-écrire une bonne partie du code de parsing du handshake en virant les String et en passant en tableau de char. La connexion passe maintenant mais ça se vautre plus loin.

Il arrive que même freeMemory() lui-même se vautre.

Fais ch... de pas pouvoir faire de pas à pas. Je crois je vais finir par me payer un AVRDragon.

Bref, je soupçonne :

  • soit un bon gros jardinage qui me fout en l'air soit la stack soit le heap (vu que même freeMemory part en sucette)
  • soit que realloc() est buggé

Skywodd, n'avais tu pas dis déjà qu'il y avait un problème avec la gestion de mémoire dynamique ?
Un upgrade de la chaîne WinAVR permettrait-il de régler le problème ?
(je suis toujours avec la chaîne par défaut de l'IDE v1.0.1)

Je me répond à moi-même

J'ai upgradé le WinAVR à la version 20100110 et ca marche impec.
Même le code d'origine avec tout ses strings marche très bien.

Conclusion : IL FAUT UPGRADER SON WINAVR !!!!!!

Sinon, Y'a pas de doute, ces WebSocket ca à l'air pas mal.
Plus simple a utiliser que du Ajax d'un point de vue code JavaScript, surtout coté Arduino.
Pas besoin de Webduino pour parser des requêtes POST/GET donc le code devrait pouvoir être plus léger.
Programmation complètement asynchrone et bidirectionnelle : l'Arduino peut envoyer de lui même des trames et cela déclenche un callback onmessage().
Par contre c'est une connexion persistante donc potentiellement il faire plus attention aux aspects connexion/déconnexion.

Il faudrait que je relise le topic d'Osaka qui est très pro-websocket car apparemment il a fait les choses un peu différemment sans gérer le handshake sur l'Arduino.

Bonjour,
Tout d'abord merci pour vos aide.
Et comment faites vous pour Upgrader votre AVR?
Cela marche avec une arduino Mega?
Et auriez vous un exemple web socket qui marche?
Vous fonctionner avec du Wifi ou de l'Ethernet (WS5100)?
Merci d'avance.

J'utilise un W5100
J'ai du légèrement adapter l'exemple (je viens de te répondre sur ton topic avec le code source adapté)
Mais je n'ai pas eu à toucher à la lib
Je n'ai utilisé que Chrome

Pour mettre à jour le compilo WinAVR il faut :

  • Télécharger l'installeur ici WinAVR - Browse /WinAVR/20100110 at SourceForge.net
  • Installer où tu veux
  • renommer c:\arduino\hardware\tools\avr en avr_original
  • déplacer le répertoire avr nouvellement installé à la place de l'ancien : tu dois garder le même niveau de répertoire
  • dans le nouveau avr, il supprimer :
    avr/bin/avrdude.exe
    avr/bin/avrdude.conf
    avr/etc/avrdude.conf
    et les remplacer par ceux de l'ancien avr_original (il n'y a pas de bin/avrdude.conf dans l'ancien, c'est pas grave)

Mais avant de te lancer la dedans, soit sur d'avoir des problèmes qui le justifie.

barbudor:
Fais ch... de pas pouvoir faire de pas à pas. Je crois je vais finir par me payer un AVRDragon.

C'est hyper fragile les AVRdragon, au moindre faux contact ... cramé ...

barbudor:
Skywodd, n'avais tu pas dis déjà qu'il y avait un problème avec la gestion de mémoire dynamique ?
Un upgrade de la chaîne WinAVR permettrait-il de régler le problème ?
(je suis toujours avec la chaîne par défaut de l'IDE v1.0.1)

La version fourni de base est complétement buggé au niveau de la gestion des new / delete, etc
Le problème a été remonté à la team arduino plusieurs fois sans réponse de leur pars ...

barbudor:
Sinon, Y'a pas de doute, ces WebSocket ca à l'air pas mal.
Plus simple a utiliser que du Ajax d'un point de vue code JavaScript, surtout coté Arduino.
Pas besoin de Webduino pour parser des requêtes POST/GET donc le code devrait pouvoir être plus léger.
Programmation complètement asynchrone et bidirectionnelle : l'Arduino peut envoyer de lui même des trames et cela déclenche un callback onmessage().
Par contre c'est une connexion persistante donc potentiellement il faire plus attention aux aspects connexion/déconnexion.

Les websockets sont de plus en plus utilisés mais il faut aussi prendre en compte la compatibilité avec les navigateurs.
Et pour ça c'est pas encore gagner ...

barbudor:

  • dans le nouveau avr, il supprimer :
    avr/bin/avrdude.exe
    avr/bin/avrdude.conf
    avr/etc/avrdude.conf
    et les remplacer par ceux de l'ancien avr_original (il n'y a pas de bin/avrdude.conf dans l'ancien, c'est pas grave)

Même pas besoin de toucher à avrdude.exe et avrdude.conf :wink:

Point 1, 2 et 3 pour la mise à jour de winAVR :

skywodd:
Même pas besoin de toucher à avrdude.exe et avrdude.conf :wink:

Hum.
Il me semble que l'AVRdude d'Arduino est modifié, notamment pour la léonardo.

barbudor:
Hum.
Il me semble que l'AVRdude d'Arduino est modifié, notamment pour la léonardo.

Ha bon ? Moins j'ai aucun soucis avec l'avrdude d'origne de winAVR.

Celui fourni avec la dernière version contient déjà le patch pour supporter le mode "arduino".
Aprés s'ils ont fait un nouveau patch pour la leonardo je l'ai même pas remarquer :.

ok, Je ferais des essais quand je serais rentré lundi

Suite à mes premiers tests, l'Arduino a du mal a gérer les websockets: la meilleures solutions (et il me semble qu'Osaka avait conclue à la même chose) c'est de faire un server mixte.

C'est à dire que côté clients web on fonctionne bien en websockets mais côté Arduino lors de l'authentification au server il faut que ce dernier saisisse qu'il discute à l'Arduino (via IP ou analyse de trame spécifique) puis courcicuite la phase de Handshake pour directement ajouter l'Arduino dans sa liste des users.

De cette facon, on arrive a un système completement fluide (aussi bien via Ethernet que via GPRS).

Au niveau navigateurs: ca fonctionne bien sous safari/safari mobile/chrome/chrome mobile/FF.

Si je comprend bien tu fais intervenir un serveur entre les 2

Navigateur ---(websocket)---> Serveur Web / PHP ---(socket simple)---> Arduino

C'est ca ?

parce qu'il n'y a pas moyen que le navigateur court-circuite le handshake
Or moi je parle d'une solution directe

Navigateur ---(websocket)---> Arduino

Donc avec handshake géré par l'Arduino.

Le problème (que j'ai re-soulevé sur ton autre post ailleurs) c'est que les hébergeurs généralement désactivent les sockets PHP.

Bonjour,

Pour faire marcher mes websocket directement entre le navigateur web et l'arduino, je procède comme suit:

côté navigateur, un peu de javascript pour initier la connexion:

	var		source;
	var		data;
	var		object;
	
	
	if (typeof (EventSource) == undefined)
	{
		// websockets non supportés par le navigateur
	}
	else
	{
		souce = new EventSource ("mon_event_handler");
		souce.onmessage = function (event)
		{
			// ici, eval.data contient les données renvoyées par l'arduino
			// cette partie est appelée à chaque envoi de données de l'arduino
		}
	}

et côté arduino:

pour préparer la socket, StartEventHandler doit être appelé dans le code du serveur web de l'arduino lorsqu'on détecte la bonne requête:

	// ligne contient la 1ère ligne de texte lue sur la socket obtenue avec client = server.available ()

	if (strcmp (ligne, "GET /mon_event_handler HTTP/1.1") == 0)
	{
		// fermeture de l'ancienne (on en garde qu'une à la fois)
		if (_socketEventHandler)
			_socketEventHandler->stop ();
	
		// renvoi de l'entête
		_socketEventHandler = client;
		_socketEventHandler->println ("HTTP/1.1 200 OK\n");
		_socketEventHandler->println ("Connection: keep-alive");
		_socketEventHandler->println ("Cache-control: no-cache");
		_socketEventHandler->println ("Content-Type: text/event-stream");
		_socketEventHandler->println ("");
	}

ensuite chaque fois qu'on veut envoyer des données dynamiquement au navigateur web, on écrit sur la socket _socketEventHandler:

	_socketEventHandler->println ("data: ");

	// écrire ici les données avec println
	_socketEventHandler->println ("coucou :)");

	// signaler la fin des données
	_socketEventHandler->println ();

y'a sûrement quelques fautes, car c'est tiré de mon projet et adapté, mais le principe est là.

si ça peut aider quelqu'un…

Ok
mais si je comprend bien, ce n'est pas des WebSocket mais des Serveur-Sent Events

Je découvre mais çà ne semple pas être tout a fait la même chose:

  • Mise en oeuvre apparemment plus simple puisqu'on se contente de garder la connexion HTTP en keep alive (pas de Upgrade handshake)
  • Mais mono directionnel : serveur -> client uniquement
    Le navigateur ne peut rien demander tel que envoyer un message si l'utilisateur clique un bouton

ah, j'ai confondu les deux technologies alors :astonished:

le client doit effectivement causer au serveur avec une requête dédiée… dans mon cas les appuis sur les boutons de la page web génèrent des requêtes GET tout à fait standard, et si l'état d'un objet change côté arduino (indépendamment de la page web), il est renvoyé à la page via un server sent event...

ok mais l'Arduino ne peut avoir qu'une seule connection active
Si le client envoi un get, ca oblige a fermer la socket des SSE (Server-Sent-Event)
Et donc il faut la ré-ouvrir derrière ?

Ca me parait un peu lourd non ?
Ou j'ai zappé quelque chose ?

Le WebSocket est complètement bidir. le handshake n'est pas très compliqué à part cette histoire de génération SHA-1 mais la lib que j'ai utilisé pour expérimenté le fait bien.
Il faudrait juste la ré-écrire pour se débarrasser de ces @#!%~de String

le shield ethernet w5100 support 4 sockets simultanées, donc c'est jouable

Hello,

Oui c'est bien ca:

Navigateur ---(websocket)---> Serveur Web / PHP ---(socket simple)---> Arduino

Car finalement, quel est l'interet de créer un websocket pour l'Arduino ? Le WS est utile niveau client web pour le temps réel !

Et évidement je suis en auto-hébergé :wink: !

Auto-herbergé demande d'avoir un PC allumé en permanence à la maison

  • Potentielle faille de sécurité si on prend la main sur ce PC

De mon point de vue c'est plus simple d'avoir les pages web sur un serveur de page perso puis de discuter ensuite directement entre le client et l'Arduino sans passer par un serveur web (qui n'était là que pour permettre de charger les pages).
Pourquoi avoir une tierce partie entre les 2 ?
Avec les WebSockets c'est assez simple.