Il est possible de créer un serveur HTTP (ou serveur WEB).
Le code HTML est directement écrit dans le programme de l'ESP32 ou contenu dans un fichier séparé.
.
|
|
Le protocole HTTP (HyperText Transfer Protocol)
C'est un protocole de communication client-serveur développé pour le World Wide Web.
Le but du protocole HTTP est de permettre un transfert de fichiers (essentiellement au format HTML) localisés grâce à une chaîne de caractères appelée URL entre un client (navigateur) et un serveur Web
Un serveur web est un logiciel capable de répondre à des requêtes HTTP, c'est à dire de renvoyer des données comme une page HTML en réponse à des demandes écrites en HTTP (exemple : une requête GET)
Communication entre client et serveur
- Le serveur écoute le port. Il attend la connexion d'un client.
- Tant qu'aucun client ne se présente, on reste bloqué (accept)
- Le client envoie une requête.
- Le serveur traite la requête puis envoie la réponse.
|
|
Serveur web, code HTML et MicroPython pour afficher une variable sur une page web
|
Affiche le résultat de la conversion analogique numérique de la tension présente sur la broche 34
Raccorder un potentiomètre sur la broche 34 (ADC1_CH6, repère A3 Shield base Grove).
Connecter l'ESP32 et le smartphone au point à un point d'accès Wifi (voir chapitre Configuration Wifi)
Le code HTML est directement intégré au code Micropython.
La variable à afficher, ici pot, est directement intégrée au code HTML.
Pour éviter de rafraîchir manuellement la page, ajouter le code HTML suivant dans l'en-tête (head) : <meta http-equiv="refresh" content="1">
Le client enverra automatiquement toutes les secondes une requête GET pour rafraîchira la page.
from machine import ADC, Pin can = ADC(Pin(34)) # crée un objet ADC sur la broche 34 can.atten(ADC.ATTN_11DB) # étendue totale : 3.3V ADC.width(ADC.WIDTH_12BIT) # résolution du convertisseur à 12bits
def web_page(): pot = can.read() print("CAN =", pot) html = """ <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP32 Serveur Web</title> <style> p { font-size: 36px; } </style> </head> <body> <h1>CAN potentiometre = </h1> <p><span>""" + str(pot) + """</span></p> </body> </html> """ return html
socketServeur = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socketServeur.bind(('', 80)) socketServeur.listen(5)
while True: try: if gc.mem_free() < 102000: gc.collect()
print("Attente d'une connexion client") connexionClient, adresse = socketServeur.accept() connexionClient.settimeout(4.0) print("Connecté avec le client", adresse)
print("Attente requete du client") requete = connexionClient.recv(1024) #requête du client requete = str(requete) print("Requete du client = ", requete) connexionClient.settimeout(None)
print("Envoi reponse du serveur : code HTML a afficher") connexionClient.send('HTTP/1.1 200 OK\n') connexionClient.send('Content-Type: text/html\n') connexionClient.send("Connection: close\n\n") reponse = web_page() connexionClient.sendall(reponse) connexionClient.close() print("Connexion avec le client fermee") except: connexionClient.close() print("Connexion avec le client fermee, le programme a declenché une erreur")
|
Serveur web, code HTML et MicroPython pour écrire une variable depuis une page Web, pilotage d'une LED
|
Commande une LED raccordée sur la broche 25 depuis deux liens hypertexte.
Raccorder une LED sur la broche 25 (repère D3 Shield base Grove).
Connecter l'ESP32 et le smartphone au point à un point d'accès Wifi (voir chapitre Configuration Wifi)
Le code HTML est directement intégré au code Micropython.
Le client envoie au serveur certains paramètres GET par le biais de l’URL demandée. Ces paramètres sont ajoutées à l’URL avec le signe « ? » et ils indiquent au serveur quelles ressources sont demandées. Le nom et sa valeur sont toujours séparées avec le symbole « = ». La syntaxe retenue est la suivante : ?nom1=valeur1
Les paramètres étant transmis par l’URL, il est conseillé d'utiliser les paramètres GET seulement pour des applications qui ne posent pas de problème de sécurité.
Ce qui donne dans l'exemple suivant :
- /?led=on ou /?led=off dans la requête du client ;
- En décodant la requête, le serveur saura s'il faut allumer ou non la LED grâce aux paramètres ;
- Le serveur donnera comme réponse au client le code HTML contenu dans la fonction web_page() ;
from machine import Pin
led_1 = Pin(25, Pin.OUT) # broche 25 en sortie (repère D3 shield base)
def web_page():
html = """ <!DOCTYPE html> <html> <head <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP32 Serveur Web</title> <style> p { font-size: 36px; } </style> </head> <body> <h1>Commande LED</h1> <p><a href="/?led=on">Allumer LED</a></p> <P><a href="/?led=off">Eteindre LED</a></p> </body> </html> """ return html
socketServeur = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socketServeur.bind(('', 80)) socketServeur.listen(5)
while True: try: if gc.mem_free() < 102000: gc.collect() print("Attente connexion d'un client") connexionClient, adresse = socketServeur.accept() connexionClient.settimeout(4.0) print("Connecté avec le client", adresse)
print("Attente requete du client") requete = connexionClient.recv(1024) #requête du client requete = str(requete) print("Requete du client = ", requete) connexionClient.settimeout(None) #analyse de la requête, recherche de led=on ou led=off if "GET /?led=on" in requete: print("LED ON") led_1.value(1) if "GET /?led=off" in requete: print("LED OFF") led_1.value(0) print("Envoi reponse du serveur : code HTML a afficher") connexionClient.send('HTTP/1.1 200 OK\n') connexionClient.send('Content-Type: text/html\n') connexionClient.send("Connection: close\n\n") reponse = web_page() connexionClient.sendall(reponse) connexionClient.close() print("Connexion avec le client fermee") except: connexionClient.close() print("Connexion avec le client fermee, le programme a declenché une erreur")
|
Serveur web, code HTML pour afficher des boutons On OFF sur une page web
|
Le code MicroPython est identique au code avec liens hypertextes ci-dessus.
<html> <head> <title>ESP</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> html { font-family: Helvetica; margin: 0px auto; text-align: center; } h1 { color: #0F3376; padding: 2vh; } p { font-size: 24px; } .button { background-color: #4CAF50; /* Vert */ border: none; border-radius: 6px; /* Angle arrondi */ color: white; padding: 15px 32px; text-align: center; text-decoration: none; font-size: 30px; } .button2 { background-color: #f44336; /* Rouge */ } </style> </head> <body> <h1>ESP Serveur Web</h1> <p><a href="/?led=on"><button class="button">ON</button></a></p> <p><a href="/?led=off"><button class="button button2">OFF</button></a></p> </body> </html>
|
|
Code sur https://www.w3schools.com
|
Serveur web, code HTML et MicroPython pour afficher un potentiomètre sur une page web
|
Ce code permet d'afficher un potentiomètre sur le navigateur et de transmettre sa valeur courante par requête.
Le client envoie au serveur des paramètres GET.
Dans l'exemple suivant :
- Le client envoie /?pot1_valeur=121 par exemple. 121 étant la valeur courante du potentiomètre.
- Le serveur décode la requête pour isoler la valeur courante : 121
- Le serveur donnera comme réponse au client le code HTML contenu dans la fonction web_page() ;
def web_page(): html = """ <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP32 Serveur Web</title> <style> p { font-size: 36px; } .slidecontainer {width: 100%;} .slider { -webkit-appearance: none; width: 80%; height: 25px; background: #ffd800; /*couleur glisssière jaune*/ outline: none; } .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #FF0000; /*couleur curseur rouge*/ cursor: pointer; } </style> </head> <body> <h1>Potentiometre 1</h1> <p><input type="range" onchange="fct_envoi()" min="0" max="255" value="127" class="slider" id="id_pot1" ></p> <p>Valeur : <span id="id_affichage_pot1_valeur"></span></p> <script> // Java script function fct_envoi() { var pot1 = document.getElementById("id_pot1"); var pot1_valeur = pot1.value; document.getElementById("id_affichage_pot1_valeur").innerHTML = pot1_valeur var objet_XHR = new XMLHttpRequest(); objet_XHR.open("GET", "/pot1?valeur="+pot1_valeur, true); objet_XHR.send(); } </script> </body> </html> """ return html
socketServeur = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socketServeur.bind(('', 80)) socketServeur.listen(5)
while True: try: if gc.mem_free() < 102000: gc.collect()
print("Attente connexion d'un client") connexionClient, adresse = socketServeur.accept() connexionClient.settimeout(4.0) print("Connecté avec le client", adresse)
print("Attente requete du client") requete = connexionClient.recv(1024) #requête du client requete = str(requete) print("Requete du client = ", requete) connexionClient.settimeout(None)
#analyse de la requête, recherche de pot1?valeur= if "GET /pot1?valeur=" in requete: indice_debut = requete.find("=")+1 indice_fin = requete.find("HTTP")-1 pot1_valeur = int(requete[indice_debut:indice_fin]) print("pot1_valeur = ", pot1_valeur) print("Envoi reponse du serveur : code HTML a afficher") connexionClient.send('HTTP/1.1 200 OK\n') connexionClient.send('Content-Type: text/html\n') connexionClient.send("Connection: close\n\n") reponse = web_page() connexionClient.sendall(reponse) connexionClient.close() print("Connexion avec le client fermee")
except: connexionClient.close() print("Connexion avec le client fermee, le programme a declenché une erreur")
|
|
Code sur https://www.w3schools.com
|
Créé avec HelpNDoc Personal Edition: Outil de création d'aide complet