Afficher du CSS et des images sur une page sur un Shield Ethernet

Bonjour a tous, :slight_smile:

Je débute dans la programmation arduino et dans le cadre d’un projet STI2D SIN pour le BAC, je suis chargé d’afficher des consommations electriques sur un site . Mon Site web est hébergé sur la carte SD du shield ethernet car il prend beaucoup de place.

J’ai déja réussi à faire afficher la page index :

//Bibliothèques indispensables pour :
#include <SPI.h>          //la communication Arduino/Shield
#include <Ethernet.h>     //la communication ethernet
#include <SD.h>           //Utiliser la carte SD



byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x9C, 0x53}; //Adresse mac du shield


IPAddress ip(192, 168, 0, 120);                    //Adresse ip du shield, à modifier selon le réseau)


EthernetServer serveur(80);                        //déclare l'objet serveur (HTTP) au port 80

File webFile;//déclare l'objet webfile (pour ouvrir une page web)


void setup()
{
    Ethernet.begin(mac, ip);                       // Initialisation du shield Ethernet
    serveur.begin();                               // Le serveur est a l'ecoute de clients
    Serial.begin(9600);                            // initialise la communication série (pour débugger)
    Serial.println("Initialisation du serveur");
    
    // Initialisation de la carte SD
    Serial.println("Initialisation de la carte SD...");
    if (!SD.begin(4)) {                                        // Si il n'y a pas de carte SD sur le pin4:
        Serial.println("ERREUR - Carte SD non détectée!");     //Pas de carte SD = message d'erreur puis retour 
        return;    
    }
    Serial.println("OK - Carte SD initialisee.");              //Carte SD = message positif
    
    if (!SD.exists("index.htm")) {                             //Si il n'y a pas de fichier index.htm:
     
        Serial.println("ERREUR - htm.htm introuvable!");       // pas de fichier index.htm = message d'erreur puis retour 
        return;  
    }
    Serial.println("OK - index.htm récupéré.");
}

void loop()
{
 
  EthernetClient client = serveur.available();
  //le serveur ecoute le port
  if (client) {                                                //si quelqu'un se connecte
    Serial.println("Client en ligne");
  
   
  
    boolean currentLineIsBlank = true;
    while (client.connected()) {                               //tant que le client est connecté
            if (client.available()) {                          //si le client est disponible
               
            
    client.println("HTTP/1.1 200 OK");                         //Annonce au client que le serveur est un serveur HTTP
   client.println("Content-Type: text/html");                  //informe le navigateur du type de document à afficher
    
     client.println();
    webFile = SD.open("index.htm");                            //ouvre la page web 
    
    if (webFile){
      while(webFile.available()) {                             //Si la page est disponible
        client.write(webFile.read());                          //envoie la page au client
        //envoie la page au client
        delay(1);
      }
      webFile.close();
      }
      break;
   
            }
    }
    client.stop();                                              //On déconnecte le client
   
    Serial.println("Deconnexion du client");
  }
}

Le problème c’est que le CSS ne s’affiche pas, ni les images et liens (qui sont contenues dans la carte SD).

Je sais que la page web envoie une “demande” au serveur arduino mais je ne sais pas comment indiquer à la page d’aller chercher ces fichiers (CSS,images,autres pages html)…

Merci d’avance pour votre aide !

Up, je cherche depuis tout à l'heure...

Et en 2 heures tu n'as rien trouvé ???

  1. Éteins la télé, la console, le téléphone, facebook, twitter, ...
  2. Allume le cerveau (la veille prolongée c'est dangeureux)

Et pour bien démarrer, un petit coup de main quand même:
http://lmgtfy.com/?q=arduino+web+server

2ème choix proposé, tu n'as plus qu'à lire et implémenter.

PS: qu'appelles tu chercher ? poster sur différents forums et attendre que les autres fassent le boulot à ta place ?

Bigben99, au lieu d’essayer de faire le malin, si tu avais pris le temps de regarder mon programme, tu aurais vu qu’une grosse partie venait de ce meme site.

Enfin bref.

Après plusieurs recherches,j’ai modifié mon programme :

void loop()
{
    EthernetClient client = server.available();  // try to get client

    if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read(); // read 1 byte (character) from client
                // buffer first part of HTTP request in HTTP_req array (string)
                // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
                if (req_index < (REQ_BUF_SZ - 1)) {
                    HTTP_req[req_index] = c;          // save HTTP request character
                    req_index++;
                }
                // print HTTP request character to serial monitor
                Serial.print(c);
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                if (c == '\n' && currentLineIsBlank) {
                    // open requested web page file
                    if (StrContains(HTTP_req, "GET / ")
                                 || StrContains(HTTP_req, "GET /index.htm")) {
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/html");
                        client.println("Connnection: close");
                        client.println();
                        webFile = SD.open("index.htm");        // open web page file
                    }
                    else if (StrContains(HTTP_req, "GET /maconso.css")) {
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/css");
                        client.println("Connnection: close");
                        client.println();
                        webFile = SD.open("maconso.css");        // open web page file
                    }
                    else if (StrContains(HTTP_req, "GET /bkhome.png")) {
                        webFile = SD.open("bkhome.png");
                        if (webFile) {
                            client.println("HTTP/1.1 200 OK");
                            client.println();
                        }
                        else if (StrContains(HTTP_req, "GET /autre.txt")) {
                        webFile = SD.open("autre.txt");
                        if (webFile) {
                            client.println("HTTP/1.1 200 OK");
                            client.println();
                        }
                         }
                         else if (StrContains(HTTP_req, "GET /chauf.txt")) {
                        webFile = SD.open("chauf.txt");
                        if (webFile) {
                            client.println("HTTP/1.1 200 OK");
                            client.println();
                        }
                         }
                         else if (StrContains(HTTP_req, "GET /eau.txt")) {
                        webFile = SD.open("eau.txt");
                        if (webFile) {
                            client.println("HTTP/1.1 200 OK");
                            client.println();
                        }
                         }
                         else if (StrContains(HTTP_req, "GET /eclai.txt")) {
                        webFile = SD.open("eclai.txt");
                        if (webFile) {
                            client.println("HTTP/1.1 200 OK");
                            client.println();
                        }
                         }
                         else if (StrContains(HTTP_req, "GET /logo.png")) {
                        webFile = SD.open("logo.png");
                        if (webFile) {
                            client.println("HTTP/1.1 200 OK");
                            client.println();
                        }
                         }
                        
                       
                         else if (StrContains(HTTP_req, "GET /favicon.png")) {
                        webFile = SD.open("favicon.png");
                        if (webFile) {
                            client.println("HTTP/1.1 200 OK");
                            client.println();
                        }
                         }
                         
                    }
                    if (webFile) {
                        while(webFile.available()) {
                            client.write(webFile.read()); // send web page to client
                        }
                        webFile.close();
                    }
                    // reset buffer index and all buffer elements to 0
                    req_index = 0;
                    StrClear(HTTP_req, REQ_BUF_SZ);
                    break;
                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
    } // end if (client)
}

// sets every element of str to 0 (clears array)
void StrClear(char *str, char length)
{
    for (int i = 0; i < length; i++) {
        str[i] = 0;
    }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
    char found = 0;
    char index = 0;
    char len;

    len = strlen(str);
    
    if (strlen(sfind) > len) {
        return 0;
    }
    while (index < len) {
        if (str[index] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index++;
    }

    return 0;
}

(J’ai seulement mis le voidloop)
Il fonctionne si je comble seulement 4,5 requetes d’images/css, cependant à partir d’un certain nombre de requetes que je “comble” avec le GET(envoie d’images,css…)

l’arduino ne veut plus rien envoyer, il semble saturé.

Je me demande donc si l’affichage du page web avec beaucoup d’images et de css est réellement possible à afficher avec un arduino et un shield ethernet ?

J’avais testé avec un Uno et demain je test avec un Mega mais je ne pense pas que cela change .

Au lieu de tester chaque nom possible de fichier, extrait le nom de la requête et ouvre le fichier correspondant

cbrandt , je ne comprend pas vraiment ta réponse, comment je pourrais faire pour extraire le nom de la requete ?

Parce que là ma logique c'est d'essayer de combler toutes les requetes que le navigateur pourrait demander lorsqu'il consulte les pages .

Ta logique est valable si tu as deux ou trois fichiers, mais pas plus. Et si tu veux ajouter une page web ou une image, tu dois recoder ton programme et le télécharger à nouveau dans l'arduino, c'est bien trop fastidieux.

La bonne logique est d'analyser la requête et de renvoyer le fichier demandé:
Normalement ta requête contient quelque chose comme "GET /index.htm HTTP/1.1"
Tu dois donc arriver à isoler ce qu'il y a après "GET /" et avant " HTTP/1.1", pour le mettre dans une variable et ensuite passer cette variable à SD.open ().
Par ailleurs, tu dois aussi renvoyer le type mime selon l'extension, la par contre je pense que tu devras tester les différents cas ("htm" -> text/html, "css" -> "text/css", "txt" -> "text/plain", "png" -> "image/png" etc).

Tous les détails sur les fonctions pour manipuler les chaînes de caractères sont ici: avr-libc: AVR Libc, plus spécialement dans cette page: http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html.
Sinon sache simplement qu'une chaîne de caractères est juste un tableau de caractères - donc pour extraire le nom du fichier, il faut examiner la chaîne caractère par caractère à partir du début, jusqu'à rencontrer le caractère "/", ensuite il faut garder les caracères suivants jusqu'au " ". Et voilà, tu as trouvé le nom du fichier !

Et tous les détails pour savoir comment est structurée la requête HTTP que tu dois analyser sont là: rfc7230

kameboii:
Bigben99, au lieu d'essayer de faire le malin, si tu avais pris le temps de regarder mon programme, tu aurais vu qu'une grosse partie venait de ce meme site.

Enfin bref.

Tu me prends vraiment pour un c.. ? Dans le premier code que tu as donné, tu t'es arrêté à la page 4 et donc ton code ne renvoyait qu'une page unique. C'est sur qu'en lisant jusqu'au bout les tuto, ça aide.