Shield wifi en serveur ... (Plus si Lent finalement)

Bonjour à tous ...
J'ai une carte mega 2560 et shield ethernet sur lequel j'ai un serveur pour de la domotique, rien de bien nouveau, juste une page html avec une dizaine de boutons ou listes de choix ... Ça marche très bien.
Seulement le câble qui traverse le salon commence à irriter ma femme alors j'ai investi dans un shield wifi officiel, en me disant que pour son prix, je serai bien servi ...
C'est la que j'ai commencé à me fâcher avec arduino : problème d'adresse mac écrite sur l'étiquette qui n'était pas la bonne (l'adresse ip que j'obtenais de ma box n'était jamais la bonne), problème de version de l'IDE ( il fallait downgrader pour faire marcher les exemples ...). Bref j'ai fini par upgrader le firmware mais je me retrouve avec un serveur digne de l'ère des modems 56k (et encore...) : si je prend l´exemple wifiserver, et qu'au lieu d'afficher 6 lignes de texte j'affiche des boutons ou des listes de choix ... La page met un temps fou à s'afficher (2 a 3s par item !) ... Je pourrais presque les dessiner plus vite avec ma souris ...
J'ai bien vu qu'il y avait une longueur maxi pour les client.println (90 cars) mais en dehors de ça je ne vois pas comment optimiser l'affichage de la page html (testé avec mega 2560, uno r3, IDE 1.05, 1.54 mais sans améliorations)

Quelqu'un a-t-il un serveur wifi avec des pages html "enrichies" qui tourne et qui soit satisfait de la vitesse d'affichage ? Faut-il espérer un jour, une mise à jour qui mette le shield wifi au niveau du shield ethernet ?

(Je ne mets pas le code, c'est celui de l'exemple de la librairie wifi avec un peu plus de code html)

Merci pour votre attention !

Je n’ai pas pratiqué le shield wifi, mais je pense qu’il s’agit du même problème de performance qui existe aussi avec le shield ethernet, sauf qu’en filaire on s’en aperçoit moins.

Pour moi le problème n’est pas hardware mais uniquement logiciel.
C’est toute la « magie » de la programmation objet, lorsqu’elle est mal mise en œuvre.

La méthode client.println(), qui a l’air toute simple comme ça, est en réalité une horreur en terme de traitements déclenchés : chaque caractère est envoyé unitairement dans un paquet protocolé sur le réseau.
Plus lourd y a pas.

Cette méthode est à bannir de tout code digne de ce nom.
A remplacer par un client.write(buf, len).

Et même problème avec le c = client.read() : si tu mets un chrono, tu seras ébahi par le nombre de millisecondes nécessaires à la réception des quelques dizaines de caractères du GET.

De ce point de vue, les codes exemples fournis par Arduino sont une vraie daube.

Bonjour,
J'ai une application avec plusieurs pages Web sur un shield ethernet et c'est assez reactif une fois l'application chargée. (pas testé sur le wifi)
J'utilise comme dit bricoleau client.write pour l'envoi des données de la carte SD par contre mes entêtes sont en client.println ( :roll_eyes:)
Par contre mes pages Web sont sur la carte SD.
Si ca peut t'aider:

                            // Ouverture du fichier sur carte SD
                            if (file.open(&root, Nom_fichier, FILE_READ)) 
                            {
                                  // Construction de l'entête
                                  client.println("HTTP/1.1 200 OK");
                                  if (strstr(Nom_fichier, ".htm") != 0)
                                     client.println("Content-Type: text/html");
                                 else if (strstr(Nom_fichier, ".css") != 0)
                                     client.println("Content-Type: text/css");
                                 else if (strstr(Nom_fichier, ".png") != 0)
                                     client.println("Content-Type: image/png");
                                 else if (strstr(Nom_fichier, ".jpg") != 0)
                                     client.println("Content-Type: image/jpeg");
                                 else if (strstr(Nom_fichier, ".gif") != 0)
                                     client.println("Content-Type: image/gif");
                                 else if (strstr(Nom_fichier, ".3gp") != 0)
                                     client.println("Content-Type: video/mpeg");
                                 else if (strstr(Nom_fichier, ".pdf") != 0)
                                     client.println("Content-Type: application/pdf");
                                 else if (strstr(Nom_fichier, ".js") != 0)
                                     client.println("Content-Type: application/x-javascript");
                                 else if (strstr(Nom_fichier, ".xml") != 0)
                                     client.println("Content-Type: application/xml");
                                 else
                                     client.println("Content-Type: text");
                                     
                                  client.println();
                                 
                                  // Lecture et envoi du fichier de la carte SD
                                  int16_t c;
                                  index = 0;
                                  while (1) 
                                  {
                                      c = file.read();
                                      Buffer_envoi[index]=c;
                                      if ((index>=Taille_buffer_envoi)||(c<0))
                                      { 
                                        if (c<0)
                                        {
                                          client.write(Buffer_envoi,index); 
                                          break;
                                        }
                                        client.write(Buffer_envoi,index+1);
                                        index = -1;                             
                                      }
                    
                                      index ++;
                                  }
                                  
                                  // Fermeture du fichier
                                  file.close();  
                                  break;
                            }

bonjour
j'avais testé ici
http://forum.arduino.cc/index.php/topic,104855.msg788522.html#msg788522
le debit d'un shield ethernet avec des data sur la SD
ça atteint peniblement les 90Ko/s

J'ai oublié de dire que j'étais sur une Due ... mais oui faut pas s'attendre à avoir des debits de fou

J'ai obtenu des gains assez spectaculaires en remplaçant tout simplement les client.println() par des HTTP_println()

où HTTP_println() est une fonction perso qui remplit un buffer char en RAM et l'envoie par client.write() lorsqu'il est plein.
Avec bien sûr l'ajout d'un envoi du buffer partiellement rempli en fin de traitement (flush).

et idem pour la lecture de la commande GET par client.read(buffer, lgmax)

je viens de tester le client.write à la place du client.print ... :fearful: ça dépote un MAX !!!

Je vais aussi essayer sur le shield ethernet mais comme je trouvais qu'il marchait bien, je ne suis pas allé chercher plus loin

Merci pour vos infos ! ...

PS : du point de vue fiabilité de la connexion wifi (on lit que le shield plante au bout d'un certain temps), ça marche bien chez vous ?

Bonjour,

Ce genre de problème de débit est lié à deux choses :

  • le transfert d'octet VS le transfert de blocs d'octets
    --> que tu transfert 1 octet ou 32 octets tu envois la même commande à la shield wifi. Si celle-ci fait 4 octets (par exemple) tu à un rapport de 4:1, ou 4:32 pour 32 octets, c'est le jour et la nuit.

  • la vitesse de communication shield / arduino
    --> avec une carte Arduino classique en SPI tu peut espérer 1Mo (16MHz (freq. cpu) / 2 (prescaler) / 8 bits)
    --> avec une carte Due le port SPI est bien plus véloce, tu peut espérer le triple voir plus.

Reste la limitation de débit physique de la shield et là faut pas s'attendre à des Mo/s. 150Ko/s est déjà un (très) bon débit pour ce genre de shield.

Merci à vous pour vos infos ...

J'ai réussi à afficher ma page html de façon presque aussi fluide qu'avec le shield ethernet et de traiter les requêtes get et/ou post sans trop de plantage.

Pour la taille idéale des chaînes qu'on envoie avec client.write(), c'est au maximum 90 caracteres pour le wifi (j'ai lu ça quelque part sur le forum) mais est-ce la taille idéale ou vaut-il mieux la limiter à 32 ou 64 (une histoire de taille de paquets IP, j'ai aussi lu ça qq part mais je n'y connaît rien !)

B83s:
Pour la taille idéale des chaînes qu'on envoie avec client.write(), c'est au maximum 90 caracteres pour le wifi (j'ai lu ça quelque part sur le forum) mais est-ce la taille idéale ou vaut-il mieux la limiter à 32 ou 64 (une histoire de taille de paquets IP, j'ai aussi lu ça qq part mais je n'y connaît rien !)

C'est surtout lié à la taille du buffer d'envoi au niveau du chipset wifi.
Si tu envois des multiples de la taille du buffer c'est là que tu as le meilleur débit possible.

C'est souvent une puissance de 2 pour simplifier la gestion en hardware du buffer.
La taille classique d'un buffer hardware c'est 32 octets.