Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

NodeMCU ESP32 de chez Joy-it !


Sujet :

Embarqué

  1. #1
    Expert éminent sénior
    NodeMCU ESP32 de chez Joy-it !
    Salut à tous.

    J'ai commencé hier mes nouveaux tests sur le NodeMCU / ESP32 de chez Joy-it que j'ai en ma possession :
    --> https://www.gotronic.fr/art-module-n...sp32-28407.htm

    Première impression : ça ressemble un peu au bus pirate, mais pour un usage plutôt didactique.
    Sinon, pour un usage IOT (Internet of Things), c'est ce que je recherche.

    J'ai pourtant suivi la documentation de chez GoTronic, et je constate qu'il y a des erreurs :

    1) le type de la carte dans l'Arduino IDE est le "NodeMCU-32S" et non le "ESP32 Dev Module" comme c'est indiqué.
    La preuve est que l'exemple : "01.Basics" / "Blink" ne fonctionne pas avec le "ESP32 Dev Module".
    Cela provoque une erreur à la compilation.

    2) je ne comprenais pas pourquoi, j'avais toujours une erreur de communication entre mon ordinateur Windows et le NodeMCU ESP32.
    J'ai mis du temps à comprendre que je devais appuyer sur le bouton de droite (boot) pour accepter l'envoi de l'exécutable.
    Je croyais que cela se faisait automatiquement (???).
    D'ailleurs, je ne vois pas trop l'intérêt d'avoir installé un bouton pour dire que l'on accepte de "Téléverser" un exécutable ou pas.

    Est-ce la même chose sur l'arduino ?

    3) l'installation du driver se fait automatiquement sous windows 10.
    Il n'est pas nécessaire de télécharger le driver depuis le site de Silicon labs.

    4) je n'ai pas compris l'utilité d'installer la bibliothèque officiel ESP32 :
    --> https://github.com/espressif/arduino-esp32

    Surtout que je n'ai pas compris comment l'installer.
    Pour l'instant, je n'en ai pas besoin. Je verrais cela en temps utile.

    Au final de ce première découverte, j'ai installé l'Arduino IDE sans problème.
    J'ai trouvé quelques exemples qui fonctionnent parfaitement.

    Comme je débute, si vous avez des conseilles à me donner, je suis preneur.

    Mon but est double :

    a) apprendre à manipuler l'Arduino IDE afin de créer des sketchs (est-ce la bonne expression ?).
    Le langage est très proche du langage 'c' sauf que ce n'est pas le langage 'c'.
    La preuve en est avec le "print()" ou le "println()" qui n'existe pas en 'c'.

    voire installer de nouvelles bibliothèques, et comprendre comment les utiliser.

    b) me faire un sketch qui va gérer une page web, accessible depuis internet, afin de piloter une led multicolore.
    Je sais, c'est basique, mais il faut bien commencer par le début.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  2. #2
    Expert éminent sénior
    Salut à tous.

    Je me suis bien amusé, cette après-midi, en faisant mon premier sketch sur le ESP32.

    Il s'agit de piloter deux leds que j'ai branché sur les GPIO26 & GPIO27 à partir d'une page web accessible via internet.
    A vrai dire, c'est depuis mon ordinateur en local chez moi, mais c'est du pareil au même.

    Voici le sketch :
    Code arduino :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    /****************************************************/
    /*                                                  */
    /*     Serveur Web avec gestion de deux boutons     */
    /*                                                  */
    /****************************************************/
     
    #include <WiFi.h>
    #include <WebServer.h>
     
    /**************************************/
    /*                                    */
    /*     Déclaration des Constantes     */
    /*                                    */
    /**************************************/
     
    const char		*ssid			= "mon_ssid";
    const char		*pwd			= "mon_mot_de_passe";
     
    const int		led_1			= 26;						/* GPIO 26 */
    const int		led_2			= 27;						/* GPIO 27 */
     
    /*************************************/
    /*                                   */
    /*     Déclaration des Variables     */
    /*                                   */
    /*************************************/
     
    bool			led_1_state		= LOW;
    bool			led_2_state		= LOW;
     
    WebServer		server(80);									/* Port 80 */
     
    /*************************************/
    /*                                   */
    /*     Déclaration des Fonctions     */
    /*                                   */
    /*************************************/
     
    String SendHTML(bool led_1_state, bool led_2_state)
    {
    	String	html = "";
     
    	html += "<!DOCTYPE html>\n";
    	html += "<html>\n";
    	html += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0 user-scalable=no\">\n";
    	html += "<link rel=\"icon\" href=\"data:,\">\n";
    	html += "<title>Leds</title>\n";
    	html += "<style>\n";
     
    	html += "html {\n";
    	html += "\t\tfont-family\t\t\t: Helvetica;\n";
    	html += "\t\tdisplay\t\t\t\t: inline-block;\n";
    	html += "\t\tmargin\t\t\t\t: 0px auto;\n";
    	html += "\t\ttext-align\t\t\t: center;\n}\n\n";
     
    	html += "body {\n";
    	html += "\t\tmargin-top\t\t\t: 50px;\n}\n\n";
     
    	html += "h1 {\n";
    	html += "\t\tcolor\t\t\t\t: black;\n";
    	html += "\t\tmargin\t\t\t\t: 50px auto 30px;\n}\n\n";
     
    	html += ".button {\n";
    	html += "\t\tdisplay\t\t\t\t: block;\n";
    	html += "\t\twidth\t\t\t\t: 80px;\n";
    	html += "\t\tbackground-color\t: #3498db;\n";
    	html += "\t\tborder\t\t\t\t: none;\n";
    	html += "\t\tcolor\t\t\t\t: white;\n";
    	html += "\t\tpadding\t\t\t\t: 13px 30px;\n";
    	html += "\t\ttext-decoration\t\t: none;\n";
    	html += "\t\tfont-size\t\t\t: 25px;\n";
    	html += "\t\tmargin\t\t\t\t: 0px auto 35px;\n";
    	html += "\t\tcursor\t\t\t\t: pointer;\n";
    	html += "\t\tborder-radius\t\t: 5px;\n}\n\n";
     
    	html +=".button-on {\n";
    	html += "\t\tbackground-color\t: #3498db;\n}\n\n";
     
    	html +=".button-on:active {\n";
    	html += "\t\tbackground-color\t: #2980b9;\n}\n\n";
     
    	html +=".button-off {\n";
    	html += "\t\tbackground-color\t: #34495e;\n}\n\n";
     
    	html +=".button-off:active {\n";
    	html += "\t\tbackground-color\t: #2c3e50;\n}\n";
     
    	html += "p {\n";
    	html += "\t\tfont-size\t\t\t: 14px;\n";
    	html += "\t\tcolor\t\t\t\t: #888;\n";
    	html += "\t\tmargin-bottom\t\t: 15px;\n}\n\n";
     
    	html += "</style>\n</head>\n\n";
    	html += "<body>\n\t<h1>Test serveur web avec NodeMCU ESP32</h1>\n";
     
    	if (led_1_state)
    			html += "\t<p>Led 1</p><a class=\"button button-on\"  href=\"/led1off\">ON</a>\n";
    	else	html += "\t<p>Led 1</p><a class=\"button button-off\" href=\"/led1on\">OFF</a>\n";
     
    	if (led_2_state)
    			html += "\t<p>Led 2</p><a class=\"button button-on\"  href=\"/led2off\">ON</a>\n";
    	else	html += "\t<p>Led 2</p><a class=\"button button-off\" href=\"/led2on\">OFF</a>\n";
     
    	html += "</body>\n</html>\n\n";
     
    	digitalWrite(led_1, led_1_state);
    	digitalWrite(led_2, led_2_state);
     
    	return html;
    }
     
    void handle_OnConnect()
    {
    	led_1_state = LOW;
    	led_2_state = LOW;
     
    	server.send(200, "text/html", SendHTML(led_1_state,led_2_state));
    }
     
    void handle_led1off()
    {
    	led_1_state = LOW;
     
    	server.send(200, "text/html", SendHTML(led_1_state,led_2_state));
    }
     
    void handle_led1on()
    {
    	led_1_state = HIGH;
     
    	server.send(200, "text/html", SendHTML(led_1_state,led_2_state));
    }
     
    void handle_led2off()
    {
    	led_2_state = LOW;
     
    	server.send(200, "text/html", SendHTML(led_1_state,led_2_state));
    }
     
    void handle_led2on()
    {
    	led_2_state = HIGH;
     
    	server.send(200, "text/html", SendHTML(led_1_state,led_2_state));
    }
     
    void handle_NotFound()
    {
    	led_1_state = LOW;
    	led_2_state = LOW;
     
    	digitalWrite(led_1, led_1_state);
    	digitalWrite(led_2, led_2_state);
     
    	server.send(404, "text/plain", "Not found");
    }
     
    /**********************************/
    /*                                */
    /*     Procédure de Démarrage     */
    /*                                */
    /**********************************/
     
    void setup()
    {
    	Serial.begin(115200);
    	delay(1000);
     
    	/*---------------------------------*/
    	/*     Initialisation des Leds     */
    	/*---------------------------------*/
     
    	pinMode(led_1, OUTPUT);
    	pinMode(led_2, OUTPUT);
     
    	digitalWrite(led_1, led_1_state);
    	digitalWrite(led_2, led_2_state);
     
    	/*------------------------------*/
    	/*     Connexion au routeur     */
    	/*------------------------------*/
     
    	WiFi.persistent(false);
    	WiFi.begin(ssid,pwd);
     
    	Serial.print("Tentative de connexion ");
     
    	while (WiFi.status() != WL_CONNECTED)
    	{
    		delay(100);
    		Serial.print(".");
    	}
    	Serial.println();
     
    	Serial.println("Connexion WiFi effectuée !");
     
    	Serial.print("SSID : ");
    	Serial.println(ssid);
     
    	Serial.print("Adresse IP : ");
    	Serial.println(WiFi.localIP());
     
    	/*-----------------------------*/
    	/*     Gestion des Handles     */
    	/*-----------------------------*/
     
    	server.on("/",        handle_OnConnect);
    	server.on("/led1on",  handle_led1on);
    	server.on("/led1off", handle_led1off);
    	server.on("/led2on",  handle_led2on);
    	server.on("/led2off", handle_led2off);
    	server.onNotFound(    handle_NotFound);
     
    	server.begin();
    }
     
    /*******************************/
    /*                             */
    /*     Procédure Itérative     */
    /*                             */
    /*******************************/
     
    void loop()
    {
    	server.handleClient();
    }

    Le SSID et le mot de passe est celui de votre routeur.
    J'ai bien entendu repris l'adresse MAC de l'ESP32 que j'ai déclaré dans le DHCP (pour avoir une adresse fixe) et dans le DNS (pour avoir un nom de site).

    Tous les "\n" et "\t" que j'ai mis dans la partie "<style>", c'est juste pour une question de lisibilité quand je consulte la page web chargée.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  3. #3
    Responsable Arduino et Systèmes Embarqués

    Salut,

    Citation Envoyé par Artemus24 Voir le message
    1) le type de la carte dans l'Arduino IDE est le "NodeMCU-32S" et non le "ESP32 Dev Module" comme c'est indiqué.
    La preuve est que l'exemple : "01.Basics" / "Blink" ne fonctionne pas avec le "ESP32 Dev Module".
    Cela provoque une erreur à la compilation.
    Il y a beaucoup de constructeurs qui proposent des cartes à base d'ESP32. Si la référence de la carte est proposée dans l'EDI Arduino, on la choisit. Si elle n'y est pas, on prend la carte générique "ESP32 Dev Module", et on tente sa chance

    Citation Envoyé par Artemus24 Voir le message
    2) je ne comprenais pas pourquoi, j'avais toujours une erreur de communication entre mon ordinateur Windows et le NodeMCU ESP32.
    J'ai mis du temps à comprendre que je devais appuyer sur le bouton de droite (boot) pour accepter l'envoi de l'exécutable.
    Je croyais que cela se faisait automatiquement (???).
    D'ailleurs, je ne vois pas trop l'intérêt d'avoir installé un bouton pour dire que l'on accepte de "Téléverser" un exécutable ou pas.

    Est-ce la même chose sur l'arduino ?
    Pour téléverser le binaire, il faut commencer par faire un "reset" de l'ESP. Normalement, ça peut se faire automatiquement via des signaux de contrôle par le port USB. Mais parfois, le câblage n'est pas complet entre le contrôleur USB-série de la carte et l'ESP32, et il faut alors préparer l'ESP manuellement avec ce bouton.
    ça dépend donc des kits, et c'est un problème hardware. Les devKits officiels d'Espressif n'ont pas ce problème.

    Bravo pour ton premier programme serveur

    Si on veut aller plus loin, on utilisera un système de fichiers comme littleFS ou SPIFFS pour stocker les fichiers html, js, les images, etc dans une partie de la mémoire Flash.
    J'aime bien la bibliothèque ESPASyncWebServer avec sa gestion asynchrone. Elle est compatible avec le système de fichiers SPIFFS et comprend un mini-moteur de template pour éviter les concaténations de String dans le code.

    On s'amuse bien avec ces bestioles

  4. #4
    Expert éminent sénior
    Salut f-leb.

    Le sketch n'est pas de moi.
    Je me suis inspiré de ce que j'ai trouvé dans les exemples de l'Arduino IDE, ainsi que du lien ci-après (le second sketch):
    --> https://lastminuteengineers.com/crea...r-arduino-ide/

    Quelques remarques et questions :

    1) l'encodage des sketchs se fait en utf-8.
    Comme j'ai l'habitude d'encoder en windows-1252, ça surprend.

    2) j'ai compris l'utilité du bouton "boot" et du bouton "en".
    Mais comment remettre le ESP32 dans son état d'origine ?
    Je suppose que je dois téléverser le sketch qui s'affiche quand je fais nouveau, c'est-à-dire quand les deux fonctions (setup et loop) sont vides.

    3) je n'ai pas trouvé l'endroit où se trouve l'application Arduino IDE dans windows 10.
    Il a été chargé à partir de "microsoft store" et est présent dans "applications.
    Pourquoi cette question ? Parce que je désire décompression un fichier et de le ranger dans le répertoire "outils".

    4) à ma disposition, il y a deux répertoires qui se trouvent dans "i:/documents", sous les noms :
    --> Arduino
    --> ArduinoData

    J'ai pu déplacer celui nommé "Arduino", mais pas l'autre. Comment ai-je procédé ?
    En passant par l'onglet "préférences" où je peux modifier le chemin d'accès vers le répertoire "Arduino".

    Comment faire pour celui qui se nomme "ArduinoData" ?

    Je n'ai rien trouvé dans la base des registres.

    5) qu'est-ce que ArduinoData ?
    Il semblerait que cela soit ce que je cherche dans le §3).
    Mais comment se fait-il que cela ne soit pas comme dans les exemples que j'ai trouvé ?
    L'arbrescence n'est pas la même (je ne parle pas, bien sûr de la racine).

    6) Dans les recommendations de Gotronic, il est dit de récupérer "official ESP32 library" qui se trouve dans github :
    --> https://github.com/espressif/arduino-esp32

    Voici ce qui est dit, en anglais (of course) :
    --> Unpack the contents of the archive into the "hardware" folder of your Arduino folder ("C:\Users\[your username]\Documents\Arduino\hardware").

    Chez moi, le chemin est "i:\Documments\ArduinoData\packages\esp32\hardware".
    J'ai placé le répertoire décompressé "arduino-esp32-master", dans le répertoire "hardware".
    J'ai redémarré Arduino IDE, mais je ne vois aucun modification de la présence de cette bibliothèque.

    Comme je ne suis pas sûr du tout de comment faut-il faire, je demande ton aide.

    7) hormis que le ESP32 est un concurrent de l'Arduino, à quoi peut-il servir ?
    Il possède le Wifi, ainsi que le bluetooth, et a priori, il est destiné à intervenir en tant que IOT.
    C'est dans l'usage de la domotique que ce composant m'intéresse, à savoir consulter et piloter à distance.
    Peux-tu détailler ce à quoi il est en général destiné (ou bieen un lien) ?

    8) je reviendrais un peu plus tard sur le document html et css que l'on peut charger en tant que fichier paramétrable dans le ESP32.

    9) le NodeMCU ESP32 de joy-it, est-il l'officiel de chez espressif ?
    Je veux dire est-il totalement compatible ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  5. #5
    Expert éminent sénior
    Salut f-leb.

    Quel bordel !!!

    J'ai résolu le §3) et §8).
    Pour le §6) je pense que c'est la bibliothèque de nom "ESP32 espressif". Comme je la charge par l'intermédiaire de l'Arduino IDE, je n'ai pas besoin de le faire comme l'indique GoTronic.

    Il ne faut pas installer "Arduino IDE" version "Windows app Requires Win 8.1 or 10". Pourquoi ?
    Parce que cette version passe par Microsoft Store, et dans windows 10, je n'ai pas les autorisations pour venir bidouiller dans le répertoire "Arduino IDE".

    Il faut prendre la version "Windows ZIP file for non admin install".
    Télécharger puis décompresser le fichier ".zip" et enfin l'installer dans "c:/Program Files" (la version 64 bits).
    Et là, j'ai les autorisations !

    Et du coup, j'ai pu installer les bibliothèques suivantes :
    --> AsyncTCP
    --> ESPAsyncWebServer

    ainsi que de l'outil :
    --> ESP32FS-1.0
    que j'ai mis dans le répertoire "C:\Program Files\arduino-1.8.13\tools\ESP32FS\tool\esp32fs.jar".
    Maintenant, j'ai bien la ligne "ESP32 Sketch Data Upload" qui apparait dans "Arduino IDE/outils".

    Pour le deuxième test, celui avec le SPIFFS, Je me suis inspiré de ce lien :
    --> https://randomnerdtutorials.com/esp3...h-file-system/

    Ca fonctionne !!!

    Je donnerai le sketch quand j'aurai fini mes tests.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  6. #6
    Expert éminent sénior
    Salut à tous.

    Comme promis, voici mon deuxième sketch :
    Code arduino :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    /****************************************************/
    /*                                                  */
    /*     Serveur Web avec gestion de deux boutons     */
    /*                                                  */
    /****************************************************/
     
    #include <WiFi.h>
    #include "ESPAsyncWebServer.h"
    #include "SPIFFS.h"
     
    /**************************************/
    /*                                    */
    /*     Déclaration des Constantes     */
    /*                                    */
    /**************************************/
     
    const char		*ssid			= "mon_ssid";
    const char		*pwd			= "mon_mot_de_passe";
     
    const int		led_1			= 26;						/* GPIO 26 */
    const int		led_2			= 27;						/* GPIO 27 */
     
    /*************************************/
    /*                                   */
    /*     Déclaration des Variables     */
    /*                                   */
    /*************************************/
     
    bool			led_1_state;
    bool			led_2_state;
     
    String			var1, var2, var3;
    String			var4, var5, var6;
     
    AsyncWebServer	server(80);									/* Port 80 */
     
    /*************************************/
    /*                                   */
    /*     Déclaration des Fonctions     */
    /*                                   */
    /*************************************/
     
    String processor(const String &var)
    {
    	if (var == "VAR1")	return var1;
    	if (var == "VAR2")	return var2;
    	if (var == "VAR3")	return var3;
    	if (var == "VAR4")	return var4;
    	if (var == "VAR5")	return var5;
    	if (var == "VAR6")	return var6;
     
    	return String();
    }
     
    void handle_OnConnect(AsyncWebServerRequest *request)
    {
    	led_1_state = LOW;
    	led_2_state = LOW;
     
    	digitalWrite(led_1, led_1_state);
    	digitalWrite(led_2, led_2_state);
     
    	var1 = "button-on";
    	var2 = "/led1on";
    	var3 = "ON";
     
    	var4 = "button-on";
    	var5 = "/led2on";
    	var6 = "ON";
     
    	request->send(SPIFFS, "/index.html", String(), false, processor);
    }
     
    void handle_led1off(AsyncWebServerRequest *request)
    {
    	led_1_state = LOW;
     
    	digitalWrite(led_1, led_1_state);
     
    	var1 = "button-on";
    	var2 = "/led1on";
    	var3 = "ON";
     
    	request->send(SPIFFS, "/index.html", String(), false, processor);
    }
     
    void handle_led1on(AsyncWebServerRequest *request)
    {
    	led_1_state = HIGH;
     
    	digitalWrite(led_1, led_1_state);
     
    	var1 = "button-off";
    	var2 = "/led1off";
    	var3 = "OFF";
     
    	request->send(SPIFFS, "/index.html", String(), false, processor);
    }
     
    void handle_led2off(AsyncWebServerRequest *request)
    {
    	led_2_state = LOW;
     
    	digitalWrite(led_2, led_2_state);
     
    	var4 = "button-on";
    	var5 = "/led2on";
    	var6 = "ON";
     
    	request->send(SPIFFS, "/index.html", String(), false, processor);
    }
     
    void handle_led2on(AsyncWebServerRequest *request)
    {
    	led_2_state = HIGH;
     
    	digitalWrite(led_2, led_2_state);
     
    	var4 = "button-off";
    	var5 = "/led2off";
    	var6 = "OFF";
     
    	request->send(SPIFFS, "/index.html", String(), false, processor);
    }
     
    void handle_NotFound(AsyncWebServerRequest *request)
    {
    	led_1_state = LOW;
    	led_2_state = LOW;
     
    	digitalWrite(led_1, led_1_state);
    	digitalWrite(led_2, led_2_state);
     
    	request->send(404, "text/plain", "Not found");
    }
     
    /**********************************/
    /*                                */
    /*     Procédure de Démarrage     */
    /*                                */
    /**********************************/
     
    void setup()
    {
    	Serial.begin(115200);
    	delay(1000);
     
    	/*---------------------------------*/
    	/*     Initialisation des Leds     */
    	/*---------------------------------*/
     
    	pinMode(led_1, OUTPUT);
    	pinMode(led_2, OUTPUT);
     
    	digitalWrite(led_1, led_1_state);
    	digitalWrite(led_2, led_2_state);
     
    	/*-------------------------*/
    	/*     Gestion "SPIFFS     */
    	/*-------------------------*/
     
    	if(!SPIFFS.begin(true))
    	{
    		Serial.println("Erreur lors du montage \"SPIFFS\"");
    		return;
    	}
     
    	/*------------------------------*/
    	/*     Connexion au routeur     */
    	/*------------------------------*/
     
    	WiFi.begin(ssid,pwd);
     
    	Serial.print("Tentative de connexion ");
     
    	while (WiFi.status() != WL_CONNECTED)
    	{
    		delay(100);
    		Serial.print(".");
    	}
    	Serial.println();
     
    	Serial.println("Connexion WiFi effectuée !");
     
    	Serial.print("SSID : ");
    	Serial.println(ssid);
     
    	Serial.print("Adresse IP : ");
    	Serial.println(WiFi.localIP());
     
    	/*--------------------------------*/
    	/*     Référence des fichiers     */
    	/*--------------------------------*/
     
    	server.on("/styles.css", HTTP_GET, [](AsyncWebServerRequest *request){request->send(SPIFFS, "/styles.css", "text/css");});
     
    	/*-----------------------------*/
    	/*     Gestion des Handles     */
    	/*-----------------------------*/
     
    	server.on("/",           HTTP_GET, [](AsyncWebServerRequest *request){handle_OnConnect(request);});
    	server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){handle_OnConnect(request);});
     
    	server.on("/led1on",     HTTP_GET, [](AsyncWebServerRequest *request){handle_led1on(request);});
    	server.on("/led1off",    HTTP_GET, [](AsyncWebServerRequest *request){handle_led1off(request);});
    	server.on("/led2on",     HTTP_GET, [](AsyncWebServerRequest *request){handle_led2on(request);});
    	server.on("/led2off",    HTTP_GET, [](AsyncWebServerRequest *request){handle_led2off(request);});
     
    	server.onNotFound(handle_NotFound);
     
    	/*------------------------------*/
    	/*     Lancement du Serveur     */
    	/*------------------------------*/
     
    	server.begin();
    }
     
    /*******************************/
    /*                             */
    /*     Procédure Itérative     */
    /*                             */
    /*******************************/
     
    void loop()
    {
    }

    Ainsi que la feuille de styles :
    Code css :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    html {
    	font-family			: Helvetica;
    	display				: inline-block;
    	margin				: 0px auto;
    	text-align			: center;
    }
     
    body {
    	margin-top			: 50px;
    }
     
    h1{
    	color				: #0F3376;
    	margin				: 50px auto 30px;
    }
     
    p {
    	font-size			: 14px;
    	color				: #888;
    	margin-bottom			: 15px;
    }
     
    .button {
    	display				: inline-block;
    	background-color		: #008CBA;
    	width				: 80px;
    	border				: none;
    	border-radius			: 4px;
    	color				: white;
    	padding				: 16px 40px;
    	text-decoration			: none;
    	font-size			: 30px;
    	margin				: 0px auto 40px;
    	cursor				: pointer;
    	border-radius			: 5px;
    }
     
    .button-on {
    	background-color		: #3498db;
    }
     
    .button-on:active {
    	background-color		: #2980b9;
    }
     
    .button-off {
    	background-color		: #34495e;
    }
     
    .button-off:active {
    	background-color		: #2c3e50;
    }

    Et du document html :
    Code html :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>Leds</title>
    		<meta name="viewport" content="width=device-width, initial-scale=1">
    		<link rel="icon" href="data:,">
    		<link rel="stylesheet" type="text/css" href="styles.css">
    	</head>
     
    	<body>
    		<h1>Test serveur web avec NodeMCU ESP32</h1>
     
    		<p>Led 1</p><a class="button %VAR1%" href="%VAR2%">%VAR3%</a>
    		<p>Led 2</p><a class="button %VAR4%" href="%VAR5%">%VAR6%</a>
    	</body>
    </html>

    comme on peut le voir dans le sketch, j'ai utilisé une fonction (handle) pour gérer ce que je dois faire.
    L'astuce (ce qui est en rouge ci-après) est le passage du paramètre request qui se fait par adresse (sans l'*) alors que dans le "serveur-on", c'est un passage par référence (avec l'*).
    Code arduino :Sélectionner tout -Visualiser dans une fenêtre à part
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){handle_OnConnect(request);});


    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  7. #7
    Expert éminent sénior
    Salut à tous.

    Voici mon petit projet domotique.

    Sur une breadboard, j'ai installé :
    --> la led de l'ESP32.
    --> une led multicolore (rouge, verte, bleue).
    --> un capteur de température DS18B20.
    --> la touche tactile.
    --> un relais.
    --> la date et l'heure.

    Le principe est fort simple, à partir d'une page web, on pilote la led multicolore, la led de l'ESP32 et le relais.
    Mais grâce à AJAX, on affiche la date, l'heure, la température ambiante, ainsi que le résultat de la touche tactile.

    Voici mon code html de nom "index.html" :
    Code html :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>Projet</title>
    		<meta charset="utf-8">
    		<meta name="viewport" content="width=device-width, initial-scale=1">
    		<link rel="icon" type="image/png" href="icon.png">
    		<link rel="stylesheet" type="text/css" href="styles.css">
    		<script src="script.js"></script>
    	</head>
     
    	<body>
    		<h1>Test serveur web avec NodeMCU ESP32</h1>
     
    		<section>
    			<p>Led Multicolore :&nbsp;</p>
    			<div>
    				<p>Red   :&nbsp;</p><button id="1" class="%V01%">%V01%</button>
    				<p>Green :&nbsp;</p><button id="2" class="%V02%">%V02%</button>
    				<p>Blue  :&nbsp;</p><button id="3" class="%V03%">%V03%</button>
    			</div>
    		</section>
     
    		<section>
    			<p>Led ESP32 :&nbsp;</p>
    			<div>
    				<button id="4" class="%V04%">%V04%</button>
    			</div>
    		</section>
     
    		<section>
    			<p>Date :&nbsp;</p>
    			<div id="date">%V06%</div>
    		</section>
     
    		<section>
    			<p>Heure :&nbsp;</p>
    			<div id="time">%V07%</div>
    		</section>
     
    		<section>
    			<p>Température :&nbsp;</p>
    			<div id="temp">%V08%</div>
    		</section>
     
    		<section>
    			<p>Touche sensitive :&nbsp;</p>
    			<div id="tact">%V09%</div>
    		</section>
     
    		<section>
    			<p>Relais :&nbsp;</p>
    			<div>
    				<button id="5" class="%V05%">%V05%</button>
    			</div>
    		</section>
    	</body>
    </html>

    J'utilise des variables dans ce documents HTML : V01 ... V09.

    La feuille de styles de nom "styles.css" :
    Code css :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    * {
    		margin			: 0px auto;
    		padding			: 0px;
    		border			: none;
    }
     
    html {
    		background-color	: maroon;
    		margin			: 25px 0;
    		text-align			: center;
    		font-family			: Helvetica;
    }
     
    body {
    		width			: 650px;
    }
     
    h1 {
    		background-color	: silver;
    		margin-bottom		: 25px;
    		padding			: 5px;
    }
     
    section {
    		background-color	: silver;
    		font-size			: 20px;
    		width			: 320px;
    		color				: black;
    		padding			: 5px 0px;
    		margin			: 10px auto;
    }
     
    section p {
    		display			: table-cell;
    		width			: 170px;
    		text-align			: right;
    		vertical-align		: middle;
    }
     
    section div {
    		display			: table-cell;
    		width			: 150px;
    		padding			: 0px;
    }
     
    section div p {
    		display			: inline-block;
    		width			: 75px;
    }
     
    section div button {
    		display			: inline-block;
    		width			: 70px;
    		background-color	: #008CBA;
    		color				: white;
    		cursor			: pointer;
    		border			: none;
    		border-radius		: 25px;
    		text-decoration		: none;
    		font-size			: 20px;
    }
     
    section div button.on {
    		background-color	: #3498db;
    }
     
    section div button.on:hover {
    		background-color	: red;
    }
     
    section div button.on:active {
    		background-color	: #2980b9;
    }
     
    section div button.off {
    		background-color	: #34495e;
    }
     
    section div button.off:hover {
    		background-color	: red;
    }
     
    section div button.off:active {
    		background-color	: #2c3e50;
    }

    Comme je ne suis pas un spécialiste web, on peut certainement améliorer la feuille de styles.

    Le code javascript qui permet de réceptionner la trame AJAX, de nom "script.js" :
    Code js :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    function getData(reqt)
    {
    	var ObjetXHR = new XMLHttpRequest();
     
    	ObjetXHR.onreadystatechange = function()
    	{
    		if (this.readyState == 4  && this.status == 200)
    		{
    			var obj = JSON.parse(this.response);
     
    			document.getElementById("1").innerHTML = obj.bt01;
    			document.getElementById("2").innerHTML = obj.bt02;
    			document.getElementById("3").innerHTML = obj.bt03;
    			document.getElementById("4").innerHTML = obj.bt04;
    			document.getElementById("5").innerHTML = obj.bt05;
     
    			document.getElementById("1").setAttribute("class",obj.bt01);
    			document.getElementById("2").setAttribute("class",obj.bt02);
    			document.getElementById("3").setAttribute("class",obj.bt03);
    			document.getElementById("4").setAttribute("class",obj.bt04);
    			document.getElementById("5").setAttribute("class",obj.bt05);
     
    			document.getElementById("temp").innerHTML = obj.temp;
    			document.getElementById("tact").innerHTML = obj.tact;
    			document.getElementById("date").innerHTML = obj.date;
    			document.getElementById("time").innerHTML = obj.time;
    		}
    	}
     
    	ObjetXHR.open("GET", reqt , true);
    	ObjetXHR.send(null);
    }
     
     
    window.onload = function()
    {
    	document.getElementsByTagName("button")[0].onclick = function ()	{	getData("ajax?val="+this.id);	}
    	document.getElementsByTagName("button")[1].onclick = function ()	{	getData("ajax?val="+this.id);	}
    	document.getElementsByTagName("button")[2].onclick = function ()	{	getData("ajax?val="+this.id);	}
    	document.getElementsByTagName("button")[3].onclick = function ()	{	getData("ajax?val="+this.id);	}
    	document.getElementsByTagName("button")[4].onclick = function ()	{	getData("ajax?val="+this.id);	}
     
    	setInterval(function () {getData("ajax");}, 500);
    }

    Le rafraîchissement se fait toutes les 1/2 secondes. Inutile de complexifier l'aspect AJAX.
    Si vous utilisez deux pages web en même temps, et que dans la première page, vous cliquez sur le bouton de la led rouge, dans la seconde page web, le bouton aura changé automatiquement.

    Et voici mon sketch :
    Code arduino :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    /****************************************************/
    /*                                                  */
    /*       Serveur Web pour pilotage domotique        */
    /*                                                  */
    /*--------------------------------------------------*/
    /*                                                  */
    /*     La feuille de styles et le document HTML     */
    /*                sont externalisées !              */
    /*                                                  */
    /****************************************************/
     
    #include <time.h>
     
    #include <WiFi.h>
    #include <ESPAsyncWebServer.h>
    #include <SPIFFS.h>
     
    #include <OneWire.h>
    #include <DallasTemperature.h>
     
    #define	TEMPERATURE_PRECISION		12
     
    #include "L:/Arduino/MyLibrairies/param.h"
     
    /**************************************/
    /*                                    */
    /*     Déclaration des Constantes     */
    /*                                    */
    /**************************************/
     
    const int		_led_1			= 27;				/* GPIO 27 */
    const int		_led_2			= 26;				/* GPIO 26 */
    const int		_led_3			= 25;				/* GPIO 25 */
    const int		_led_4			= 2;				/* GPIO  2 */
     
    const int		_relay			= 19;				/* GPIO 19 */
    const int		_touch			= 4;				/* GPIO  4 */
     
    const int		_oneWireBus		= 33;				/* GPIO 33 */
     
    /*************************************/
    /*                                   */
    /*     Déclaration des Variables     */
    /*                                   */
    /*************************************/
     
    String			_v01, _v02, _v03, _v04, _v05;
    String			_v06, _v07, _v08, _v09;
     
    byte			_addr[8];
     
     
    AsyncWebServer			_server(80);				/* Port 80 */
    OneWire					_device(_oneWireBus);
    DallasTemperature		_sensor(&_device);
     
    /*************************************/
    /*                                   */
    /*     Déclaration des Fonctions     */
    /*                                   */
    /*************************************/
     
    /*==========================================================*/
    /*     Affichage de l'adresse du capteur de température     */
    /*==========================================================*/
     
    void printDeviceAddress(byte _addr[8])
    {
    	char	_tab[3];
     
    	Serial.print("Adresse du capteur de température : ");
     
    	for (byte _i=0; _i<8; _i++)
    	{
    		sprintf(_tab, "%02X", (int)_addr[_i]);
    		Serial.print(_tab);
     
    		if (_i<7)		Serial.print(':');
    	}
     
    	Serial.println();
    }
     
    /*==================================================*/
    /*     Initialisation du capteur de température     */
    /*==================================================*/
     
    void initSensor(void)
    {
    	Serial.println();
     
    	_device.search(_addr);
    	printDeviceAddress(_addr);
     
    	if (OneWire::crc8(_addr, 7) != _addr[7])
    	{
    		Serial.println("Le CRC (code de redondance cyclique) n'est pas valide !");
    		return;
    	}
     
    	switch (_addr[0])
    	{
    		case 0x10:		Serial.println("Capteur : DS18S20 !");
    						break;
     
    		case 0x22:		Serial.println("Capteur : DS1822 !");
    						break;
     
    		case 0x28:		Serial.println("Capteur : DS18B20 !");
    						break;
     
    		default:		Serial.println("ce n'est pas un capteur de température de la famille des \"DS18x20\" !");
    						return;
    						break;
    	}
     
    	_sensor.setResolution(_addr, TEMPERATURE_PRECISION);
     
    	Serial.print("Résolution: ");
    	Serial.print(_sensor.getResolution(_addr), DEC); 
    	Serial.println("\n");
     
    	_device.reset();
    }
     
    /*=============================*/
    /*     Gestion des boutons     */
    /*-----------------------------*/
    /*     LOW  = 0  Eteint        */
    /*     HIGH = 1  Allumée       */
    /*=============================*/
     
    void boutons(const short _val)
    {
    	switch(_val)
    	{
    		/*-------------------*/
    		/*     Led Rouge     */
    		/*-------------------*/
     
    		case 1:
    			switch(digitalRead(_led_1))
    			{
    				case LOW:
    					_v01 = "on";
    					digitalWrite(_led_1, HIGH);
    					break;
     
    				case HIGH:
    					_v01 = "off";
    					digitalWrite(_led_1, LOW);
    					break;
    			}
    			break;
     
    		/*-------------------*/
    		/*     Led Verte     */
    		/*-------------------*/
     
    		case 2:
    			switch(digitalRead(_led_2))
    			{
    				case LOW:
    					_v02 = "on";
    					digitalWrite(_led_2, HIGH);
    					break;
     
    				case HIGH:
    					_v02 = "off";
    					digitalWrite(_led_2, LOW);
    					break;
    			}
    			break;
     
    		/*-------------------*/
    		/*     Led Bleue     */
    		/*-------------------*/
     
    		case 3:
    			switch(digitalRead(_led_3))
    			{
    				case LOW:
    					_v03 = "on";
    					digitalWrite(_led_3, HIGH);
    					break;
     
    				case HIGH:
    					_v03 = "off";
    					digitalWrite(_led_3, LOW);
    					break;
    			}
    			break;
     
    		/*------------------------*/
    		/*     Led de l'ESP32     */
    		/*------------------------*/
     
    		case 4:
    			switch(digitalRead(_led_4))
    			{
    				case LOW:
    					_v04 = "on";
    					digitalWrite(_led_4, HIGH);
    					break;
     
    				case HIGH:
    					_v04 = "off";
    					digitalWrite(_led_4, LOW);
    					break;
    			}
    			break;
     
    		/*----------------*/
    		/*     relais     */
    		/*----------------*/
     
    		case 5:
    			switch(digitalRead(_relay))
    			{
    				case LOW:
    					_v05 = "on";
    					digitalWrite(_relay, HIGH);
    					break;
     
    				case HIGH:
    					_v05 = "off";
    					digitalWrite(_relay, LOW);
    					break;
    			}
    			break;
     
    		/*-----------------------*/
    		/*     Remise à zéro     */
    		/*-----------------------*/
     
    		case 9:
    			digitalWrite(_led_1, LOW);
    			digitalWrite(_led_2, LOW);
    			digitalWrite(_led_3, LOW);
    			digitalWrite(_led_4, LOW);
    			digitalWrite(_relay, LOW);
     
    			_v01 = "off";
    			_v02 = "off";
    			_v03 = "off";
    			_v04 = "off";
    			_v05 = "off";
    			break;
    	}
    }
     
    /*===========================*/
    /*     Gestion des Infos     */
    /*===========================*/
     
    void infos()
    {
    	char		_data[20];
    	byte		_i;
    	int			_val;
    	time_t		_now;
    	struct tm	*_p;
     
    	/*------------------------------------------*/
    	/*     Lecture de la date et de l'heure     */
    	/*------------------------------------------*/
     
    	time(&_now);
    	_p = localtime(&_now);
     
    	sprintf(_data, "%4d-%02d-%02d", (_p->tm_year + 1900), (_p->tm_mon + 1), _p->tm_mday);
    	_v06 = String(_data);
     
    	sprintf(_data, "%02d:%02d:%02d", _p->tm_hour, _p->tm_min, _p->tm_sec);
    	_v07 = String(_data);
     
    	/*-----------------------------------*/
    	/*     Lecture de la température     */
    	/*-----------------------------------*/
     
    	_sensor.requestTemperatures();
    	_v08 = String(_sensor.getTempC(_addr)) + "°C";
     
    	/*--------------------------------------*/
    	/*     Lecture de la touche tactile     */
    	/*--------------------------------------*/
     
    	_val=0;
    	for (_i=0; _i<100; _i++)
    		_val += touchRead(_touch);
     
    	_val /= 100;
     
    	if (_val < 30)		_v09 = "Actif";
    	else				_v09 = "Inactif";
    }
     
    /*====================================*/
    /*     Gestion des variables HTML     */
    /*====================================*/
     
    String processor(const String &var)
    {
    	if (var == "V01")	return _v01;
    	if (var == "V02")	return _v02;
    	if (var == "V03")	return _v03;
     
    	if (var == "V04")	return _v04;
    	if (var == "V05")	return _v05;
    	if (var == "V06")	return _v06;
     
    	if (var == "V07")	return _v07;
    	if (var == "V08")	return _v08;
    	if (var == "V09")	return _v09;
     
    	return String();
    }
     
    /*=============================*/
    /*     Gestion des Handles     */
    /*=============================*/
     
    void handle_OnConnect(AsyncWebServerRequest *request)
    {
    	boutons(9);
    	infos();
    	request->send(SPIFFS, "/index.html", String(), false, processor);
    }
     
    void handle_ajax(AsyncWebServerRequest *request)
    {
    	short _val;
     
    	if (request->hasParam("val"))
    	{
    		AsyncWebParameter *p = request->getParam("val");
    		_val = p->value().toInt();
    		boutons(_val);
    	}
    	else
    	{
    		infos();
    	}
     
    	request->send(200, "application/json", "{\"bt01\":\"" + _v01 + "\", \"bt02\":\"" + _v02 + "\", \"bt03\":\"" + _v03 + "\", \"bt04\":\"" + _v04 + "\", \"bt05\":\"" + _v05 + "\", \"date\":\"" + _v06 + "\", \"time\":\"" + _v07 + "\", \"temp\":\"" + _v08 + "\", \"tact\":\"" + _v09 + "\"}");
    }
     
    void handle_NotFound(AsyncWebServerRequest *request)
    {
    	boutons(9);
    	request->send(404, "text/plain", "Not found");
    }
     
    /**********************************/
    /*                                */
    /*     Procédure de Démarrage     */
    /*                                */
    /**********************************/
     
    void setup()
    {
    	Serial.begin(115200);
    	delay(1000);
     
    	/*-----------------------------------------*/
    	/*     Initialisation des Leds & Relais    */
    	/*-----------------------------------------*/
     
    	pinMode(_led_1, OUTPUT);
    	pinMode(_led_2, OUTPUT);
    	pinMode(_led_3, OUTPUT);
    	pinMode(_led_4, OUTPUT);
    	pinMode(_relay, OUTPUT);
     
    	digitalWrite(_led_1, LOW);
    	digitalWrite(_led_2, LOW);
    	digitalWrite(_led_3, LOW);
    	digitalWrite(_led_4, LOW);
    	digitalWrite(_relay, LOW);
     
    	boutons(9);
     
    	/*------------------------------------------*/
    	/*     Initialisation de la Température     */
    	/*------------------------------------------*/
     
    	_sensor.begin();
     
    	initSensor();
     
    	/*-------------------------*/
    	/*     Gestion "SPIFFS     */
    	/*-------------------------*/
     
    	if(!SPIFFS.begin(true))
    	{
    		Serial.println("Erreur lors du montage \"SPIFFS\"");
    		return;
    	}
     
    	/*------------------------------*/
    	/*     Connexion au routeur     */
    	/*------------------------------*/
     
    	WiFi.mode(WIFI_STA);
    	WiFi.begin(ssid,pwd);
     
    	Serial.print("Tentative de connexion ");
     
    	while (WiFi.status() != WL_CONNECTED)
    	{
    		delay(100);
    		Serial.print(".");
    	}
    	Serial.println();
     
    	Serial.println("Connexion WiFi effectuée !");
     
    	WiFi.enableIpV6();
    	delay(2000);
     
    	Serial.print("SSID : ");
    	Serial.println(ssid);
     
    	Serial.print("Adresse IPv6 : ");
    	Serial.println(WiFi.localIPv6());
     
    	Serial.print("Adresse IPv4 : ");
    	Serial.println(WiFi.localIP());
     
    	Serial.print("Masque de sous-réseau : ");
    	Serial.println(WiFi.subnetMask());
     
    	Serial.print("Paserelle : ");
    	Serial.println(WiFi.gatewayIP());
     
    	Serial.print("Adresse MAC : ");
    	Serial.println(WiFi.macAddress());
     
    	Serial.println();
     
    	/*---------------------------------------------------*/
    	/*     Configuration NTP (Network Time Protocol)     */
    	/*---------------------------------------------------*/
     
    	configTime(7200, 0, "fr.pool.ntp.org");
     
    	Serial.print("Tentative de connexion au serveur NTP ");
     
    	while (time(nullptr) <= 100000)
    	{
    		Serial.print(".");
    		delay(1000);
    	}
     
    	Serial.println("\n");
     
    	/*--------------------------------*/
    	/*     Référence des fichiers     */
    	/*--------------------------------*/
     
    	_server.on("/styles.css", HTTP_GET, [](AsyncWebServerRequest *request){request->send(SPIFFS, "/styles.css", "text/css");});
    	_server.on("/script.js",  HTTP_GET, [](AsyncWebServerRequest *request){request->send(SPIFFS, "/script.js",  "application/javascript");});
    	_server.on("/icon.png",   HTTP_GET, [](AsyncWebServerRequest *request){request->send(SPIFFS, "/icon.png",   "image/png");});
     
    	/*-----------------------------*/
    	/*     Gestion des Handles     */
    	/*-----------------------------*/
     
    	_server.on("/",           HTTP_GET, [](AsyncWebServerRequest *request){handle_OnConnect(request);});
    	_server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){handle_OnConnect(request);});
    	_server.on("/ajax",       HTTP_GET, [](AsyncWebServerRequest *request){handle_ajax(request);});
    	_server.onNotFound(handle_NotFound);
     
    	/*------------------------------*/
    	/*     Lancement du Serveur     */
    	/*------------------------------*/
     
    	_server.begin();
    }
     
    /*******************************/
    /*                             */
    /*     Procédure Itérative     */
    /*                             */
    /*******************************/
     
    void loop()
    {
    	infos();
     
    	Serial.print("Date : ");
    	Serial.print(_v06);
    	Serial.print("  ");
     
    	Serial.print("Heure : ");
    	Serial.print(_v07);
    	Serial.print("  ");
     
    	Serial.print("Température : ");
    	Serial.print(_v08);
    	Serial.print("  ");
     
    	Serial.print("Touche : ");
    	Serial.println(_v09);
     
    	delay(1000);
    }

    Je n'utilise pas les "#include" consacré à JSON car c'est totalement inutile de le faire.

    Dans la console, j'affiche la date du jour, ainsi que l'heure, la température et la touche tactile.

    EDIT : J'ai mis à jour mon projet avec la dernière version !

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  8. #8
    Expert éminent sénior
    Salut à tous.

    Un exemple de comment récupérer la date et l'heure NTP (Network Time Protocol) sans passer par la bibliothèque "NTPClient.h".
    Code arduino :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    /***************************************************************************/
    /*                                                                         */
    /*     Connexion WiFi & Récupération Heure NTP (Network Time Protocol)     */
    /*                                                                         */
    /***************************************************************************/
     
    #include <WiFi.h>
    #include <time.h>
    #include "L:/Arduino/MyLibrairies/param.h"
     
    /*************************************/
    /*                                   */
    /*     Déclaration des Variables     */
    /*                                   */
    /*************************************/
     
    void printLocalTime()
    {
    	time_t		now;
    	struct tm	*timeinfo;
     
    	time(&now);
    	timeinfo = localtime(&now);
     
    	Serial.println(timeinfo, "Date : %Y-%m-%d   Heure : %H:%M:%S");
    }
     
    /**********************************/
    /*                                */
    /*     Procédure de Démarrage     */
    /*                                */
    /**********************************/
     
    void setup()
    {
    	Serial.begin(115200);
    	delay(1000);
     
    	/*---------------------------*/
    	/*     Connexion Routeur     */
    	/*---------------------------*/
     
    	WiFi.mode(WIFI_STA);
    	WiFi.persistent(false);
    	WiFi.begin(ssid, pwd);
     
    	Serial.print("Tentative de connexion au routeur ");
     
    	while(WiFi.status() != WL_CONNECTED)
    	{
    		Serial.print(".");
    		delay(100);
    	}
    	Serial.println();
     
    	Serial.println("Connexion établie !");
    	Serial.print("Adresse IP : ");
    	Serial.print(WiFi.localIP());
     
    	Serial.println("\n");
     
    	/*---------------------------*/
    	/*     Configuration NTP     */
    	/*---------------------------*/
     
    	configTime(7200, 0, "fr.pool.ntp.org");
     
    	Serial.print("Tentative de connexion au serveur NTP ");
     
    	while (time(nullptr) <= 100000)
    	{
    		Serial.print(".");
    		delay(1000);
    	}
     
    	Serial.println("\n");
    	WiFi.disconnect(true);
    	WiFi.mode(WIFI_OFF);
     
    	delay(1000);
    }
     
    /*******************************/
    /*                             */
    /*     Procédure Itérative     */
    /*                             */
    /*******************************/
     
    void loop()
    {
    	printLocalTime();
    	delay(1000);
    }


    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  9. #9
    Responsable Arduino et Systèmes Embarqués

    Salut,

    Code c :Sélectionner tout -Visualiser dans une fenêtre à part
    #include "L:/Arduino/MyLibrairies/param.h"

    Que contient param.h ?

    A chaque appui sur un bouton ON/OFF, la page est rechargée. Pourquoi ne passes-tu pas aussi l'état des boutons dans la requête Ajax ?

    Plutôt que des url du type /led1on, /led2off, etc., je verrais mieux quelque chose comme /device?led=red&state=on, /device?led=green&state=off, etc. avec des paramètres dans l'url. Il y a des fonctions getParameters() et autres pour récupérer les valeurs des paramètres.

  10. #10
    Expert éminent sénior
    Salut f-leb.

    Citation Envoyé par f-leb
    Que contient param.h ?
    C'est la même idée que chez toi, mon SSID et mon PASSWORD. Je les ai externalisé afin d'avoir la même chose partout dans mes exemples.

    Citation Envoyé par f-leb
    Pourquoi ne passes-tu pas aussi l'état des boutons dans la requête Ajax ?
    J'ai suivi ta recommendation et j'ai modifié mon projet afin que tout ce qui est variable dans la page web soit géré en Ajax

    Si deux pages web sont ouvertes en même temps, quand on clique sur un bouton dans la première page, la mise à jour se fait automatiquement dans la seconde page
    De cette façon, je connais l'état de mes boutons à chaque instant !

    EDIT : j'ai mis à jour mon projet !

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  11. #11
    Responsable Arduino et Systèmes Embarqués

    J'ai testé, belle mise à jour

    Par contre, si tu rafraichis la page, tout se met à OFF ! Il faudrait lire l'état des sorties de l'ESP au chargement de la page pour mettre à jour l'état des boutons ON/OFF.

  12. #12
    Expert éminent sénior
    Salut f-leb.

    Citation Envoyé par f-leb
    Par contre, si tu rafraîchis la page, tout se met à OFF !
    Sais-tu faire la distinction entre un premier démarrage de la page et son rafraîchissement ?

    Et du coup, pourquoi rafraîchir la page puisque tout ce qui est variable est alimenté en AJAX ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  13. #13
    Expert éminent sénior
    Salut à tous.

    Comme je n'ai plus accès à mon message #7, je mets la dernière version de mon petit projet.
    Voici le document HTML :
    Code html :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>Projet</title>
    		<meta charset="utf-8">
    		<meta name="viewport" content="width=device-width, initial-scale=1">
    		<link rel="icon" type="image/png" href="icon.png">
    		<link rel="stylesheet" type="text/css" href="styles.css">
    		<script src="script.js"></script>
    	</head>
     
    	<body>
    		<h1>Test serveur web avec NodeMCU ESP32</h1>
     
    		<section>
    			<p>Led Multicolore :&nbsp;</p>
    			<div>
    				<p>Red   :&nbsp;</p><button id="1" class="%V01%">%V01%</button>
    				<p>Green :&nbsp;</p><button id="2" class="%V02%">%V02%</button>
    				<p>Blue  :&nbsp;</p><button id="3" class="%V03%">%V03%</button>
    			</div>
    		</section>
     
    		<section>
    			<p>Led ESP32 :&nbsp;</p>
    			<div>
    				<button id="4" class="%V04%">%V04%</button>
    			</div>
    		</section>
     
    		<section><p>Date :&nbsp;</p>			<span>%V06%</span></section>
    		<section><p>Heure :&nbsp;</p>			<span>%V07%</span></section>
    		<section><p>Température :&nbsp;</p>		<span>%V08%</span></section>
    		<section><p>Touche sensitive :&nbsp;</p>	<span>%V09%</span></section>
     
    		<section>
    			<p>Relais :&nbsp;</p>
    			<div>
    				<button id="5" class="%V05%">%V05%</button>
    			</div>
    		</section>
    	</body>
    </html>

    J'ai modifié l'ancienne balise "<p>" en la remplaçant par "<span>".
    Voici la feuille de styles :
    Code css :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    * {
    		margin				: 0px auto;
    		padding				: 0px;
    		border				: none;
    }
     
    html {
    		background-color	: maroon;
    		margin				: 25px 0;
    		text-align			: center;
    		font-family			: Helvetica;
    }
     
    body {
    		width				: 650px;
    }
     
    h1 {
    		background-color	: silver;
    		margin-bottom		: 25px;
    		padding				: 5px;
    }
     
    section {
    		background-color	: silver;
    		font-size			: 20px;
    		width				: 320px;
    		color				: black;
    		padding				: 5px 0px;
    		margin				: 10px auto;
    }
     
    section p {
    		display				: table-cell;
    		width				: 170px;
    		text-align			: right;
    		vertical-align		: middle;
    }
     
    section div {
    		display				: table-cell;
    		width				: 150px;
    		padding				: 0px;
    }
     
    section span {
    		display				:table-cell;
    }
     
    section div p {
    		display				:inline-block;
    		width				: 75px;
    }
     
    section div button {
    		display				: inline-block;
    		width				: 70px;
    		background-color	: #008CBA;
    		color				: white;
    		cursor				: pointer;
    		border				: none;
    		border-radius		: 25px;
    		text-decoration		: none;
    		font-size			: 20px;
    		text-transform		: uppercase;
    }
     
    section div button.on {
    		background-color	: #3498db;
    }
     
    section div button.on:hover {
    		background-color	: red;
    }
     
    section div button.on:active {
    		background-color	: #2980b9;
    }
     
    section div button.off {
    		background-color	: #34495e;
    }
     
    section div button.off:hover {
    		background-color	: red;
    }
     
    section div button.off:active {
    		background-color	: #2c3e50;
    }

    Voici le code Javascript. Au lieu de gérer une chaîne JSON avec des clefs différentes, j'ai préféré créer deux tableaux, l'un pour la balise "<button>" et l'autre pour la balise "<span>".
    Code javascript :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    function getData(reqt)
    {
    	var ObjetXHR = new XMLHttpRequest();
     
    	ObjetXHR.onreadystatechange = function()
    	{
    		if (this.readyState == 4  && this.status == 200)
    		{
    			var obj    = JSON.parse(this.response);
    			var nodeBt = document.getElementsByTagName("button");
    			var nodeSp = document.getElementsByTagName("span");
     
    			for (var i=0; i<nodeBt.length; i++)
    			{
    				nodeBt[i].innerHTML = obj.bt[i];
    				nodeBt[i].setAttribute("class",obj.bt[i]);
    			}
     
    			for (var i=0; i<nodeSp.length; i++)
    			{
    				nodeSp[i].innerHTML = obj.sp[i];
    				nodeSp[i].setAttribute("class",obj.sp[i]);
    			}
    		}
    	}
     
    	ObjetXHR.open("GET", reqt , true);
    	ObjetXHR.send(null);
    }
     
    window.onload = function()
    {
    	var node = document.getElementsByTagName("button");
     
    	for (var i=0; i<node.length; i++)
    		node[i].onclick = function () { getData("ajax?val="+this.id); }
     
    	setInterval(function () {getData("ajax");}, 500);
    }

    Et pour finir, le sketch où j'ai simplifié la chaîne JSON, et le passage de SPIFFS à LITTLEFS.
    Code c :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    /****************************************************/
    /*                                                  */
    /*       Serveur Web pour pilotage domotique        */
    /*                                                  */
    /*--------------------------------------------------*/
    /*                                                  */
    /*     La feuille de styles et le document HTML     */
    /*                sont externalisées !              */
    /*                                                  */
    /****************************************************/
     
    #include <time.h>
     
    #include <WiFi.h>
    #include <ESPAsyncWebServer.h>
    #include <LITTLEFS.h>
     
    #include <OneWire.h>
    #include <DallasTemperature.h>
     
    #define	TEMPERATURE_PRECISION		12
     
    #include "L:/Arduino/MyLibrairies/param.h"
     
     
    /**************************************/
    /*                                    */
    /*     Déclaration des Constantes     */
    /*                                    */
    /**************************************/
     
    const int		_led_1			= 27;				/* GPIO 27 */
    const int		_led_2			= 26;				/* GPIO 26 */
    const int		_led_3			= 25;				/* GPIO 25 */
    const int		_led_4			= 2;				/* GPIO  2 */
     
    const int		_relay			= 19;				/* GPIO 19 */
    const int		_touch			= 4;				/* GPIO  4 */
     
    const int		_oneWireBus		= 33;				/* GPIO 33 */
     
     
    /*************************************/
    /*                                   */
    /*     Déclaration des Variables     */
    /*                                   */
    /*************************************/
     
    String			_v01, _v02, _v03, _v04, _v05, _v06, _v07, _v08, _v09;
     
    byte			_addr[8];
     
     
    AsyncWebServer			_server(80);				/* Port 80 */
    OneWire					_device(_oneWireBus);
    DallasTemperature		_sensor(&_device);
     
     
    /*************************************/
    /*                                   */
    /*     Déclaration des Fonctions     */
    /*                                   */
    /*************************************/
     
     
    /*==========================================================*/
    /*     Affichage de l'adresse du capteur de température     */
    /*==========================================================*/
     
    void printDeviceAddress(byte _addr[8])
    {
    	char	_tab[3];
     
    	Serial.print("Adresse du capteur de température : ");
     
    	for (byte _i=0; _i<8; _i++)
    	{
    		sprintf(_tab, "%02X", (int)_addr[_i]);
    		Serial.print(_tab);
     
    		if (_i<7)		Serial.print(':');
    	}
     
    	Serial.println();
    }
     
     
    /*==================================================*/
    /*     Initialisation du capteur de température     */
    /*==================================================*/
     
    void initSensor(void)
    {
    	Serial.println();
     
    	_device.search(_addr);
    	printDeviceAddress(_addr);
     
    	if (OneWire::crc8(_addr, 7) != _addr[7])
    	{
    		Serial.println("Le CRC (code de redondance cyclique) n'est pas valide !");
    		return;
    	}
     
    	switch (_addr[0])
    	{
    		case 0x10:		Serial.println("Capteur : DS18S20 !");
    						break;
     
    		case 0x22:		Serial.println("Capteur : DS1822 !");
    						break;
     
    		case 0x28:		Serial.println("Capteur : DS18B20 !");
    						break;
     
    		default:		Serial.println("ce n'est pas un capteur de température de la famille des \"DS18x20\" !");
    						return;
    						break;
    	}
     
    	_sensor.setResolution(_addr, TEMPERATURE_PRECISION);
     
    	Serial.print("Résolution: ");
    	Serial.print(_sensor.getResolution(_addr), DEC); 
    	Serial.println("\n");
     
    	_device.reset();
    }
     
     
    /*=============================*/
    /*     Gestion des boutons     */
    /*-----------------------------*/
    /*     LOW  = 0  Eteint        */
    /*     HIGH = 1  Allumée       */
    /*=============================*/
     
    void bouton(const int _btn, String *_val, const int _action)
    {
    	switch(digitalRead(_btn))
    	{
    		case LOW:	if (_action == 1)		/* pression sur le bouton */
    					{
    							*_val = "on";
    							digitalWrite(_btn, HIGH);
    					}
    					else	*_val = "off";
    					break;
     
    		case HIGH:	if (_action == 1)		/* pression sur le bouton */
    					{
    							*_val = "off";
    							digitalWrite(_btn, LOW);
    					}
    					else	*_val = "on";
    					break;
    	}
    }
     
    void keys(const short _val)
    {
    	switch(_val)
    	{
    		/*-------------------*/
    		/*     Led Rouge     */
    		/*-------------------*/
     
    		case 1:		bouton(_led_1, &_v01, 1);
    					break;
     
    		/*-------------------*/
    		/*     Led Verte     */
    		/*-------------------*/
     
    		case 2:		bouton(_led_2, &_v02, 1);
    					break;
     
    		/*-------------------*/
    		/*     Led Bleue     */
    		/*-------------------*/
     
    		case 3:		bouton(_led_3, &_v03, 1);
    					break;
     
    		/*------------------------*/
    		/*     Led de l'ESP32     */
    		/*------------------------*/
     
    		case 4:		bouton(_led_4, &_v04, 1);
    					break;
     
    		/*----------------*/
    		/*     Relais     */
    		/*----------------*/
     
    		case 5:		bouton(_relay, &_v05, 1);
    					break;
     
    		/*--------------------------*/
    		/*     Rafraichissement     */
    		/*--------------------------*/
     
    		case 8:		bouton(_led_1, &_v01, 0);
    					bouton(_led_2, &_v02, 0);
    					bouton(_led_3, &_v03, 0);
    					bouton(_led_4, &_v04, 0);
    					bouton(_relay, &_v05, 0);
    					break;
     
    		/*-----------------------*/
    		/*     Remise à zéro     */
    		/*-----------------------*/
     
    		case 9:		digitalWrite(_led_1, LOW);
    					digitalWrite(_led_2, LOW);
    					digitalWrite(_led_3, LOW);
    					digitalWrite(_led_4, LOW);
    					digitalWrite(_relay, LOW);
     
    					_v01 = "off";
    					_v02 = "off";
    					_v03 = "off";
    					_v04 = "off";
    					_v05 = "off";
    					break;
    	}
    }
     
     
    /*==================================================*/
    /*     Gestion des Infos à transmettre par AJAX     */
    /*==================================================*/
     
    void infos()
    {
    	char		_data[20];
    	byte		_i;
    	int			_val;
    	time_t		_now;
    	struct tm	*_p;
     
    	/*------------------------------------------*/
    	/*     Lecture de la date et de l'heure     */
    	/*------------------------------------------*/
     
    	time(&_now);
    	_p = localtime(&_now);
     
    	sprintf(_data, "%4d-%02d-%02d", (_p->tm_year + 1900), (_p->tm_mon + 1), _p->tm_mday);
    	_v06 = String(_data);
     
    	sprintf(_data, "%02d:%02d:%02d", _p->tm_hour, _p->tm_min, _p->tm_sec);
    	_v07 = String(_data);
     
    	/*-----------------------------------*/
    	/*     Lecture de la température     */
    	/*-----------------------------------*/
     
    	_sensor.requestTemperatures();
    	_v08 = String(_sensor.getTempC(_addr)) + "°C";
     
    	/*--------------------------------------*/
    	/*     Lecture de la touche tactile     */
    	/*--------------------------------------*/
     
    	_val=0;
    	for (_i=0; _i<100; _i++)
    		_val += touchRead(_touch);
     
    	_val /= 100;
     
    	if (_val < 30)		_v09 = "Actif";
    	else				_v09 = "Inactif";
    }
     
     
    /*====================================*/
    /*     Gestion des variables HTML     */
    /*====================================*/
     
    String processor(const String &var)
    {
    	if (var == "V01")	return _v01;
    	if (var == "V02")	return _v02;
    	if (var == "V03")	return _v03;
     
    	if (var == "V04")	return _v04;
    	if (var == "V05")	return _v05;
    	if (var == "V06")	return _v06;
     
    	if (var == "V07")	return _v07;
    	if (var == "V08")	return _v08;
    	if (var == "V09")	return _v09;
     
    	return String();
    }
     
     
    /*=============================*/
    /*     Gestion des Handles     */
    /*=============================*/
     
    void handle_OnConnect(AsyncWebServerRequest *request)
    {
    	keys(8);
    	infos();
    	request->send(LITTLEFS, "/index.html", String(), false, processor);
    }
     
    void handle_ajax(AsyncWebServerRequest *request)
    {
    	short _val;
     
    	if (request->hasParam("val"))
    	{
    		AsyncWebParameter *p = request->getParam("val");
    		_val = p->value().toInt();
    		keys(_val);
    	}
    	else
    	{
    		infos();
    	}
     
    	request->send(200, "application/json", "{\"bt\":[\"" + _v01 + "\",\"" + _v02 + "\", \"" + _v03 + "\", \"" + _v04 + "\", \"" + _v05 + "\"], \"sp\":[\"" + _v06 + "\", \"" + _v07 + "\", \"" + _v08 + "\", \"" + _v09 + "\"]}");
    }
     
    void handle_NotFound(AsyncWebServerRequest *request)
    {
    	keys(9);
    	request->send(404, "text/plain", "Not found");
    }
     
     
    /**********************************/
    /*                                */
    /*     Procédure de Démarrage     */
    /*                                */
    /**********************************/
     
    void setup()
    {
    	Serial.begin(115200);
    	delay(1000);
     
    	/*-----------------------------------------*/
    	/*     Initialisation des Leds & Relais    */
    	/*-----------------------------------------*/
     
    	pinMode(_led_1, OUTPUT);
    	pinMode(_led_2, OUTPUT);
    	pinMode(_led_3, OUTPUT);
    	pinMode(_led_4, OUTPUT);
    	pinMode(_relay, OUTPUT);
     
    	keys(8);
     
    	/*------------------------------------------*/
    	/*     Initialisation de la Température     */
    	/*------------------------------------------*/
     
    	_sensor.begin();
     
    	initSensor();
     
    	/*-------------------------*/
    	/*     Gestion "LITTLEFS     */
    	/*-------------------------*/
     
    	if(!LITTLEFS.begin(true))
    	{
    		Serial.println("Erreur lors du montage \"LITTLEFS\"");
    		return;
    	}
     
    	/*------------------------------*/
    	/*     Connexion au routeur     */
    	/*------------------------------*/
     
    	WiFi.mode(WIFI_STA);
    	WiFi.begin(ssid,pwd);
     
    	Serial.print("Tentative de connexion ");
     
    	while (WiFi.status() != WL_CONNECTED)
    	{
    		delay(100);
    		Serial.print(".");
    	}
    	Serial.println();
     
    	Serial.println("Connexion WiFi effectuée !");
     
    	WiFi.enableIpV6();
    	delay(2000);
     
    	Serial.print("SSID : ");
    	Serial.println(ssid);
     
    	Serial.print("Adresse IPv6 : ");
    	Serial.println(WiFi.localIPv6());
     
    	Serial.print("Adresse IPv4 : ");
    	Serial.println(WiFi.localIP());
     
    	Serial.print("Masque de sous-réseau : ");
    	Serial.println(WiFi.subnetMask());
     
    	Serial.print("Paserelle : ");
    	Serial.println(WiFi.gatewayIP());
     
    	Serial.print("Adresse MAC : ");
    	Serial.println(WiFi.macAddress());
     
    	Serial.println();
     
    	/*---------------------------------------------------*/
    	/*     Configuration NTP (Network Time Protocol)     */
    	/*---------------------------------------------------*/
     
    	configTime(7200, 0, "fr.pool.ntp.org");
     
    	Serial.print("Tentative de connexion au serveur NTP ");
     
    	while (time(nullptr) <= 100000)
    	{
    		Serial.print(".");
    		delay(1000);
    	}
     
    	Serial.println("\n");
     
    	/*--------------------------------*/
    	/*     Référence des fichiers     */
    	/*--------------------------------*/
     
    	_server.on("/styles.css", HTTP_GET, [](AsyncWebServerRequest *request){request->send(LITTLEFS, "/styles.css", "text/css");});
    	_server.on("/script.js",  HTTP_GET, [](AsyncWebServerRequest *request){request->send(LITTLEFS, "/script.js",  "application/javascript");});
    	_server.on("/icon.png",   HTTP_GET, [](AsyncWebServerRequest *request){request->send(LITTLEFS, "/icon.png",   "image/png");});
     
    	/*-----------------------------*/
    	/*     Gestion des Handles     */
    	/*-----------------------------*/
     
    	_server.on("/",           HTTP_GET, [](AsyncWebServerRequest *request){handle_OnConnect(request);});
    	_server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){handle_OnConnect(request);});
    	_server.on("/ajax",       HTTP_GET, [](AsyncWebServerRequest *request){handle_ajax(request);});
    	_server.onNotFound(handle_NotFound);
     
    	/*------------------------------*/
    	/*     Lancement du Serveur     */
    	/*------------------------------*/
     
    	_server.begin();
    }
     
    /*******************************/
    /*                             */
    /*     Procédure Itérative     */
    /*                             */
    /*******************************/
     
    void loop()
    {
    	infos();
     
    	Serial.print("Date : ");
    	Serial.print(_v06);
    	Serial.print("  ");
     
    	Serial.print("Heure : ");
    	Serial.print(_v07);
    	Serial.print("  ");
     
    	Serial.print("Température : ");
    	Serial.print(_v08);
    	Serial.print("  ");
     
    	Serial.print("Touche : ");
    	Serial.println(_v09);
     
    	delay(1000);
    }

    Désolé pour la présentation, mais les tabulations ne sont pas à l'identique entre notepad++ et l'affichage dans ce forum.

    Et pour finir, un fichier compressé contenant mes quatre fichiers destiné à NodeMCU ESP32.
    Je l'ai compressé avec "7-zip".

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr