Exemple d'usage du shield Ethernet pour faire un serveur interactif

Bonjour à tous,

(EDIT: en post #25 la meme chose pour une carte esp8266 genre Wemos D1 R2)

comme j'ai vu pas mal de questions concernant l'usage d'un shield Ethernet pour permettre de piloter son Arduino par une page web, ou simplement d'afficher de l'information en provenance de son Arduino sur un navigateur, je me suis dit qu'en cette fin de journée pluvieuse ce serait un petit exercice sympa à partager.

Le montage physique est super simple:

Vous connectez le shield ethernet sur votre UNO
Vous connectez la pin 7 à l'Anode (longue broche) d'une LED rouge (fil rouge sur la photo)
Vous connectez la cathode de la LED à une Résistance de limitation de courant (200 à 300Ω)
Vous connectez l'autre côté de la résistance au GND de la carte arduino (fil vert sur la photo)
Vous branchez un câble ethernet relié à votre réseau local dans la prise ethernet du shield

Vous branchez le câble USB vers votre ordinateur favori et chargez le programme, ouvrez la console à 115200 bauds

Vous prenez un navigateur web d'un ordinateur quelconque qui se trouve sur le réseau local pour vous connecter

L'idée est d'afficher une page HTML qui permet

  • de modifier l'état d'une PIN pour allumer ou éteindre la LED
  • de visualiser et interagir avec des variables dans le programme (V et W)

Modification de l'état d'une pin

on se connecte depuis un navigateur sur son arduino par le biais de la liaison ethernet locale et de son shield ethernet. le programme vous dira quelle URL utiliser, ouvrez la console à 115200 bauds et vous n'aurez plus qu'à copier coller l'URL. Pour moi c'est http://192.168.1.29

Voilà ce que l'on fait:


(1) on clique sur le bouton "LED ON"


(2) ça envoie un requête à votre Arduino sous la forme http://192.168.1.29/[color=red]LED=1[/color]. L'aduino reçoit la requête, va analyser le LED=1 pour comprendre ce que vous voulez faire, modifier l'état de la LED (l'allumer) puis l'Arduino va
(3) régénérer la page web mais ce coup ci de bouton va dire "LED OFF" (pour éteindre la LED)


Modification d'une variable dans le programme

De la même manière quand vous
(1) cliquez sur le bouton [b]V +1[/b]
(2) une URL déclenchera une requête particulière http://192.168.1.29/[color=red]V=1[/color]. L'aduino reçoit la requête, va analyser le V=1 pour comprendre ce que vous voulez faire, modifier la valeur de la variable V et
(3) afficher à nouveau la page, avec la valeur de V modifiée


Il en va de même pour W mais ici le code incrémente ou décrémente de 5 en 5 suivant le bouton et l'URL générée est http://192.168.1.29/[color=red]W=5[/color]


Enfin Si vous cliquez sur le bouton RESET, l'URL générée tient compte des valeurs des variables et va envoyer par exemple http://192.168.1.29/[color=red]LED=0,V=0,W=-5[/color]. L'aduino reçoit la requête, va analyser chacune des commandes séparées par des virgules et faire ce qui est demandé. ça vous donnera l'occasion de voir comment utiliser la fonction strtok() qui est bien pratique pour l'analyse de chaînes de caractères.


Bien sûr si vous tapiez directement l'URL http://192.168.1.29/[color=red]W=-70[/color] à la main, le code fonctionnera et reconnaitra que vous voulez modifier la variable W et ajouter -70 (donc soustraire 70).


C'est pas trop commenté mais bon, ça devrait se lire sans trop de problème.

le code de connexion au réseau provient de l'exemple standard DHCP fournit avec l'IDE et donc dépend d'un serveur DHCP (qui vous fournit une adresse IP quand vous vous branchez sur le réseau, toutes les box internet font cela en standard) - sinon faudra modifier quelques lignes pour passer en adresse statique sur votre réseau (cf la doc standard de la libraire Ethernet)

La partie serveur HTTP provient pour la base de l'exemple standard /WebServer fournit avec l'IDE.

J'ai organisé le code en gros comme ceci:

la loop() vérifie que le shield dispose toujours d'une adresse IP par renewDHCPLease()) puis appelle handleClient();. Cette fonction regarde s'il y a une requête HTTP qui arrive, si oui trouve la partie qui commence par "GET /...." car c'est notre commande (le reste c'est du bavardage du protocole HTTP) et extrait ce que je mets en rouge dans les URL ci dessus, par exemple [color=red]LED=1[/color] (stockée dans la chaîne urlCommand)

Une fois que la requête HTTP a été entièrement lue (elle se termine par une ligne vide) alors on appelle la fonction handleCommand(); qui va d'abord analyser la commande par la fonction parseCommand(); et effectuer ce qui est demandé puis refabriquer la page web avec la fonction sendHTTPResponse() et clore la connexion.

ethernetShieldDemo.ino (8.71 KB)

Merci pour le partage J-M-L, j'étudierai le code avec soin, peut être que je trouverai le problème que j'ai avec ma NodeMCU.

Bonjour J-M-L,

Il y a une partie de la fonction handleClient() que je n'arrive pas à expliquer:

if (client.available()) {
        char c = client.read();
        // Serial.print(c); // if you want to see the HTTP request
        if (!urlCommandFound) {
          httpHeader[httpHeaderIndex++] = c;
          httpHeader[httpHeaderIndex] = '\0';
          if (httpHeaderIndex > MaxCommand - 1) httpHeaderIndex = MaxCommand - 1;
        }

De ce que je comprend, chaque caractère reçu est rangé dans le tableau httpHeader et en même temps, l'index httpHeaderIndex est incrémenté. Dans la limite de MaxCommand
Mais ce même caractère est tout de suite remplacé par '\0', donc le tableau reste vide en permanence?

A moins que le ++ n'incrémente l'index qu'une fois l'écriture faite et non avant?

Ça reste une incompréhension du C pour moi...

Jambe:
A moins que le ++ n'incrémente l'index qu'une fois l'écriture faite et non avant?

Bravo vous avez gagné :slight_smile:

il faut savoir qu'on peut mettre ++ (ou --) avant ou après la variable et ce n'est pas la même chose:

si vous écrivez i++, l'expression est évaluée à la valeur de variable, et l'incrémentation est effectuée ensuite. Donc si i vaut 10 par exemple tableau[i++] = 100; va mettre 100 dans tableau[10] et augmenter i de 1 et i vaudra 11

On peut écrire ++i et ce n'est pas la même chose , dans ce cas on commence par incrémenter la variable, et l'expression est évaluée à la valeur incrémentée. donc si i vaut 10, alors tableau[++i] = 100; va mettre 100 dans tableau[11] et i vaudra 11

J-M-L:
Bravo vous avez gagné :slight_smile:

il faut savoir qu'on peut mettre ++ (ou --) avant ou après la variable et ce n'est pas la même chose:

Aaah! Je connaissait pourtant les 2 écritures, c'est abordé dans de nombreux cours ou tuto à travers le net mais jamais la distinction n'est faite.

Merci pour la précision!

De rien :slight_smile:

bonjour et merci pour le tutoriel!

moi j'ai un petit soucis et j'ai besoin d'aide.

j'utilise un modem wifi pour me connecter à Internet.

du coup j'aimerais savoir comment partager la connexion Internet de mon pc avec ma carte arduino via le shield Ethernet.

merci d'avance

Postez dans le forum principal, ne polluez pas cette file avec des commentaires qui n'ont rien à voir...

Merci beaucoup pour votre courtoisie

"polluer" n'est pas à prendre péjorativement, juste factuel. Postez dans le forum principal et je participerai aux réponses dès que j'ai un peu de temps

Merci pour le partage J-M-L ,

je me suis permis de modifier le code de base legerement , de sorte qu il soit compatible avec le nouvel IDE , avec le mega 2560 et le shield ethernet 2 ( wiznet 5500 ) .

Vu que j' avais besoin de piloter environ 50 relais confortablement , je me suis permis d' ajouter le code qui va bien avec ton tuto .

Si jamais ca ne vous pas , dites le moi .

Pas de soucis c'est pour cela que les tutos sont faits - faut pas hésiter à copier, s'inspirer, modifier, améliorer, détourner, etc (et corriger les bugs s'il y en a :slight_smile: )

Bonjour,
J'utiliserais votre programme pour conduire des volets roulants. Est-il possible avec une minuterie de varier la durée de la mise en service des relais?

@titof

Allez voir mon autre petit tuto sur les machines à états et comment introduire le temps sans bloquer la machine

Merci

Bonjour,

Merci pour ce tuto.

Est-il possible d'avoir le code la page HTML, car je ne l'ai pas trouver en parcourant les différents liens de votre tuto.

La page HTML est générée directement dans le code source, ligne par ligne. Pour voir à quoi elle ressemble le plus simple c’est de demander au navigateur web de vous montrer le HTML reçu

Bonjour,

Encore un tutoriel magnifique encore J-M-L :slight_smile: Trop trop fort et impeccable. Instructions claire, net et précise c'est du (Made In J-M-L) :slight_smile:

Possédant le module en mini shield, c'est exactement ce qu'il me fallait pour commencer à le testé,
Karma pour JML merci infiniment.

Bonjours,

Je ne suis pas sûr de tout comprendre, comment ton programme peut-il fonctionner à l'infini si tu ne ne met rien dans ton void loop?

TanguyISN:
Bonjours,

Je ne suis pas sûr de tout comprendre, comment ton programme peut-il fonctionner à l'infini si tu ne ne met rien dans ton void loop?

euh, il y a bien quelque chose dans la loop(), je demande de gérer les clients

void loop() {
  if (renewDHCPLease()) handleClient();
}

Toute la magie est dans handleClient(); et bien sur vous pouvez rajouter du code dans la loop ensuite à condition que ce soit rapide et que vous reveniez tester les clients assez souvent