|
|
(5 révisions intermédiaires par le même utilisateur non affichées) |
Ligne 37 : |
Ligne 37 : |
| |Prerequisites=Configurez le réseau Wifi sur un ESP | | |Prerequisites=Configurez le réseau Wifi sur un ESP |
| }} | | }} |
− | |Tuto_Attachments={{Tuto Attachments | + | |ExternalAttachmentsLinks={{ExternalAttachmentsLinks |
− | |Attachment=Commander_un_D1_mini_avec_une_interface_web_A_D1_WiFi.ino | + | |ExternalAttachmentsLinks=https://cloud.debrouillonet.org/s/w6F3L2CpXDX4dxZ |
− | }}{{Tuto Attachments}}{{Tuto Attachments
| |
− | |Attachment=Commander_un_D1_mini_avec_une_interface_web_C_Cmd_Leds.ino
| |
− | }}{{Tuto Attachments
| |
− | |Attachment=Commander_un_D1_mini_avec_une_interface_web_D_Servomoteur.ino
| |
− | }}{{Tuto Attachments
| |
− | |Attachment=Commander_un_D1_mini_avec_une_interface_web_E_Potentiometre.ino
| |
− | }}{{Tuto Attachments
| |
− | |Attachment=Commander_un_D1_mini_avec_une_interface_web_F_Schema_Montage.ino
| |
| }} | | }} |
| }} | | }} |
Ligne 67 : |
Ligne 59 : |
| {{Tuto Step | | {{Tuto Step |
| |Step_Title=Chargement du code Arduino sur le D1 mini | | |Step_Title=Chargement du code Arduino sur le D1 mini |
− | |Step_Content=On suppose ici que le logiciel Arduino est déjà installé, ainsi que la bibliothèque de gestion du D1 mini (voir pré-requis). | + | |Step_Content=On suppose ici que le logiciel Arduino est déjà installé, ainsi que la bibliothèque de gestion du D1 mini (voir pré-requis). |
| | | |
− | #Créez sur votre ordinateur un répertoire '''A_D1_WiFi'''. | + | #Téléchargez le fichier '''A_D1_WiFi.zip''' (Cf. rubrique "Fichiers ci-dessus"), puis en extraire le répertoire '''A_D1_WiFi''', qui contient tous les modules Arduino (*.ino") - Cf image n° 1. |
− | #Téléchargez tous les fichiers de code Arduino (suffixe ".ino") sous ce répertoire. Vous devriez avoir alors 6 fichiers (Cf. image n° 1)
| + | #Double-cliquez sur le fichier '''A_D1_WiFi.ino''', ce qui lancera le logiciel Arduino, sous lequel vous aurez 6 onglets correspondant aux 6 fichiers - Cf. image n° 2. |
− | #Double-cliquez sur le fichier A_D1_WiFi.ino, ce qui lancera le logiciel Arduino, sous lequel vous aurez 6 onglets correspondant aux 6 fichiers (Cf. image n°2) | |
| #Connectez le D1 mini au port USB de votre ordinateur. | | #Connectez le D1 mini au port USB de votre ordinateur. |
− | #Dans le menu "Outil", positionnez le bon type de carte, et le bon port (Cf. image n°3). Si cette carte n'est pas définie, ou que le port est grisé, revérifier la configuration Arduino grâce au prérequis [[Utiliser le D1 mini avec Arduino]]. | + | #Dans le menu "Outil", positionnez le bon type de carte, et le bon port - Cf. image n°3. Si cette carte n'est pas définie, ou que le port est grisé, revérifier la configuration Arduino grâce au prérequis [[Utiliser le D1 mini avec Arduino]]. |
− | #Cliquez sur l'icône de téléversement (Cf.. image n° 4), et patientez. Si le téléversement se termine bien (Cf. image n°5), bravo ! Si un message d'erreur indique que le port n'est pas le bon, il faut le modifier dans l'onglet outil et relancer cette étape.<br /> | + | #Cliquez sur l'icône de téléversement - Cf.. image n° 4, et patientez. Si le téléversement se termine bien - Cf. image n°5, bravo ! Si un message d'erreur indique que le port n'est pas le bon, il faut le modifier dans l'onglet outil et relancer cette étape.<br /> |
− | | |
− | <br />Code du fichier B_Serveur_Web.ino :
| |
− | <br /><syntaxhighlight lang="arduino">
| |
− | /* ==============================================================================================================
| |
− | *
| |
− | * B_SERVEUR_WEB
| |
− | *
| |
− | * --------------------------------------------------------------------------------------------------------------
| |
− | * Ce module gère l'ensemble des pages Web générées par le D1 Mini. Dans cet exemple, il y a une seule page Web.
| |
− | * La page Web est lancée par le D1 Mini par la fonction 'server.send', prenant en paramètre une chaîne de caractères
| |
− | * contenant l'intégralité de cette page web au format HTML/CSS/Javascript standard ... on suppose ici que ce format
| |
− | * n'a plus de secrets pour vous, mais on mettra quand même quelques rappels au cas où ... ;-)
| |
− | * --------------------------------------------------------------------------------------------------------------
| |
− | * IMPORTANT : Le code HTML/Javascript/CSS étant contenu dans une chaîne de caractères, des précautions s'imposent :
| |
− | *
| |
− | * - La chaîne de caractère complète étant encadrée par un double-apostrophe ("), le contenant doit utiliser
| |
− | * uniquement des apostrophes simples (').
| |
− | * - Pour pouvoir débugger facilement le code HTML/Javascript sur un browser (*), il est préférable d'indenter le code
| |
− | * à l'intérieur même de la chaîne de caractère, et de mettre des sauts de ligne ("\n") à la fin de chaque ligne de code.
| |
− | * - Comme tout code, il est indispensable de mettre des commentaires dans cette partie HTML/Javascript. Mais pour
| |
− | * alléger le D1 Mini, ces commentaires ne sont pas insérés dans la chaîne de caractères. Ils resteront au niveau
| |
− | * de l'interface IDE / Arduino, et donc non téléversés.
| |
− | *
| |
− | * (*) Par exemple sous Firefox : (menu de l'application) --> Outils supplémentaires --> Outils de développement Web
| |
− | * =============================================================================================================*/
| |
− | | |
− | /* --------------------------------------------------------------------------------------------------------------
| |
− | * Variables globales du module
| |
− | * ------------------------------------------------------------------------------------------------------------- */
| |
− | | |
− | String A_pLed = "00000" ; // contiendra la valeur du paramètre 'led' de la page web.
| |
− | String A_pCmd = "0000" ; // idem pour 'cmd'.
| |
− | String A_pSrv = "90" ; // idem pour 'servo'.
| |
− | String A_pPot = "0" ; // idem pour 'pot'.
| |
− | String A_pPtc = "0" ; // idem pour 'ptc'
| |
− | | |
− | String A_ledNames[] = { "Led 0", "Led 1", "Led 2", "Led 3", "Led 4" } ;
| |
− | String A_cmdNames[] = { "Clignote 1", "Clignote 2", "Defile 1", "Defile 2" } ;
| |
− | | |
− | /* --------------------------------------------------------------------------------------------------------------
| |
− | * WEBPAGE01 : construction de la page web n° 1
| |
− | * ------------------------------------------------------------------------------------------------------------- */
| |
− | String webPage01(){
| |
− |
| |
− | String p; // cette chaine contiendra l'intégralité de la page web au format HTML/CSS/Javascript
| |
− | | |
− | // Début de construction de la page web (entête, titre)
| |
− |
| |
− | p = "<html lang=fr-FR><head>\n" ;
| |
− | p += " <title>Interface web D1 mini</title>\n" ; // Titre de la page
| |
− | p += " <meta charset='iso-8859-1'>\n" ; // Codage des caractères
| |
− | p += " <meta http-equiv='Refresh' content='2'>\n" ; // La page se rafraichira toutes les 2 secondes
| |
− | p += "</head>\n" ;
| |
− | | |
− | // Définitions CSS (), qui permettent de décrire le format des objets sur la page web (tableaux, boutons, ...)
| |
− | // Si vous voulez tout savoir sur CSS, on peut trouver une bonne introduction ici : https://developer.mozilla.org/fr/docs/Learn/CSS
| |
− | // et une référence complète ici : https://developer.mozilla.org/fr/docs/Web/CSS/Reference
| |
− |
| |
− | p += "<style>\n" ;
| |
− | p += " body { background-color: #000088; font-family: Arial, Helvetica, Sans-Serif; color: white; }\n";
| |
− | p += " table { width: 98%; background-color: white; border: 1px solid #000088; margin-top:20px; border-radius: 15px; }\n";
| |
− | p += " th, td { border: 0px; border-collapse: separate; text-align:center; }\n";
| |
− | p += " h1 { font-size:300%; color: #000088; }\n";
| |
− | p += " h2 { font-size:250% }\n";
| |
− | p += " .headerimg { border: 1px; width:25%}\n";
| |
− | p += " .headertitle { border: 1px; }\n";
| |
− | p += " .b_led { width:15%; }\n"; // Car 5 boutons 'Led' par ligne
| |
− | p += " .b_cmd { width:20%; }\n"; // Car 4 boutons 'Cmd' par ligne
| |
− | p += " input { border:none; border-radius: 15px; margin:2%; height:8%; font: bold ; font-size:200% ; }\n";
| |
− | p += " .input_off { box-shadow: 3px 3px 5px black; background-color: #AAAAAA; color: black; }\n";
| |
− | p += " .input_off:focus { box-shadow: inset 3px 3px 5px black; background-color: yellow; color: red; }\n";
| |
− | p += " .input_on { box-shadow: inset 3px 3px 5px black; background-color: yellow; color: red; }\n";
| |
− | p += " .bservo { width:15%; box-shadow: 3px 3px 5px black; background-color: red; color: white; font: bold ; font-size:200% ;}\n";
| |
− | p += " .bservo:focus { box-shadow: inset 3px 3px 5px black; background-color: yellow; color: red; }\n";
| |
− | p += " .bmoteur { width:25%; }\n";
| |
− | p += " .blabel { font-size:200% ; color: yellow; }\n";
| |
− | p += "</style>\n" ;
| |
− | | |
− | // Début du code javascript. Javascript est le langage utilisé au niveau des navigateurs web (Firefox, Microsoft Edge, Google Chrome, ...)
| |
− | // pour introduire un peu de dynamisme et d'intelligence dans les pages web. Cela peut permettre, par exemple, de réaliser une action
| |
− | // locale et immediate, telle que l'agrandissement d'une image, le changement d'un texte, etc ... sans avoir à réinterroger le serveur web.
| |
− | | |
− | p += "<script>\n" ;
| |
− |
| |
− | // ---
| |
− | // Variables globales du code Javascript. On va en particulier recopier les valeurs des paramètres de la page web.
| |
− | // ---
| |
− |
| |
− | p += "let J_nbLeds = " + String(GL_nbLeds) + ";\n";
| |
− | p += "let J_nbCmds = " + String(GL_nbCmds) + ";\n";
| |
− | p += "let J_pLed = '" + A_pLed + "';\n";
| |
− | p += "let J_pCmd = '" + A_pCmd + "';\n";
| |
− | p += "let J_pSrv = '" + A_pSrv + "';\n";
| |
− | p += "let J_pPot = '" + A_pPot + "';\n";
| |
− | p += "let J_pPtc = '" + A_pPtc + "';\n";
| |
− | p += "let incrSrv = 10 ;\n";
| |
− |
| |
− | // ---
| |
− | // Fonction reloadWebPage : recharge la page web avec de nouveaux paramètres.
| |
− | // ---
| |
− |
| |
− | p += "//---\n" ;
| |
− | p += "function reloadWebPage(led,cmd,srv,pot,ptc) {\n";
| |
− | p += " window.location = window.location.pathname + '?led=' + led + '&cmd=' + cmd + '&srv=' + srv + '&pot=' + pot + '&ptc=' + ptc ;\n";
| |
− | p += "}\n";
| |
− |
| |
− | // ---
| |
− | // Fonction clickLed : activée lorsqu'un bouton de test individuel de led est cliqué
| |
− | // On reconstitue le paramètre "led" puis on recharge la page web. Seul le 'n+1-ième' (*) caractère change, le reste ne bouge pas.
| |
− | // (*) n entre 0 et 4, donc n = 2 va modifier le 3ème caractère. Par exemple : J_pLed = "01001" et n = 2 --> newLed "01101".
| |
− | // Si n'importe quel bouton de test est cliqué, on annule toute commande 'évoluée' en cours (d'où le '0000' dans le reloadWebPage).
| |
− | // ---
| |
− |
| |
− | p += "//---\n" ;
| |
− | p += "function clickLed(n) {\n";
| |
− | p += " var newLed = J_pLed.substring(0,n) + (J_pLed.charAt(n) == '0' ? '1' : '0') + J_pLed.substring(n+1) ; \n";
| |
− | p += " reloadWebPage(newLed, '0000', J_pSrv, J_pPot, J_pPtc) ;\n";
| |
− | p += "}\n";
| |
− | | |
− | // ---
| |
− | // Fonction clickCmd : activée lorsqu'un bouton de commande 'évoluée" est cliqué.
| |
− | // On reconstitue le paramètre "cmd" puis on recharge la page web. Un seul des caractères doit être égal à 1 au mieux.
| |
− | // Par exemple, J_pCmd = "0100" et n = 2 ==> newCmd = "0010"
| |
− | // Si n'importe quel bouton de commande 'évoluée' est cliqué, les test individuels sont annulés (d'où le '00000' dans le reloadWebPage).
| |
− | // ---
| |
− | | |
− | p += "//---\n" ;
| |
− | p += "function clickCmd(n) {\n";
| |
− | p += " var newCmd = '' ;\n" ;
| |
− | p += " newCmd = newCmd.padEnd(n, '0') + (J_pCmd.charAt(n) == '0' ? '1' : '0') + newCmd.padEnd(J_nbCmds, '0') ;\n";
| |
− | p += " reloadWebPage('00000', newCmd, J_pSrv, J_pPot, J_pPtc) ; \n";
| |
− | p += "}\n";
| |
− | | |
− | // ---
| |
− | // Fonction clickSrv : activée lorsqu'un bouton "servo" est appuyé. Cette fonction se contente de modifier le
| |
− | // paramètre 'srv' de la page web, avant de réactualiser la page. Valeur du paramètre "n" :
| |
− | // (-2) marche arrière à vitesse maximale
| |
− | // (-1) réduction de la vitesse si marche avant, accélération en marche arrière
| |
− | // (0) arrêt du moteur
| |
− | // (1) accélération si marche avant, réduction de la vitesse si marche arrière
| |
− | // (2) marche avant à vitesse maximale
| |
− | // Si n'importe quel bouton 'servo' est appuyé, on annule l'action du potentiomètre (d'où le '0' dans reloadWebPage).
| |
− | // ---
| |
− | | |
− | p += "//---\n" ;
| |
− | p += "function clickSrv(n) {\n";
| |
− | p += " var newSrv; \n" ;
| |
− | p += " switch(n) {\n" ;
| |
− | p += " case -2 : newSrv = 0 ; break ; \n";
| |
− | p += " case -1 : newSrv = " + String(GL_servoSpeed) + " - incrSrv; if (newSrv < 0) { newSrv = 0; } ; break ; \n";
| |
− | p += " case 0 : newSrv = 90; break ; \n";
| |
− | p += " case 1 : newSrv = " + String(GL_servoSpeed) + " + incrSrv; if (newSrv > 180) { newSrv = 180; } ; break ; \n";
| |
− | p += " case 2 : newSrv = 180 ; break ; \n";
| |
− | p += " }\n" ;
| |
− | p += " reloadWebPage(J_pLed, J_pCmd, newSrv, J_pPot, '0') ; \n";
| |
− | p += "}\n";
| |
− |
| |
− | // ---
| |
− | // Fonction clickMot : activée lorsqu'un bouton "potentiomètre (non/oui)" est appuyé.
| |
− | // Si on a appuyé sur "non", on remet le moteur à l'arrêt (d'ou le '90' dans le reloadWebPage ci-dessous)
| |
− | // Si on a appuyé sur 'oui", la valeur du servo-moteur est mise à jour en fonction du potentiomètre.
| |
− | // ---
| |
− | | |
− | p += "//---\n" ;
| |
− | p += "function clickMot(n) {\n";
| |
− | p += " if (n == 0) { J_pSrv = '90' ; } else { J_pSrv = String(parseInt(J_pPot) * 180 / 1023) ; } \n" ;
| |
− | p += " reloadWebPage(J_pLed, J_pCmd, J_pSrv, J_pPot, n) ; \n";
| |
− | p += "}\n";
| |
− |
| |
− |
| |
− | // Nous terminons ici la partie Javascript.
| |
− | | |
− | p += "</script>\n" ;
| |
− | | |
− | | |
− | // Corps de la page web.
| |
− |
| |
− | p += "<body>\n" ;
| |
− | p += " <center><table><tr><td class='headerimg'><h1>" + GL_PtDebs_Logo + "</h1></td>\n";
| |
− | p += " <td class='headertitle'><h1>Commande Web D1 Mini</h1></td></tr></table>\n";
| |
− | | |
− | // premier formulaire = un bouton par led (commande individuelle)
| |
− | // Le format du bouton sera défini par [class = 'b_led input_off' ... ou ... 'b_led input_on', selon l'état de la led
| |
− |
| |
− | p += " <h2>Test individuel des leds</h2>\n" ;
| |
− | p += " <form>\n";
| |
− | for (int l = 0; l < GL_nbLeds; l++) {
| |
− | p += " <input class='b_led input_" + String((GL_ledState[l] == 0 ? "off" : "on")) + "' type='submit' value='" + A_ledNames[l] + "' formaction='javascript:clickLed(" + l + ");' formmethod=post>\n" ;
| |
− | }
| |
− | p += " </form>\n";
| |
− | | |
− | // Deuxième formulaire = un bouton par commande dite 'évoluée'.
| |
− | | |
− | p += " <h2>Commandes des leds</h2>\n" ;
| |
− | p += " <form>\n";
| |
− | for (int c = 0; c < GL_nbCmds; c++) {
| |
− | p += " <input class='b_cmd input_" + String((c == GL_ledMode ? "on" : "off")) + "' type='submit' value='" + A_cmdNames[c] + "' formaction='javascript:clickCmd(" + c + ");' formmethod=post>\n";
| |
− | }
| |
− | p += " </form>\n";
| |
− | | |
− | // Troisième formulaire = boutons de commande du servo-moteur.
| |
− | | |
− | p += " <h2>Servo-moteur (valeur : " + String(GL_servoSpeed) + ")</h2>\n" ;
| |
− | p += " <form>\n";
| |
− | p += " <input class='bservo' type='submit' value='<<' formaction='javascript:clickSrv(-2);' formmethod=post>\n";
| |
− | p += " <input class='bservo' type='submit' value='<' formaction='javascript:clickSrv(-1);' formmethod=post>\n";
| |
− | p += " <input class='bservo' type='submit' value='Stop' formaction='javascript:clickSrv(0);' formmethod=post>\n";
| |
− | p += " <input class='bservo' type='submit' value='>' formaction='javascript:clickSrv(1);' formmethod=post>\n";
| |
− | p += " <input class='bservo' type='submit' value='>>' formaction='javascript:clickSrv(2);' formmethod=post>\n";
| |
− | p += " </form>\n";
| |
− | | |
− | // Quatrième formulaire = gestion du potentiomètre.
| |
− | | |
− | p += " <h2>Potentiometre (valeur : " + String(GL_valPot) + ")</h2>\n";
| |
− | p += " <form>\n";
| |
− | p += " <label class='blabel'>Actionne le moteur ?</label>\n";
| |
− | p += " <input class='bmoteur input_" + String((A_pPtc == "1" ? "off" : "on")) + "' type='submit' value='Non' formaction='javascript:clickMot(0);' formmethod=post>\n";
| |
− | p += " <input class='bmoteur input_" + String((A_pPtc == "1" ? "on" : "off")) + "' type='submit' value='Oui' formaction='javascript:clickMot(1);' formmethod=post>\n";
| |
− | p += " </form>\n";
| |
− | | |
− | p += "</body></html>" ;
| |
− | | |
− | // ça y est, la page web est complètement constituée !
| |
− |
| |
− | return p;
| |
− |
| |
− | }
| |
− | | |
− | /* --------------------------------------------------------------------------------------------------------------
| |
− | * runPage01 : Gestion de la page (unique) du serveur web.
| |
− | * ------------------------------------------------------------------------------------------------------------- */
| |
− | void runPage01(){
| |
− | | |
− | // Récupération des paramètres de la page
| |
− |
| |
− | if ( GL_server.hasArg("led") ) { A_pLed = GL_server.arg("led") ; }
| |
− | if ( GL_server.hasArg("cmd") ) { A_pCmd = GL_server.arg("cmd") ; }
| |
− | if ( GL_server.hasArg("srv") ) { A_pSrv = GL_server.arg("srv") ; }
| |
− | if ( GL_server.hasArg("pot") ) { A_pPot = GL_server.arg("pot") ; }
| |
− | if ( GL_server.hasArg("ptc") ) { A_pPtc = GL_server.arg("ptc") ; }
| |
− |
| |
− | // Traitement individuel des leds (allumage / extinction)
| |
− | | |
− | int i;
| |
− | for (i = 0; i < GL_nbLeds; i++) {
| |
− | GL_ledState[i] = A_pLed.charAt(i) - '0' ; // transformation char --> int.
| |
− | digitalWrite(GL_ledPin[i], GL_ledState[i]);
| |
− | }
| |
− |
| |
− | // Traitement des boutons "Commandes 'évoluées".
| |
− | // On ne fait ici qu'initialiser le n° de la commande, le traitement sera fait dans la fonction 'loop()' du premier onglet.
| |
− |
| |
− | GL_ledMode = -1;
| |
− | for (i = 0; i < GL_nbCmds; i++) {
| |
− | if (A_pCmd.charAt(i) == '1') { GL_ledMode = i ; }
| |
− | }
| |
− |
| |
− | // Le potentiomètre actionne le moteur ? Là encore on se contente de mettre à jour le paramètre global GL_cmdServo
| |
− | // qui sera utilisé par ailleurs (ci-dessous, et dans la fonction manageAnalog() de l'onglet E_Potentiometre pour ne rien vous cacher)
| |
− | | |
− | GL_cmdServo = (A_pPtc == "1" ? true : false) ;
| |
− | | |
− | // traitement du servo-moteur, s'il n'est pas commandé par le potentiomètre
| |
− |
| |
− | if (!GL_cmdServo) {
| |
− | GL_servoSpeed = A_pSrv.toInt() ;
| |
− | runServo(GL_servoSpeed) ;
| |
− | }
| |
− | | |
− |
| |
− | // On renvoie la page web.
| |
− |
| |
− | GL_server.send ( 200, "text/html", webPage01() );
| |
− |
| |
− | }
| |
− | </syntaxhighlight><br />
| |
| |Step_Picture_00=Commander_un_D1_mini_avec_une_interface_web_Arduino-fichiers.png | | |Step_Picture_00=Commander_un_D1_mini_avec_une_interface_web_Arduino-fichiers.png |
| |Step_Picture_01=Commander_un_D1_mini_avec_une_interface_web_Arduino-onglets.png | | |Step_Picture_01=Commander_un_D1_mini_avec_une_interface_web_Arduino-onglets.png |
Ligne 363 : |
Ligne 78 : |
| <br /> | | <br /> |
| | | |
− | # Cherchez "'''DebrouilloBot_0000'''" dans la liste des points d'accès Wi-Fi, et connectez-vous sur ce point d'accès (Cf. image n° 1). Il n'y a pas de mot de passe. Il y aura peut-être un message indiquant qu'Internet n'est pas disponible, c'est normal, ne pas en tenir compte. | + | #Cherchez "'''DebrouilloBot_0000'''" dans la liste des points d'accès Wi-Fi, et connectez-vous sur ce point d'accès (Cf. image n° 1). Il n'y a pas de mot de passe. Il y aura peut-être un message indiquant qu'Internet n'est pas disponible, c'est normal, ne pas en tenir compte. |
− | # Sur votre navigateur préféré, tapez "'''192.168.4.22'''", si tout se passe bien vous aurez l’interface de commande du D1 mini (Cf. image n° 2) | + | #Sur votre navigateur préféré, tapez "'''192.168.4.22'''", si tout se passe bien vous aurez l’interface de commande du D1 mini (Cf. image n° 2) |
− | # C'est tout bon, vous pouvez activer les leds, de façon individuelle ou combinée, activer le servomoteur soit avec les touches rouges, soit en activant la commande via le potentiomètre. | + | #C'est tout bon, vous pouvez activer les leds, de façon individuelle ou combinée, activer le servomoteur soit avec les touches rouges, soit en activant la commande via le potentiomètre. |
| |Step_Picture_00=Commander_un_D1_mini_avec_une_interface_web_Mobile-WiFi.png | | |Step_Picture_00=Commander_un_D1_mini_avec_une_interface_web_Mobile-WiFi.png |
| |Step_Picture_01=Commander_un_D1_mini_avec_une_interface_web_Interface_web.png | | |Step_Picture_01=Commander_un_D1_mini_avec_une_interface_web_Interface_web.png |
Ligne 388 : |
Ligne 103 : |
| {{Notes}} | | {{Notes}} |
| {{Tuto Status | | {{Tuto Status |
− | |Complete=Draft | + | |Complete=Published |
| }} | | }} |