Partage
  • Partager sur Facebook
  • Partager sur Twitter

Arduino & Ethernet

    9 septembre 2019 à 19:19:30

    Bonjour à tous,

    Je viens vous sonder un peu, je suis actuellement sur le cours pour lancer un serveur via le shield Arduino et piloter des LED via une page web.

    Seulement, ma connexion semble se faire une fois sur cinquante... ce qui est d'une part très pénible, et fait que le peu de temps que j'arrive à prendre pour bidouiller l'arduino se résume en ce moment à appuyer sur le bouton reset en attendant que la connexion se fasse.

    Je me dit de plus que c'est pour mes tests, mais impensable alors de faire un projet concret en Ethernet si la connexion ne marque presque jamais, et de façon aléatoire (en apparence du moins.

    Je vous glisse mon code au cas ou, mais je suppose qu'il fonctionne vu que parfois, ça passe :

    C'est surtout l'étape de connexion qui m'interesse, et une fois lancé, le moniteur affiche donc généralement : Le serveur est sur l'adresse : 0.0.0.0

    EDIT :

    Dans le fonctionnement général, je modifie encore mon programme, donc c'est normal que vous puissiez voir des incohérences dans la gestion des LED ou autre par exemple.

    #include <SPI.h>
    #include <Ethernet.h>
    
    byte mac[] = {0x90, 0xA2, 0xDA, 0x0F, 0xDF, 0xAB};
    IPAddress ip(192, 168, 1, 123);
    EthernetServer serveur(80);         //déclare l'objet serveur sur le port 80
    
    int pinLED[5] = {9,8,7,6,5};        //pin des LED
    int tabEtatLED[5] = {0,0,0,0,0};
    String etats[3] = {"ON", "OFF", "CLI"};
    long tempsDeb = millis();
    
    void setup() {
        Serial.begin(9600);
        Ethernet.begin(mac, ip);
        Serial.print("\nLe serveur est sur l'adresse : ");
        Serial.println(Ethernet.localIP());
        serveur.begin();
    
        for(int i=0; i<5; i++){
            pinMode(pinLED[i], OUTPUT);
            digitalWrite(pinLED[i], HIGH);
        }
    }
    
    void loop() {
        EthernetClient client = serveur.available();    //on écoute le port
        if(client){                                     //si client connecté
            Serial.println("Client en ligne\n");
    
            if(client.connected()){                      //si le client est en connecté
                GET(client);
                gestionLED();
                
                while(client.available()){              //tant qu'il a des infos à transmettre
                    char c = client.read();
                    Serial.write(c);                    //on l'écrit sur le moniteur série
                    delay(1);                           //délai de lecture
                }
    
                //Ecriture de la page initiale
                entete(client);
                String ligne0 = ("LED 0 " + etats[tabEtatLED[0]] + " <a href=?val=0>Change</a><br>");
                client.println(ligne0);
                String ligne1 = ("LED 1 " + etats[tabEtatLED[1]] + " <a href=?val=1>Change</a><br>");
                client.println(ligne1);
                String ligne2 = ("LED 2 " + etats[tabEtatLED[2]] + " <a href=?val=2>Change</a><br>");
                client.println(ligne2);
                Serial.println(ligne2);
                String ligne3 = ("LED 3 " + etats[tabEtatLED[3]] + " <a href=?val=3>Change</a><br>");
                client.println(ligne3);
                String ligne4 = ("LED 4 " + etats[tabEtatLED[4]] + " <a href=?val=4>Change</a><br>");
                client.println(ligne4);
    
                client.println("<br></body></html>");
                client.stop();
                Serial.println("Fin de communication avec le client");
    
                
            }
        }
    }
    
    void entete(EthernetClient cl){
        cl.println("<!DOCTYPE HTML>");
        cl.println("<html><head><title>Web-Commande de LED</title></head>");
        cl.println("<body><h1>Web-Commande de LED</h1><br><hr>");
    }
    
    //version simple, mais devrait controler quelle valeur GET est récupérée (dans le cas de plusieurs par exemple)
    void GET(EthernetClient cl){
        int lecture = 0;                    // variable pour les étapes de décodage
        String donnee = "";   
        
        while(cl.available()){
            char c = cl.read();
            if (lecture == 0 && c == '?') { //début de lecture des données donc d'un nom
                lecture = 1;
                donnee = "";
            }else if (lecture == 1 && c == '=') {   //début de lecture d'une valeur
                lecture = 2;
                donnee = "";
            }else if (lecture == 2 && c == '&') {   //nouveau nom
                lecture = 1;
                donnee = "";
            }else if ((lecture == 2 || lecture == 1) && c == ' ') { //fin de lecture
                lecture = 3;
            }else if (lecture == 1 || lecture == 2) {   //récupération des données de nom ou de valeur
                int led = int(c) - 48;                  //conversion char en int
                tabEtatLED[led] = (tabEtatLED[led] + 1) %3;
            }
            delay(1); //delai de lecture
        }
    }
    
    void gestionLED(){
        for(int i=0; i<5; i++){
            switch(pinLED[i]){
                case 0:     //ON
                    digitalWrite(pinLED[i], HIGH);
                    break;
                case 1:     //OFF
                    digitalWrite(pinLED[i], HIGH);
                    break;
                case 2:     //clignote
                    clignoter(pinLED[i]);
            }
        }
    }
    
    void clignoter(int led){
        long tempsAct = millis();
        int niveau = 1;
        
        while(pinLED[led] == 2){
            if(tempsAct - tempsDeb > 500){
                niveau = (niveau + 1) % 2;
                digitalWrite(pinLED[led], niveau);
            }
        }
        
        
    }



    -
    Edité par Uhmoja 9 septembre 2019 à 19:23:49

    • Partager sur Facebook
    • Partager sur Twitter
      11 septembre 2019 à 13:15:04

      Bonjour,

      Tu n'as pas de carte SD dans le lecteur du shield ? Parce que ça expliquerait peut-être pourquoi ça met 0.0.0.0 pour l'adresse alors qu'elle est explicitement définie, dans ce cas, il faut configurer la broche 4 (Chip Select de la SD) en sortie et le mettre à 1 pour désactiver la SD.

      De plus, sur certains shields, les broches du connecteur Ethernet sur le dessous du shield peuvent entrer en contact avec le dessus de la prise USB type B de l'arduino et faire un court-circuit (les broches du shield officiel sont suffisamment longues pour que ça n'arrive pas, mais les clones ne sont pas tous égaux).

      Accessoirement tu as une boucle sans fin dans ta fonction clignoter: pinLED[led] n'est pas modifié dans la boucle, donc si elle vaut 2, et que c'est la seule condition de la boucle, elle ne s'arrête pas et donc ton programme ne peut plus répondre aux requêtes HTTP.

      La fonction gestionLED devrait être appelée en dehors du if(client), sinon les LEDs ne clignoteront que le temps de connexion d'un client. Tu auras aussi des problèmes si tu gères tempsDeb/tempsAct dans la fonction clignoter, puisque la première LED à clignoter devrait mettre à jour tempsDeb et les autres n'auront jamais une condition "tempsAct - tempsDeb > 500" à moins d'avoir un temps de début de clignotement par LED (transformer tempsDeb en tableau), ou gérer tempsDeb et niveau dans gestionLED avant la boucle for.

      • Partager sur Facebook
      • Partager sur Twitter
        11 septembre 2019 à 22:51:36

        Un grand merci à toi alexisdm,

        En effet, j'avais une carte SD, et paramétrer correctement le pin 4 semble avoir réglé le problème, je ne pensais pas que cela causerais de soucis si je ne me servais pas de la carte et du pin.

        Merci d'avoir pris le temps d'analyser mon code, j'avais corrigé le placement de gestionLED() et la fonction clignoter, mais ma gestion du tempsDeb et tempsAct est toujours à revoir.

        • Partager sur Facebook
        • Partager sur Twitter

        Arduino & Ethernet

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown