accélérer serveur web (html/css/js)

Bonjour,
Je suis sur un petit projet domotique pour ma maison.
Pour l'instant je trouve que la rapidité de mon serveur web est très faible
J'ai crée sur la carte micro SD des fichier html pour un site qui a le design de l'iphone grace à iwebkit
tout fonctionne j'arrive à naviguer entre les pages mais il faut compter plus de 10 seconde pour afficher la page...
peut être que j'en demande trop à mon mega 2560....
si quelqu'un aurais une solution pour accelerer la génération de page ca pourrais être plutôt pas mal

voici mon code

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#include <Wire.h>
 
/************ ETHERNET STUFF ************/
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xFE, 0x7E };
byte ip[] = { 192, 168, 1, 4 };
char rootFileName[] = "index.htm";
EthernetServer server(80);
 
/************ SDCARD STUFF ************/
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))
 
void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}
 
void setup() {
  Serial.begin(9600);
 
  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());  
 
  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  // breadboards.  use SPI_FULL_SPEED for better performance.
  pinMode(10, OUTPUT);                       // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);                    // but turn off the W5100 chip!
 
  if (!card.init(SPI_HALF_SPEED, 4)) error("card.init failed!");
 
  // initialize a FAT volume
  if (!volume.init(&card)) error("vol.init failed!");
 
  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();
 
  if (!root.openRoot(&volume)) error("openRoot failed");
 
  // list file in root with date and size
  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();
 
  // Recursive list of all directories
  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);
 
  Serial.println();
  PgmPrintln("Done");
 
  // Debugging complete, we start the server!
  Ethernet.begin(mac, ip);
  server.begin();
}
 
void ListFiles(EthernetClient client, uint8_t flags) {
  // This code is just copied from SdFile.cpp in the SDFat library
  // and tweaked to print to the client output in html!
  dir_t p;
 
  root.rewind();
  client.println("<ul>");
  while (root.readDir(p) > 0) {
    // done if past last used entry
    if (p.name[0] == DIR_NAME_FREE) break;
 
    // skip deleted entry and entries for . and  ..
    if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') continue;
 
    // only list subdirectories and files
    if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
 
    // print any indent spaces
    client.write("<li><a href=\"");
    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.write('.');
      }
      client.write((char)p.name[i]);
    }
    client.write("\">");
 
    // print file name with possible blank fill
    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.write('.');
      }
      client.write((char)p.name[i]);
    }
 
    client.write("</a>");
 
    if (DIR_IS_SUBDIR(&p)) {
      client.write('/');
    }
 
    // print modify date/time if requested
    if (flags & LS_DATE) {
       root.printFatDate(p.lastWriteDate);
       client.write(' ');
       root.printFatTime(p.lastWriteTime);
    }
    // print size if requested
    if (!DIR_IS_SUBDIR(&p) && (flags & LS_SIZE)) {
      client.write(' ');
      client.write(p.fileSize);
    }
    client.println("</li>");
  }
  client.println("</ul>");
}
 
// How big our line buffer should be. 100 is plenty!
#define BUFSIZ 100
 
void loop()
{
 
  char clientline[BUFSIZ];
  char *filename;
  int index = 0;
  int image = 0;
 
  EthernetClient client = server.available();
    if (client) {
    // an http request ends with a blank line
    boolean current_line_is_blank = true;
 
    // reset the input buffer
    index = 0;
 
      while (client.connected()) {
        if (client.available()) {
          char c = client.read();
 
        // If it isn't a new line, add the character to the buffer
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          // are we too big for the buffer? start tossing out data
          if (index >= BUFSIZ)
            index = BUFSIZ -1;
 
          // continue to read more data!
          continue;
        }
 
         // got a \n or \r new line, which means the string is done
        clientline[index] = 0;
 
        // Print it out for debugging
        Serial.println(clientline);
 
        // Look for substring such as a request to get the root file
        if (strstr(clientline, "GET / ") != 0) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
 
          // print all the files, use a helper to keep it clean
          client.println("<h2>Files:</h2>");
          ListFiles(client, LS_SIZE);
        } else if (strstr(clientline, "GET /") != 0) {
          // this time no space after the /, so a sub-file!
 
 
          filename = clientline + 5; // look after the "GET /" (5 chars)
          // a little trick, look for the " HTTP/1.1" string and
          // turn the first character of the substring into a 0 to clear it out.
          (strstr(clientline, " HTTP"))[0] = 0;
 
          // print the file we want
          Serial.println(filename);
 
          if (! file.open(&root, filename, O_READ)) {
            client.println("HTTP/1.1 404 Not Found");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<h2>File Not Found!</h2>");
            break;
          }
 
          Serial.println("Opened!");
 
          client.println("HTTP/1.1 200 OK");
          if (strstr(filename, ".htm") != 0)
             client.println("Content-Type: text/html");
         else if (strstr(filename, ".css") != 0)
             client.println("Content-Type: text/css");
         else if (strstr(filename, ".png") != 0)
             client.println("Content-Type: image/png");
          else if (strstr(filename, ".jpg") != 0)
             client.println("Content-Type: image/jpeg");
        else if (strstr(filename, ".gif") != 0)
             client.println("Content-Type: image/gif");
         else if (strstr(filename, ".3gp") != 0)
             client.println("Content-Type: video/mpeg");
         else if (strstr(filename, ".pdf") != 0)
             client.println("Content-Type: application/pdf");*/
         else if (strstr(filename, ".js") != 0)
             client.println("Content-Type: application/x-javascript");
         else if (strstr(filename, ".xml") != 0)
             client.println("Content-Type: application/xml");
         else
             client.println("Content-Type: text");
 
          client.println();
 
          int16_t c;
          while ((c = file.read()) >= 0) {
              // uncomment the serial to debug (slow!)
              //Serial.print((char)c);
              client.write((char)c);
          }
          file.close();
        } else {
          // everything else is a 404
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<h2>File Not Found!</h2>");
           }
        break;
      }
    }
    // give the web browser time to receive the data
    delay(1);
    client.stop();
  }
}

Merci

Bonjour

Et si je te proposais de passer de 10s à 0,5s, ça te dirait?

Les capacités de la mega ne sont pas en cause.

Ton problème, c'est l'utilisation de la méthode print.
Y a rien de mieux que d'utiliser des méthodes génériques sans se poser de question, pour obtenir sans s'en rendre compte de bonnes grosses usines à gaz.

Je m'explique : là, ton serveur envoie la page web octet par octet.
C'est-à-dire que chaque octet est transmis unitairement dans un paquet protocolé sous ip.
Une véritable orgie de signaux à faire dresser les cheveux sur la tête de n'importe quel routeur.

L'idée est de remplacer les client.print et les client.write par le remplissage d'un buffer en mémoire, envoyé en un seul coup lorsqu'il est plein, par un client.write(buffer, longueur)

Un truc du genre :

  1. déclare ton "EthernetClient client;"en variable globale
  2. remplace tous les client.print et les client.write par client_print, les client.println par client_println, le client.stop par client_stop

avec (pas vérifié, mais c'est l'idée)

char buffer[200];//voire plus
uint16_t longueur = 0;

void client_send() {
  if (longueur != 0) client.write(buffer, longueur);
  longueur = 0;
}

void client_print(char c) {
  if (longueur == sizeof(buffer)) client_send();
  buffer[longueur++] = c;
}

void client_print(char *c) {
  while (*c) client_print(*c++);
}

void client_retchar() {
  client_print((char)0x0a);
}

void client_println(char c) {
  client_print(c);
  client_retchar();
}

void client_println(char *c) {
  client_print(c);
  client_retchar();
}

void client_stop() {
  client_send();
  client.stop();
}

Merci pour le coup de main mais j'ai essayé de le mettre en oeuvre et je n'ai pas réussi... :confused:
j'ai compris l'idée du programme mais étant encore assez novice je ne pourrais pas aller plus loin

En revanche pour les suivants j'ai trouvé ceci que j'ai du modifier pour fonctionner avec l'IDE d'aujourd'hui.
Le temps à été largement réduit.
C'est sur que j'aimerais plus rapide mais pour le moment j'en suis conten

//This version includes a readout buffer that reads a specific amount of data from the SD card before it writes it to the wiznet chip.  This increases transfer
//speed considerably, up to 6x download speed.
#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>
#include <Wire.h>

uint8_t bufindex;  //Buffer index, used to keep track of current buffer byte
const uint8_t maxbyte=255;  //The maximum allowable buffer length
uint8_t buf[maxbyte];  //Creates the buffer with a length equal to the max length

byte mac[] = {0x90,0xA2,0xDA,0x00,0x26,0xEB};
byte ip[] = {
  192,168,1,4};
char rootFileName[] = "index.htm";
EthernetServer server(80);

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

#define error(s) error_P(PSTR(s))
void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

void setup() {
  Serial.begin(256000);
  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  if (!card.init(SPI_FULL_SPEED, 4)) error("card.init failed!");
  if (!volume.init(&card)) error("vol.init failed!");
  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();
  if (!root.openRoot(&volume)) error("openRoot failed");
  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();
  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);
  Serial.println();
  PgmPrintln("Done");
  Ethernet.begin(mac, ip);
  server.begin();
}
#define BUFSIZ 100

void loop()
{
  char clientline[BUFSIZ];
  char *filename;
  int index = 0;
  int image = 0;
EthernetClient  client = server.available();
  if (client) {
    boolean current_line_is_blank = true;
    index = 0;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          if (index >= BUFSIZ)
            index = BUFSIZ -1;
          continue;
        }
        clientline[index] = 0;
        filename = 0;
        Serial.println(clientline);
        if (strstr(clientline, "GET / ") != 0) {
          filename = rootFileName;
        }
        if (strstr(clientline, "GET /") != 0) {
          if (!filename) filename = clientline + 5;
          (strstr(clientline, " HTTP"))[0] = 0;
          Serial.println(filename);
          if (! file.open(&root, filename, O_READ)) {
            client.println("HTTP/1.1 404 Not Found");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<h2>File Not Found!</h2>");
            break;
          }
          Serial.println("Opened!");
          client.println("HTTP/1.1 200 OK");
          if (strstr(filename, ".htm") != 0)
            client.println("Content-Type: text/html");
          else if (strstr(filename, ".css") != 0)
            client.println("Content-Type: text/css");
          else if (strstr(filename, ".png") != 0)
            client.println("Content-Type: image/png");
          else if (strstr(filename, ".jpg") != 0)
            client.println("Content-Type: image/jpeg");
          else if (strstr(filename, ".gif") != 0)
            client.println("Content-Type: image/gif");
          else if (strstr(filename, ".3gp") != 0)
            client.println("Content-Type: video/mpeg");
          else if (strstr(filename, ".pdf") != 0)
            client.println("Content-Type: application/pdf");
          else if (strstr(filename, ".js") != 0)
            client.println("Content-Type: application/x-javascript");
          else if (strstr(filename, ".xml") != 0)
            client.println("Content-Type: application/xml");
          else
            client.println("Content-Type: text");
          client.println();
          int16_t c;
          bufindex=0;  //reset buffer index
          while ((c = file.read()) >= 0) {
            buf[bufindex++]=((char)c);  //fill buffer
            if(bufindex==maxbyte)  //empty buffer when maximum length is reached.
            {
              client.write(buf, maxbyte);
              bufindex=0;
            }
          }
          file.close();  //close the file
          if(bufindex>0)  //most likely, the size of the file will not be an even multiple of the buffer length, so any remaining data is read out.
          {
            client.write(buf, bufindex);
          }
          bufindex=0; //reset buffer index (reset twice for redundancy
        } 
        else {
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<h2>File Not Found!</h2>");
        }
        break;
      }
    }
    delay(1);
    client.stop();
  }
}

bonjour,
la lenteur peut aussi intervenir lors d'une mauvaise liaison rj45.

as tu fais un ping de ton server pour vérifier?
ping 192.168.1.4

Bonjour
Non je n'ai pas fait de test ping
d'ailleurs je ne sais pas comment le faire entre ma box et mon arduino

mais je ne pense pas que ce soit cela
avec le nouveau code c'est deja pas mal

merci

je vais quand même me renseigner pour le ping

ouvrir une console windows via cmd
taper
ping 192.168.1.4

Jz84100:
Merci pour le coup de main mais j'ai essayé de le mettre en oeuvre et je n'ai pas réussi... :confused:

Ton dernier code réalise bien un envoi par paquets, avec un résultat probablement proche des petites modifs que je t'avais indiquées.
Mais il faudrait aussi appliquer la même logique vis à vis de la carte SD : lire par paquets d'octets au lieu de lire octet par octet.

Quel résultat avec le code ci-dessous ?

//This version includes a readout buffer that reads a specific amount of data from the SD card before it writes it to the wiznet chip.  This increases transfer
//speed considerably, up to 6x download speed.
#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>
#include <Wire.h>

uint8_t bufindex;  //Buffer index, used to keep track of current buffer byte
const uint8_t maxbyte=255;  //The maximum allowable buffer length
uint8_t buf[maxbyte];  //Creates the buffer with a length equal to the max length

byte mac[] = {0x90,0xA2,0xDA,0x00,0x26,0xEB};
byte ip[] = {
  192,168,1,4};
char rootFileName[] = "index.htm";
EthernetServer server(80);

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

#define error(s) error_P(PSTR(s))
void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

void setup() {
  Serial.begin(256000);
  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  if (!card.init(SPI_FULL_SPEED, 4)) error("card.init failed!");
  if (!volume.init(&card)) error("vol.init failed!");
  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();
  if (!root.openRoot(&volume)) error("openRoot failed");
  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();
  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);
  Serial.println();
  PgmPrintln("Done");
  Ethernet.begin(mac, ip);
  server.begin();
}
#define BUFSIZ 100

EthernetClient  client;
char buffer[500];//voire plus
uint16_t longueur = 0;

void loop()
{
  char clientline[BUFSIZ];
  char *filename;
  int index = 0;
  int image = 0;
  client = server.available();
  if (client) {
    boolean current_line_is_blank = true;
    index = 0;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          if (index >= BUFSIZ)
            index = BUFSIZ -1;
          continue;
        }
        clientline[index] = 0;
        filename = 0;
        Serial.println(clientline);
        if (strstr(clientline, "GET / ") != 0) {
          filename = rootFileName;
        }
        if (strstr(clientline, "GET /") != 0) {
          if (!filename) filename = clientline + 5;
          (strstr(clientline, " HTTP"))[0] = 0;
          Serial.println(filename);
          if (! file.open(&root, filename, O_READ)) {
            client_println("HTTP/1.1 404 Not Found");
            client_println("Content-Type: text/html");
            client_println();
            client_println("<h2>File Not Found!</h2>");
            break;
          }
          Serial.println("Opened!");
          client_println("HTTP/1.1 200 OK");
          if (strstr(filename, ".htm") != 0)
            client_println("Content-Type: text/html");
          else if (strstr(filename, ".css") != 0)
            client_println("Content-Type: text/css");
          else if (strstr(filename, ".png") != 0)
            client_println("Content-Type: image/png");
          else if (strstr(filename, ".jpg") != 0)
            client_println("Content-Type: image/jpeg");
          else if (strstr(filename, ".gif") != 0)
            client_println("Content-Type: image/gif");
          else if (strstr(filename, ".3gp") != 0)
            client_println("Content-Type: video/mpeg");
          else if (strstr(filename, ".pdf") != 0)
            client_println("Content-Type: application/pdf");
          else if (strstr(filename, ".js") != 0)
            client_println("Content-Type: application/x-javascript");
          else if (strstr(filename, ".xml") != 0)
            client_println("Content-Type: application/xml");
          else
            client_println("Content-Type: text");
          client_println();
          uint16_t c= file.read(buf, maxbyte);
          client_write(buf, c);
/*          int16_t c;
          bufindex=0;  //reset buffer index
          while ((c = file.read()) >= 0) {
            buf[bufindex++]=((char)c);  //fill buffer
            if(bufindex==maxbyte)  //empty buffer when maximum length is reached.
            {
              client_write(buf, maxbyte);
              bufindex=0;
            }
          }*/
          file.close();  //close the file
/*          if(bufindex>0)  //most likely, the size of the file will not be an even multiple of the buffer length, so any remaining data is read out.
          {
            client_write(buf, bufindex);
          }
          bufindex=0; //reset buffer index (reset twice for redundancy*/
        } 
        else {
          client_println("HTTP/1.1 404 Not Found");
          client_println("Content-Type: text/html");
          client_println();
          client_println("<h2>File Not Found!</h2>");
        }
        break;
      }
    }
    delay(1);
    client_stop();
  }
}

void client_send() {
  if (longueur != 0) client.write(buffer, longueur);
  longueur = 0;
}

void client_print(char c) {
  if (longueur == sizeof(buffer)) client_send();
  buffer[longueur++] = c;
}

void client_print(char *c) {
  while (*c) client_print(*c++);
}

void client_write(uint8_t buf[], uint16_t lg) {
  for (uint16_t i=0; i<lg; i++) client_print((char)buf[i]);
}

void client_println() {
  client_print((char)0x0a);
}

void client_println(char c) {
  client_print(c);
  client_println();
}

void client_println(char *c) {
  client_print(c);
  client_println();
}

void client_stop() {
  client_send();
  delay(1);
  client.stop();
}

pour ce qui est du ping la commande a marché sous mac mais je ne sais pas interpréter...

Par contre merci bricoleau mais j'ai essayé et ça ne charge qu' une page blanche...

Jz84100:
pour ce qui est du ping la commande a marché sous mac mais je ne sais pas interpréter...

Par contre merci bricoleau mais j'ai essayé et ça ne charge qu' une page blanche...

si tu mettais le résultat du ping, ca pourrait donner une idée de la connexion :wink:

voila ce que j'ai.
je n'ai selectionné qu'un bout
je pense que le ping est testé jusqu'a ce que l'on ferme l'invite de commande.

64 bytes from 192.168.1.4: icmp_seq=0 ttl=128 time=5.379 ms
64 bytes from 192.168.1.4: icmp_seq=1 ttl=128 time=1.742 ms
64 bytes from 192.168.1.4: icmp_seq=2 ttl=128 time=3.008 ms
64 bytes from 192.168.1.4: icmp_seq=3 ttl=128 time=2.993 ms
64 bytes from 192.168.1.4: icmp_seq=4 ttl=128 time=2.760 ms
64 bytes from 192.168.1.4: icmp_seq=5 ttl=128 time=2.040 ms
64 bytes from 192.168.1.4: icmp_seq=6 ttl=128 time=2.833 ms
64 bytes from 192.168.1.4: icmp_seq=7 ttl=128 time=2.983 ms
64 bytes from 192.168.1.4: icmp_seq=8 ttl=128 time=1.999 ms
64 bytes from 192.168.1.4: icmp_seq=9 ttl=128 time=1.772 ms
64 bytes from 192.168.1.4: icmp_seq=10 ttl=128 time=1.566 ms
64 bytes from 192.168.1.4: icmp_seq=11 ttl=128 time=1.411 ms
64 bytes from 192.168.1.4: icmp_seq=12 ttl=128 time=1.301 ms
64 bytes from 192.168.1.4: icmp_seq=13 ttl=128 time=1.182 ms
64 bytes from 192.168.1.4: icmp_seq=14 ttl=128 time=2.069 ms
64 bytes from 192.168.1.4: icmp_seq=15 ttl=128 time=1.851 ms
64 bytes from 192.168.1.4: icmp_seq=16 ttl=128 time=2.920 ms
64 bytes from 192.168.1.4: icmp_seq=17 ttl=128 time=1.847 ms
64 bytes from 192.168.1.4: icmp_seq=18 ttl=128 time=1.066 ms
64 bytes from 192.168.1.4: icmp_seq=19 ttl=128 time=1.657 ms
64 bytes from 192.168.1.4: icmp_seq=20 ttl=128 time=1.209 ms
64 bytes from 192.168.1.4: icmp_seq=21 ttl=128 time=1.306 ms
64 bytes from 192.168.1.4: icmp_seq=22 ttl=128 time=1.160 ms
64 bytes from 192.168.1.4: icmp_seq=23 ttl=128 time=1.684 ms
64 bytes from 192.168.1.4: icmp_seq=24 ttl=128 time=1.584 ms
64 bytes from 192.168.1.4: icmp_seq=25 ttl=128 time=5.201 ms

c'est pas tellement stable comme connexion, de gros écarts quand même.
si je ping un de mes servers en passant par un router et une passerelle ca donne ca

PING 192.168.1.18 (192.168.1.18) 56(84) bytes of data.
64 bytes from 192.168.1.18: icmp_seq=1 ttl=63 time=4.21 ms
64 bytes from 192.168.1.18: icmp_seq=2 ttl=63 time=2.42 ms
64 bytes from 192.168.1.18: icmp_seq=3 ttl=63 time=2.41 ms
64 bytes from 192.168.1.18: icmp_seq=4 ttl=63 time=2.38 ms
64 bytes from 192.168.1.18: icmp_seq=5 ttl=63 time=2.45 ms
64 bytes from 192.168.1.18: icmp_seq=6 ttl=63 time=2.37 ms
64 bytes from 192.168.1.18: icmp_seq=7 ttl=63 time=2.38 ms
64 bytes from 192.168.1.18: icmp_seq=8 ttl=63 time=2.36 ms
64 bytes from 192.168.1.18: icmp_seq=9 ttl=63 time=2.38 ms
64 bytes from 192.168.1.18: icmp_seq=10 ttl=63 time=2.41 ms
64 bytes from 192.168.1.18: icmp_seq=11 ttl=63 time=2.45 ms

Oui on voit que c'est plus stable mais est ce vraiment significatif finalement?

disons que oui, en plus d'un codage non optimisé.

Une idée pour résoudre ce problème de stabilité???
La solution de la carte SD aurait été bien aussi....

Merci :slight_smile: pour cette astuce, je viens de l'appliquer:

Exemple avec un fichier .csv de 60Ko,

  • avec le code non optimisé: 20 secondes,
  • avec le code optimisé: 4 secondes,

code non optimisé:

///////////////////////////////////////////////////////////////////
// Lecture fichier CSV à travers la page web
///////////////////////////////////////////////////////////////////
void HtmlReadCSV(EthernetClient client)
{
  File dataFile = SD.open(GETFILECSV, FILE_READ);

  if (dataFile) {
    while (dataFile.available()) {
      char c = dataFile.read();

      if (c == '\n')
      {
        client.println("
");
      }
      else
      {
        client.write(c);
      }

    }
    dataFile.close();
  }
  else {
    client.print("error opening");
    client.print(GETFILECSV);
  }
  GETFILECSV = "-.csv";
}

code optimisé:

///////////////////////////////////////////////////////////////////
// Lecture fichier CSV à travers la page web
///////////////////////////////////////////////////////////////////
void HtmlReadCSV2(EthernetClient client)
{
  int bufindex;  
  int maxbyte = 255; 
  char buf[maxbyte];  
  File dataFile = SD.open(GETFILECSV, FILE_READ);

  if (dataFile) {
    bufindex = 0; //reset buffer index
    while (dataFile.available()) {
      char c = dataFile.read();

      if (c == '\n')
      {
        buf[bufindex++] = '<';buf[bufindex++] = 'b';buf[bufindex++] = 'r';buf[bufindex++] = '/';    buf[bufindex++] = '>';
      }
      else
      {
        buf[bufindex++] = c;
      }
      if (bufindex >= (maxbyte - 6)) 
      {
        client.write(buf, bufindex);
        bufindex = 0;
      }
    }
    dataFile.close();
    if (bufindex > 0)
    {
      client.write(buf, bufindex);
    }
    bufindex = 0;
  }
  else {
    client.print("error opening");
    client.print(GETFILECSV);
  }
  GETFILECSV = "-.csv";
}

Je suis content que ça te serves!
on remarque nettement la difference!

Bonjour

J'aime pas rester sur un échec ???

Alors j'ai repris le code que je t'avais indiqué précédemment, j'ai ajouté les deux modifs qui permettent de le faire fonctionner, et je l'ai testé sur une simple arduino ethernet.

Résultat : image jpg de 100ko stockée sur la carte SD de l'arduino, affichée en moins de deux secondes sur le navigateur de mon PC (liaison tout en filaire, pas de wifi).

Voici le code correct

#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[] = {192,168,1,4};
char rootFileName[] = "index.htm";
EthernetServer server(80);

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

#define error(s) error_P(PSTR(s))
void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

void setup() {
  Serial.begin(9600);
  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  if (!card.init(SPI_FULL_SPEED, 4)) error("card.init failed!");
  if (!volume.init(&card)) error("vol.init failed!");
  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();
  if (!root.openRoot(&volume)) error("openRoot failed");
  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();
  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);
  Serial.println();
  PgmPrintln("Done");
  Ethernet.begin(mac, ip);
  server.begin();
}
#define BUFSIZ 100

EthernetClient  client;
char buffer[350];//voire plus
uint16_t longueur = 0;

char clientline[BUFSIZ];
void loop()
{
  char *filename;
  int index = 0;
  int image = 0;
  client = server.available();
  if (client) {
    boolean current_line_is_blank = true;
    index = 0;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          if (index >= BUFSIZ)
            index = BUFSIZ -1;
          continue;
        }
        clientline[index] = 0;
        filename = 0;
        Serial.println(clientline);
        if (strstr(clientline, "GET / ") != 0) {
          filename = rootFileName;
        }
        if (strstr(clientline, "GET /") != 0) {
          if (!filename) filename = clientline + 5;
          (strstr(clientline, " HTTP"))[0] = 0;
          Serial.println(filename);
          if (! file.open(&root, filename, O_READ)) {
            client_println("HTTP/1.1 404 Not Found");
            client_println("Content-Type: text/html");
            client_println();
            client_println("<h2>File Not Found!</h2>");
            break;
          }
          Serial.println("Opened!");
          client_println("HTTP/1.1 200 OK");
          client_print("Content-Type: ");
          if (strstr(filename, ".htm") != 0)
            client_println("text/html");
          else if (strstr(filename, ".css") != 0)
            client_println("text/css");
          else if (strstr(filename, ".png") != 0)
            client_println("image/png");
          else if (strstr(filename, ".jpg") != 0)
            client_println("image/jpeg");
          else if (strstr(filename, ".gif") != 0)
            client_println("image/gif");
          else if (strstr(filename, ".3gp") != 0)
            client_println("video/mpeg");
          else if (strstr(filename, ".pdf") != 0)
            client_println("application/pdf");
          else if (strstr(filename, ".js") != 0)
            client_println("application/x-javascript");
          else if (strstr(filename, ".xml") != 0)
            client_println("application/xml");
          else
            client_println("text");
          client_println();          
          client_send();

          longueur = file.read(buffer, sizeof(buffer));
          while (longueur != 0)
          {
            client_send();
            longueur = file.read(buffer, sizeof(buffer));
          }
          file.close();  //close the file
        }
        else {
          client_println("HTTP/1.1 404 Not Found");
          client_println("Content-Type: text/html");
          client_println();
          client_println("<h2>File Not Found!</h2>");
        }
        break;
      }
    }
    delay(1);
    client.flush();
    client.stop();
  }
}

void client_send() {
  if (longueur != 0) client.write(buffer, longueur);
  longueur = 0;
}

void client_print(char c) {
  buffer[longueur++] = c;
  if (longueur == sizeof(buffer)) client_send();
}

void client_print(char *c) {
  while (*c) client_print(*c++);
}

void client_println() {
  client_print((char)0x0a);
}

void client_println(char c) {
  client_print(c);
  client_println();
}

void client_println(char *c) {
  client_print(c);
  client_println();
}

Merci c'est génial
Je testerais demain mais si tu dit que ça fonctionne !
C'est top
Par contre je n'y comprends rien....

Ce serveur est top il peut servir de base à tout serveur web sur arduino!
Maintenant j'essaye de faire fonctionner des boutons pour contrôler la led souder sur l'arduino dans un premier temps, mais sans succès...

ouah c'est une fusée c'est top mais j'ai l'impression que une fois sur deux c'est trop rapide et l'arduino ne génère pas la page html il se content de l'envoyé c'est tout
on se retrouve donc souvent dans le navigateur à avoir que le code html....

Bonjour

Je ne comprends pas trop ton dernier propos, car les termes utilisés ne sont probablement pas les bons.
Il n'y a pas vraiment de différence entre "générer" une page html et "envoyer" une page html.

Je suppose que tu parles d'un fichier .htm présent sur la carte SD, que l'arduino lit et envoie au client.
Le HTML, c'est un flux texte avec des balises.
Le navigateur traduit ces balises pour afficher la page correctement.
Tu peux lui demander d'afficher le code source de la page, pour visualiser exactement le flux texte reçu de l'arduino. C'est très utile pour mettre au point ton serveur.

Si ce flux est incorrect / tronqué, il va manquer des infos au navigateur pour l'interpréter.
C'est probablement dans ce cas que tu "vois" le html.

Cela peut provenir soit d'un problème de communication entre l'arduino et ton navigateur, soit d'un bug au niveau du code arduino, dans la mécanique de lecture SD / envoi au client.
Là comme ça je ne vois pas trop. Faudrait déjà identifier quel est le bout qui manque.
De mon côté je n'ai pas constaté ce type d'anomalie, mais je n'ai pas fait de test sur un fichier .htm

Dans tous les cas, tu vas avoir du mal à aller significativement plus loin avec un code aussi mal fagoté.
Je serais toi, je remettrais tout ça au propre, avec une structuration des traitements en fonctions.
Cela te permettra aussi de comprendre son fonctionnement, et donc de le maîtriser / modifier.

Commence par faire simple : un serveur web qui renvoie une bête page HTML, jusqu'à comprendre la moindre ligne de code.
Des Serial.print insérés temporairement un peu partout te permettront d'appréhender le fonctionnement.

Idem pour les boutons, car vouloir les ajouter directement sur ce code, sans maîtrise de la programmation, ça va être une galère sans nom qui a peu de chances d'arriver à bon port.