LOCODUINO

TCO Web interactif

TCO Web interactif avec des ESP32 et des ESP8266 (1)

.
Par : utpeca

DIFFICULTÉ :

Cet article propose de commander des appareils de voie depuis une tablette (ou un smartphone, ou un PC) et un browser. Pour ce faire, un ESP32 est utilisé en serveur web, qui, via une box et son réseau wifi va afficher le TCO qui permettra d’établir un itinéraire. Si ce premier article n’utilise qu’un ESP32, les articles suivants mentionneront la possibilité d’utiliser des ESP8266.

Le schéma ci-dessous donne le principe de fonctionnement de la solution mise en œuvre.

Figure 1
Figure 1
Principe de fonctionnement du TCO-Web.

Le projet met en œuvre un ESP32 serveur HTML B qui permet de piloter des aiguillages ou autres accessoires de réseau C à partir d’une tablette ou un smartphone A. La tablette/smartphone se connecte en wifi au serveur de l’ESP32 B qui présente une ou plusieurs pages en forme de TCO A sur lequel des commandes tactiles agissent sur les aiguilles.

Dans l’écran du TCO A, les appareils de voie sont repérés par une zone jaune qui indique leur état (la direction donnée). Les images des appareils de voie sont cliquables (sur un browser PC) ou touchables (sur un smartphone ou une tablette), ce qui permet de changer leur état (d’obtenir une autre direction).

Enfin, un message de changement d’état est envoyé par le serveur Web B, qui réaffiche la nouvelle image de l’appareil de voie A et commande électroniquement le ou les moteurs de l’appareil de voie C.

Les différents moteurs.

Les moteurs pris en compte disposent, de préférence, des caractéristiques suivantes :

  • Alimentation en courant continu ;
  • Mouvement lent des aiguilles ;
  • Dispositif de coupure de courant en fin de course ;
  • Réalimentation des cœurs.

Les moteurs disposant d’autres caractéristiques (alimentation en courant alternatif, servomoteurs, moteurs pas-à-pas, etc.) devront faire l’objet d’adaptations particulières.

La figure suivante présente des exemples de moteurs pouvant convenir :

Figure 2
Figure 2
Quelques moteurs pour le TCO-Web.

L’ESP32 sera hébergé sur une carte électronique permettant la commande de 8 moteurs. Le nombre d’appareils de voie pouvant être commandés par ces 8 moteurs se déduit du tableau ci-après.

Figure 3
Figure 3
Nombre de moteurs par type d’appareil de voie.

Avec cette carte électronique, on pourra commander au mieux :

  • soit 8 aiguillages simples (gauche, droite ou symétrique) ;
  • soit 4 appareils de voie complexes (TJD ou aiguillage triple) ;
  • soit entre 5 et 7 appareils de voie de toute sorte.

D’autres types de moteurs sont envisageables comme les moteurs à solénoïdes, à condition qu’ils soient dotés d’un dispositif de coupure de courant en fin de course et d’une réalimentation du cœur de l’appareil. Les moteurs Piko référence 55271 et Roco référence 61195 sont de ce type et peuvent convenir.

Les autres moteurs à solénoïdes, moyennant un supplément d’électronique (relais, redresseur, dispositif de décharge capacitive, etc.) peuvent convenir. Voir le sujet Décodeur pour aiguillage à solénoïdes sur Arduino ou bien Amplifier le signal de sortie d’un ARDUINO avec un ULN 2803. Les moteurs Peco PL10E, PL10W, PL1001, Marklin 74491 ou 74492 sont de cette catégorie.

Figure 4
Figure 4
Autres moteurs à solénoïdes.

Le microcontrôleur ESP32

Le choix s’est porté sur le microcontrôleur ESP32 NodeMCU de la société AZ-Delivery. Ce microcontrôleur présente les caractéristiques suivantes :

  • Double processeur ;
  • Fréquence d’horloge jusqu’à 240 MHz ;
  • Mémoire : 512k de RAM, 448k d’EEPROM, 4M de Flash ;
  • 38 broches (32 GIOP [1] , 5 pour l’alimentation, 1 Reset/Enable) ;
  • Alimentation de 7 à 12V par le régulateur intégré – les processeurs fonctionnant sous 3,3V ;
  • Capacités Wifi et Bluetooth (LE ou standard) ;
  • Connection aux périphériques grâce à ADC [2], DAC [3], PWM [4], I2C [5], SPI [6], UART [7] , … ;
  • Connection avec d’autres ESP par radio (2,4 MHz) avec la technologie ESP-NOW ;
  • Basse consommation d’énergie et dispositif de mise en sommeil.

Le brochage de l’ESP32 NodeMCU d’AZ-Delivery est présenté dans la figure suivante. Merci de bien vouloir noter que pour un ESP32 d’un autre modèle ou d’un autre fournisseur, le brochage peut être différent. Veuillez-vous reporter à la documentation normalement fournie avec le microcontrôleur. Dans la suite du document, le nom du microcontrôleur sera abrégé en ESP32.

Figure 5
Figure 5
Brochage de l’ESP NodeMCU.

Plus d’explications sur le fonctionnement des différentes broches se trouve sur le site suivant (en anglais) Random Nerd Tutorials : ESP32 Pinout Reference : Which GPIO pins should you use ?.

L’ESP32 peut être programmé avec l’IDE de l’Arduino. La procédure d’installation de l’ESP32 dans l’IDE est décrite par Jean-Luc dans l’article intitulé Éclairer le réseau (2). Le site Random Nerd Tutorials : Installing ESP32 in Arduino IDE (Windows, Mac OS X, Linux) décrit également (en anglais) la procédure à mettre en œuvre.

Une présentation de l’ESP32 a également été faite dans le sujet Automatisation du pont FLEISCHMANN 6152 (HO) avec un ESP32 (1).

La conception du TCO

Comme dans le sujet Écran couleur tactile Kuman, le TCO est constitué de petites images carrées représentant une portion du réseau pour laquelle les appareils de voie doivent être commandés.

Figure 6
Figure 6
Exemple de TCO simple.

Les différentes images des éléments de construction du TCO sont, pour le moment, hébergées par le site web http://utpeca.free.fr/ dans le sous-répertoire TCO. Le tableau ci-après présente les différents éléments pouvant entrer dans la composition d’un TCO.

Figure 7
Figure 7
Liste des éléments de TCO.

De même, les images des éléments correspondants à la rotation des autres éléments de voie existent :

  • AigD1_E1_090.png, AigD1_E1_180.png, AigD1_E1_270.png pour l’aiguillage droit ;
  • Crois2_E4_090.png, Crois2_E4_180.png, Crois2_E4_270.png pour la TJD2 ;

Pour les lecteurs qui souhaiteraient héberger ces vignettes dans leur propre site Web, ou bien utiliser d’autres technologies (SPIFFS [8], cartes MicroSD, ...), elles sont fournies dans le ZIP ci-après.

Vignettes pour la construction de TCO

Construction du TCO.

Le code HTML pour représenter le TCO de la figure 6 est le suivant :

<table border='0' cellspacing='0' cellpadding='0'><tr>
<tr>
<td> <img class='img1' src='http://utpeca.free.fr/TCO/Sign.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/VirG1_180.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/VirD1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
</tr>
<tr>
<td> <img class='img1' src='http://utpeca.free.fr/TCO/But5.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/AigG1_E1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/Crois2_E1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/But5_180.png'></td> 
</tr>
<tr>
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/VirD1_180.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td> 
<td> <img class='img1' src='http://utpeca.free.fr/TCO/But5_180.png'></td> 
</tr>
</table>

L’attribut class=’img1’ permet de définir le style (les caractéristiques) de l’affichage des éléments du TCO, comme suit :

  <style>
    .img1 {border: 0px; width: 64px; height=64px;}
  </style>

Cette portion de code doit se trouver dans la section head du code HTML.

Introduction de l’interactivité.

Le TCO tel qu’il est défini précédemment ne permet pas l’interactivité (c’est-à-dire de commander les appareils de voie). Pour ce faire, il faut remplacer les lignes :

…
<td> <img class='img1' src='http://utpeca.free.fr/TCO/AigG1_E1.png'></td> 
…
<td> <img class='img1' src='http://utpeca.free.fr/TCO/Crois2_E1.png'></td> 
…

par les lignes suivantes :

…
<td> <a href='javascript:;' 
      onClick="posApp1=ChangeAig(posApp1, 'Aig1', 'AigG1', '')"> 
     <img class='img1' src='http://utpeca.free.fr/TCO/AigG1_E1.png'
      name='imgAig1'></td> 
…
<td> <a href='javascript:;' 
      onClick="posApp2=ChangeTjd(posApp2, 'Tjd2', 'Crois2', '')"> 
     <img class='img1' src='http://utpeca.free.fr/TCO/Crois2_E1.png'
      name='imgTjd2'></td> 
…

De cette façon, un clic sur l’image de l’appareil de voie (ou un toucher de l’écran) déclenchera l’appel à la fonction Javascript ChangeAig pour l’aiguillage ou ChangeTjd pour la TJD.

Le code de la fonction ChangeAig est le suivant :

function ChangeAig(posApp, kodApp, imgApp, angApp)
{
   var posAig = posApp;
   var xhr = new XMLHttpRequest();
   if ( posAig == "1" )
   {
      posAig = "2";
      document.getElementById("DESC").innerHTML = 
               "&nbsp;"+kodApp+" : voie d&eacute;vi&eacute;e";
   }
   else
   {
      posAig = "1";
      document.getElementById("DESC").innerHTML = 
               "&nbsp;"+kodApp+" : voie directe";
   }
   if ( angApp == '' )
   {
      document.images['img'+kodApp].src=imgWeb+imgApp+'_E'+posAig+'.png';
   } 
   else
   {
      document.images['img'+kodApp].src= 
               imgWeb+imgApp+'_E'+posAig+'_'+angApp+'.png';
   }
   xhr.open("GET", "/update?output="+document.getElementById(kodApp).id+
                   ":A&state="+posAig, true);
   xhr.send();
   return posAig;
}

Le code des fonctions ChangeTjd, ChangeAigS et ChangeAigT prend en compte les différences d’état des appareils correspondants, mais reste similaire à la fonction ChangeAig.

Le code à téléverser dans l’ESP32.

Ce programme est basé sur l’exemple fourni par Rui Santos publié sur le site RandomNerdTutorials, à l’adresse suivante https://RandomNerdTutorials.com/esp....

Il comprend, dans l’ordre :

  • Les includes nécessaires au programme : Wifi, AsyncTCP et ESPAsyncWebServer ;
  • Les constantes et variables générales du programme (connexion au routeur, état des appareils, etc.) ;
  • Une chaîne de caractères contenant les instructions HTML qui seront exécutées sur le serveur ESP32 ainsi que le code Javascript ;
  • Un include définissant la table des appareils ainsi que le TCO à afficher (code HTML) – ce code est injecté dans la chaîne de caractères vue ci-dessus par la fonction processor ;
  • Une fonction pour actionner les appareils à la demande de l’utilisateur ;
  • La fonction setup qui permet la connexion au router, qui envoie la page HTML sur la tablette ou le PC du demandeur et qui récupère l’appareil à positionner ;
  • La fonction loop vide.

Les bibliothèques utilisées.

Il faut tout d’abord importer les bibliothèques prenant en charge un serveur web asynchrone. Ces bibliothèques sont WiFi, AsyncTCP et ESPAsyncWebServer.

// Import required libraries
#include "WiFi.h"
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

Les constantes et variables.

// Connection au routeur wifi (la box)
  const char* ssid     = "... le nom de votre routeur ...";
  const char* password = "... votre mot de passe ...";

// communication entre le serveur et la page HTML (browser)
const char* PARAM_INPUT_1 = "output"; // Nom de l'appareil
const char* PARAM_INPUT_2 = "state";  // Etat de l'appareil

// Adresse du site où sont stockées les images
String        img_Web   = "http://utpeca.free.fr/TCO/"; 

// Gestion des 74HC595
const    byte verrou     = 2;     // ST_CP (latch)
const    byte donnee     = 4;     // DS (data)
const    byte horloge    = 0;     // SH_CP (clock)
         uint16_t u_Data = 0b0101010101010101;     // data pour les 74hc595
const    uint16_t k_Msk  = 0b1100000000000000;     // Masque
const    uint16_t k_Dir  = 0b0100000000000000;     // Moteur direct
const    uint16_t k_Dev  = 0b1000000000000000;     // Moteur dévié

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

La chaîne contenant le code HTML+Javascript.

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <title>TCO par UTPECA</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
  <style>
    html {font-family: Arial; display: inline-block; text-align: left;}
    h2 {font-size: 3.0rem;}
    p {font-size: 15px; font-weight: bold; width: 400px; margin-left: 30px;
       padding-bottom: 2px; padding-top: 2px; border: 2px solid #6B6B94}
    .img1 {border: 0px; width: 64px; height=64px;}
    body {max-width: 1280px; margin:0px auto; padding-bottom: 10px;
          padding-top: 10px;}
  </style>
</head>
<body background='http://utpeca.free.fr/TCO/Pierre.gif' >
<table border='0' width='1280' cellspacing='0' cellpadding='0'>
<tr><td><img border='0' src=’%IMAGE_WEB%Titre2.gif'</td></tr>
<tr><td><img border='0' src=’%IMAGE_WEB%Ligne.gif'</td></tr></table>
 
%CONSTRUIRE_TCO%

<table><tr><td><img border='0' src='%IMAGE_WEB%Ligne.gif'</td></tr></table>
<p id='DESC'> &nbsp;Manoeuvrez un appareil</p>
<table><tr><td><img border='0' src='%IMAGE_WEB%Ligne.gif'</td></tr></table>

<script>
var imgWeb  = '%IMAGE_WEB%';
var posApp1 = '%VALEUR_APP1%';
var posApp2 = '%VALEUR_APP2%';
var posApp3 = '%VALEUR_APP3%';
var posApp4 = '%VALEUR_APP4%';
var posApp5 = '%VALEUR_APP5%';
var posApp6 = '%VALEUR_APP6%';
var posApp7 = '%VALEUR_APP7%';
var posApp8 = '%VALEUR_APP8%';

function ChangeAig(posApp, kodApp, imgApp, angApp)
{
   var posAig = posApp;
   var xhr = new XMLHttpRequest();

   ...Comme vu dans le paragraphe "Introduction de l’interactivité"

   xhr.open("GET", "/update?output="+document.getElementById(kodApp).id+
                   ":Aig&state="+posAig, true);
   xhr.send();   return posAig;
}

function ChangeAigS(posApp, kodApp, imgApp, angApp)
{
   ...Comme vu dans le paragraphe "Introduction de l’interactivité"
   return posAig;
}

function ChangeAigT(posApp, kodApp, imgApp, angApp)
{
    ...Comme vu dans le paragraphe "Introduction de l’interactivité"
  return posAig;
}

function ChangeTjd(posApp, kodApp, imgApp, angApp)
{
    ...Comme vu dans le paragraphe "Introduction de l’interactivité"
  return posTjd;
}

</script>
</body>
</html>
)rawliteral";

Le module de description du TCO (tables des appareils et fonction processor).

D’une manière générale, ce module de description du TCO est un fichier source chargé dans le croquis et contenant du code supplémentaire décrivant la table des appareils, ainsi que la fonction processor. Cette fonction permet d’injecter dans le code HTML la description du TCO et d’injecter dans le code Javascript les données permettant l’interactivité du TCO.

Le croquis fourni avec ce projet comprend quatre définitions de TCO. Le choix de chaque TCO se fait en modifiant le #define qui va bien (sic) et en recompilant. Par exemple, modifier #define TCO1 par #define TCO3 pour obtenir le TCO nommé PO-Midi1 puis téléverser.

// Prise en compte du fichier source du TCO
/*********************************************************************/
#define TCO1
#ifdef TCO1
#include "Mon_TCO_No01.h"
#endif
#ifdef TCO2
#include "Mon_TCO_No02.h"
#endif
#ifdef TCO3
#include "PO-Midi1.h"
#endif
#ifdef TCO4
#include "Mon_TCO_No04.h"
#endif

Ces TCO sont donnés à titre d’exemple pour permettre au lecteur de produire son propre TCO.

Figure 8
Figure 8
Images des TCO fournis en exemple

Le code de la description de la table des appareils de voie est donné ci-après.

// Définition de la table des Appareils
/*********************************************************************/
// par TCO_Web (Utpeca) le 24/06/2022
typedef struct 
{
  char   etaApp;    // état de l'appareil ( de '1' à '4')
  char   typApp;    // type de l'appareil ('A', 'J', 'T', 'S')
  byte   noMot1;    // No du 1er moteur (de 1 à 8)
  byte   noMot2;    // No du 2me moteur (de 1 à 8)
} appareil;

appareil t_App[NBMOT] = 
{
  {'1', 'A', 1, 0},
  {'1', 'J', 2, 3},
  {'1', ' ', 0, 0},
  {'1', ' ', 0, 0},
  {'1', ' ', 0, 0},
  {'1', ' ', 0, 0},
  {'1', ' ', 0, 0},
  {'1', ' ', 0, 0}
};

Le code de la fonction processor est comme suit :

// Remplacer %CONSTRUIRE_TCO% par la table des images dans la page web
/*********************************************************************/
String processor(const String& var)
{
  if (var == "CONSTRUIRE_TCO")
  {
    String tco = "";
    tco += "<table border='0' cellspacing='0' cellpadding='0'><tr>\n";
    tco += "<tr>\n";
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/Sign.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1'
                  src='http://utpeca.free.fr/TCO/VirG1_180.png'> </td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/VirD1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "</tr>\n";
    tco += "<tr>\n";
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/But5.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <a href='javascript:;' 
                  onClick=\"posApp1=ChangeAig(posApp1, 'Aig1', 'AigG1', '')\"> 
                 <img class='img1' src='http://utpeca.free.fr/TCO/AigG1_E1.png' 
                  name='imgAig1'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <a href='javascript:;' 
                  onClick=\"posApp2=ChangeTjd(posApp2, 'Tjd2', 'Crois2', '')\"> 
                 <img class='img1' src='http://utpeca.free.fr/TCO/Crois2_E1.png'
                  name='imgTjd2'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/But5_180.png'></td>\n"; 
    tco += "</tr>\n";

    tco += "<tr>\n";
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/vide.png'></td>\n"; 
    tco += "<td> <img class='img1'
                  src='http://utpeca.free.fr/TCO/VirD1_180.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' src='http://utpeca.free.fr/TCO/H1.png'></td>\n"; 
    tco += "<td> <img class='img1' 
                  src='http://utpeca.free.fr/TCO/But5_180.png'></td>\n"; 
    tco += "</tr>\n";
    tco += "</table>\n";
    return tco;
  }
  else if (var == "IMAGE_WEB")   { return img_Web; }
  else if (var == "VALEUR_APP1") { return String(t_App[0].etaApp); }
  else if (var == "VALEUR_APP2") { return String(t_App[1].etaApp); }
  else if (var == "VALEUR_APP3") { return String(t_App[2].etaApp); }
  else if (var == "VALEUR_APP4") { return String(t_App[3].etaApp); }
  else if (var == "VALEUR_APP5") { return String(t_App[4].etaApp); }
  else if (var == "VALEUR_APP6") { return String(t_App[5].etaApp); }
  else if (var == "VALEUR_APP7") { return String(t_App[6].etaApp); }
  else if (var == "VALEUR_APP8") { return String(t_App[7].etaApp); }
  else return String();
}

La fonction setup.

Les principales étapes exécutées dans la fonction sont les suivantes :

  • Mise en route du moniteur série à la vitesse de 115 200 bauds ;
  • Déclarations des broches utilisées pour faire fonctionner les registres à décalage 74HC595 ;
  • Initialisation des appareils pour les mettre en conformité avec le TCO affiché ;
  • Connexion au réseau wifi avec les paramètres SSID et Mot-de-Passe, puis envoi au moniteur du résultat de la connexion ;
  • Envoi de la chaîne de caractères HTML (index_html) complétée par l’exécution de processor au browser via le wifi ;
  • Attente de la réponse du browser et si celle-ci est correcte, appel de la fonction CommandeAppareil avec les paramètres véhiculés dans la réponse.

La fonction CommandeAppareil.

Les principales étapes exécutées dans la fonction sont les suivantes :

  • Décodage des données renvoyées par le browser au serveur web (nom, type et état de l’appareil ;
  • Appel de la fonction AfficheAppareil permettant l’affichage sur le moniteur série des informations relatives à l’appareil concerné (la quantité d’information dépendant de l’éventuelle directive DEBUG dans le croquis) ;
  • Appel de la fonction ActionneAppareil effectuant le calcul de la donnée à passer aux registres à décalage 74HC595 qui permettront la mise en route des moteurs adéquats ;
Figure 9
Figure 9
Affichage sur le moniteur série des données de l’appareil.
Figure 10
Figure 10
Algorithme de calcul des sorties des 74HC595.
Fichiers du croquis

Mise en route du serveur Web.

Une fois le code du croquis téléversé dans l’ESP32, l’écran ci-après s’affiche sur le moniteur série du PC.

Figure 11
Figure 11
Affichage du moniteur série au lancement du croquis.

Dans la ligne de commande de votre browser, il faut entrer l’adresse IP du serveur Web sous la forme suivante : http://192.168.1.xxx. C’est celle indiquée dans la figure ci-dessus.

La carte électronique et sa mise en œuvre

Le circuit imprimé.

Figure 12
Figure 12
Vue de dessus du circuit imprimé.

L’implantation des composants.

Figure 13
Figure 13
Vue de la carte coté composants.

Liste des composants :

  • un ESP32 à 38 broches ;
  • un connecteur 12 V (J1), 8 connecteurs 3 bornes vers les moteurs d’aiguillages (M1 à M8) et un strap (fil de câblage) ;
  • un réducteur de tension (buck converter) – entrée de 4,5V à 24V) – sortie réglée sur 3,3V ;
  • deux 74HC595 et deux ULN2803 ;
  • trois condensateurs de découplage (100 nF/35 V).

Le schéma de câblage.

Le schéma de câblage est présenté dans la figure suivante. Les condensateurs de découplage ne sont pas représentés afin d’alléger le schéma.

Figure 14
Figure 14
Schéma de câblage
Le réducteur de tension.

Le réducteur de tension peut être un modèle de base. Il coûte quelques euros sur les sites chinois ou américains vendant du chinois (Amazon, AliExpress, etc.). Il n’a pas de référence précise, mais on peut le retrouver en faisant une recherche "mini-réducteur de tension".

Il faut le préparer comme indiqué dans l’image suivante. Certains fabricants le fournissent avec l’ajustable en fonction, auquel cas il faut couper la piste cuivrée avec un cutter comme indiqué dans la figure. Dans tous les cas, il faut faire un pont de soudure pour avoir 3,3V.

Figure 15
Figure 15
Préparation du réducteur de tension.

D’autres réducteurs de tension peuvent être utilisés comme le Mini360 ou le MP1584. Cependant, leur mise en œuvre nécessite un multimètre et une adaptation des connexions au circuit imprimé.

Les décodeurs série/parallèle et les réseaux de Darlington.
Figure 16
Figure 16
Brochage des circuits intégrés 74HC595 et ULN2803.

Le fonctionnement du décodeur série/parallèle 74HC595 est décrit dans le site Arduino Serial to Parallel Shifting-Out with a 74HC595. Il a été également expliqué par Christian dans la fiche pratique du Loco Revue N° 902 d’août 2022.

Le fonctionnement du réseau de Darlington ULN2803 est exposé dans le sujet Amplifier le signal de sortie d’un ARDUINO avec un ULN 2803.

Le branchement des moteurs.
Connecteur
  • la broche de gauche (notée Mia) vers la commande de voie directe ;
  • la broche centrale au +12V (commun du moteur) ;
  • la broche de droite (Mib) vers la commande de voie déviée.

La commande d’un moteur se fait en mettant au niveau bas la sortie correspondante du 74HC595.

Fichiers Gerber du circuit imprimé

Câblage des appareils.

Les deux schémas ci-après indiquent comment câbler l’aiguillage et la TJD contrôlés par le TCO :

Figure 17
Figure 17
Câblage de l’aiguillage.
Figure 18
Figure 18
Câblage de la traversée jonction double.

Conclusion

Cet article a présenté un TCO économique (pas d’électrotechnique), universel (pour réseau analogique ou DCC) et évolutif, qui pourra inciter le lecteur à construire sa propre solution.
Un deuxième article est en préparation pour présenter une évolution de ce projet : séparation des fonctions Serveur HTML / Commande des Appareils et hébergement des vignettes du TCO dans le serveur HTML plutôt que dans un site Web.

[1GPIO (ou GIOP) : General Purpose Input/Output pins – broche d’entrée/sortie générale.

[2ADC : analogic digital convertor – convertisseur analogique digital.

[3DAC : digital analogic convertor– convertisseur digital analogique.

[4PWM : pulse wide modulator – modulation de largeur d’impulsion.

[5I2C : inter integrated circuit – bus série synchrone bidirectionnel half-duplex (origine Philips).

[6SPI : serial peripheral interface – bus série synchrone full-duplex (origine Motorola).

[7UART : universal asynchronous receiver/transmitter – émetteur-récepteur asynchrone universel.

[8SPIFFS : Serial Peripheral Interface Flash File System.

10 Messages

  • TCO Web interactif avec un ESP32 8 janvier 2023 01:16, par trimarco232

    Bonjour, Bonne année, Bravo !
    il faudrait peut-être un trait vertical, pour ceux qui veulent faire des ovales, ainsi que des boutons, à placer sur trait horizontal ou vertical, pour ceux qui veulent(peuvent) faire des commandes d’itinéraires ; dans ce cas il faudrait aussi que les traits puissent prendre un segment blanc ou rouge (pour montrer les occupations de zones)
    à défaut, tu peux nous donner les directives pour dessiner les .png, mais idéalement tout le monde aurait les mêmes

    Répondre

  • TCO Web interactif avec un ESP32 8 janvier 2023 10:44, par utpeca

    Bonjour trimarco232,

    Bonne année à toi également, ainsi qu’à tous les Locoduineurs !

    Le trait vertical existe en deux exemplaires : H1_090.png et V1.png.

    Pour pouvoir utiliser ses propres vignettes, il est préférable d’attendre la solution décrite dans le prochain article intitulé "TCO Web interactif avec des ESP32". En effet, elle décrit l’hébergement des vignettes dans la mémoire Flash de l’ESP32 et l’utilisation de ces vignettes grâce à SPIFFS.

    Pour dessiner ses propres vignettes, le mieux est de partir de la vignette vide.png, de l’enrichir et de la sauvegarder.

    Transformer une vignette en bouton (zone cliquable) n’est pas très compliqué (pour qui a des bases en Javascript !). Il suffit de remplacer

    img "But5_180.png"

    par

    a href="javascript : ;" onClick="MaFonctionNo1(’X14Y00’)" img "But5_180.png" id="X14Y00"

    sachant que MaFonctionNo1 est une fonction Javascript à écrire qui s’exécutera lorsque la vignette But5_180.png sera cliquée.

    La gestion des itinéraires est en cours d’étude mais cela représente un gros chantier. Evidemment, les vignettes indiquant un itinéraire constitué, libre ou occupé existent déjà.

    Cordialement

    Répondre

    • TCO Web interactif avec un ESP32 9 janvier 2023 08:14, par trimarco232

      j’ai testé ça, intuitivement je pense que c’est pertinent : (remplacer les // et \\ par les accolades)
      ...
      .img1 //border : 0px ; width : 64px ; height=64px ;\\
      .img1_90 // border : 0px ; width : 64px ; height=64px ;
      -webkit-transform : rotate(90deg) ;
      -moz-transform : rotate(90deg) ;
      -ms-transform : rotate(90deg) ;
      -o-transform : rotate(90deg) ;
      transform : rotate(90deg) ;
      \\
      .img1_180 // border : 0px ; width : 64px ; height=64px ;
      -webkit-transform : rotate(180deg) ;
      -moz-transform : rotate(180deg) ;
      -ms-transform : rotate(180deg) ;
      -o-transform : rotate(180deg) ;
      transform : rotate(180deg) ;
      \\
      .img1_270 // border : 0px ; width : 64px ; height=64px ;
      -webkit-transform : rotate(-90deg) ;
      -moz-transform : rotate(-90deg) ;
      -ms-transform : rotate(-90deg) ;
      -o-transform : rotate(-90deg) ;
      transform : rotate(-90deg) ;
      \\

      Répondre

      • TCO Web interactif avec un ESP32 9 janvier 2023 11:04, par trimarco232

        pour ne pas surcharger ici, j’ai ouvert la rubrique "TCO Web interactif avec un ESP32" dans le forum sous "Architectures logicielles et matérielles"

        Répondre

  • TCO Web interactif avec un ESP32 (1) 15 juin 2023 11:06, par babskwal

    Très intéressant !
    N’étant pas spécialiste, je ne sais pas : où faudrait-il mettre des condensateurs de découplage, et de quelle valeur ?

    Répondre

    • TCO Web interactif avec un ESP32 (1) 15 juin 2023 16:47, par utpeca

      Les condensateurs de découplage doivent se mettre le plus près possible des circuits intégrés qu’ils sont sensés aider. Des condensateurs standards céramiques ou films plastiques de 100 nF conviennent.

      Répondre

  • Hallo.Ich bin auf Ihr sehr Interessantes Projekt hier gestossen. Beim Nachbau habe ich aber leider etwas Schwierigkeiten. Ich habe die Gerberdatei für den ESP32 zusammen gelötet und wie in Ihrer Beschreibung angeschlossen. Mit dem 3,3V Regler bekomme ich keine Verbindung zu Stande, stecke ich aber noch ein USB Kabel direkt an den ESP, funktioniert es. An was es liegen könnte kann ich im Moment nicht Entdecken. MfG Ron from Germany

    Répondre

    • TCO Web interactif avec des ESP32 et des ESP8266 (1) 6 octobre 2023 16:55, par utpeca (Jean-Claude GENDRE)

      Google est notre ami, le message de Ron :

      Bonjour, je suis tombé sur votre projet très intéressant ici. Malheureusement, j’ai un peu de mal à le reproduire. J’ai soudé le fichier Gerber pour l’ESP32 et je l’ai connecté selon votre description. Je n’arrive pas à obtenir de connexion avec le contrôleur 3,3 V, mais si je branche un câble USB directement sur l’ESP, cela fonctionne. Je n’arrive pas à comprendre ce que cela pourrait être pour le moment. Cordialement, Ron d’Allemagne

      Ma réponse :
      Bonjour Ron,
      Merci de vos commentaires pour ce projet. Si vous n’arrivez pas à obtenir 3,3 V en sortie du réducteur de tension, c’est que probablement celui-ci est défectueux. Votre solution consistant à utiliser le câble USB pour alimenter l’ESP32 convient parfaitement. N’oubliez pas d’alimenter la prise 12 V pour faire fonctionner les moteurs d’aiguillage.
      Cordialement,

      et sa traduction :
      Hallo Ron,
      Vielen Dank für Ihre Kommentare zu diesem Projekt. Wenn Sie am Ausgang des Spannungsreduzierers keine 3,3 V erhalten, ist dieser wahrscheinlich defekt. Ihre Lösung, den ESP32 über das USB-Kabel mit Strom zu versorgen, funktioniert perfekt. Vergessen Sie nicht, die 12-V-Steckdose mit Strom zu versorgen, um die Weichenmotoren zu betreiben.
      Aufrichtig,
      Jean-Claude GENDRE

      Répondre

  • Hallo. Ich bins nochmal. Vielen Dank für Ihre Antwort. Ich habe den Spannungsregler noch ein mal überprüft und auch alle Verbindungen auf der Platine kontrolliert.Funktioniert alles wie es soll. Dann habe ich ein anderes ESP32 DevKit probiert und dieser funktioniert mit der Schaltung. Es scheint also am ESP32 zu liegen. Mfg Ron from Germany

    Répondre

    • TCO Web interactif avec des ESP32 et des ESP8266 (1) 9 octobre 2023 10:23, par utpeca (Jean-Claude GENDRE)

      Traduction du message de Ron :
      Bonjour. C’est encore moi. Merci pour votre réponse. J’ai vérifié à nouveau le régulateur de tension ainsi que toutes les connexions sur la carte. Tout fonctionne comme il se doit. Ensuite, j’ai essayé un autre DevKit ESP32 et celui-ci fonctionne avec le circuit. Il semble donc que ce soit l’ESP32. Meilleures salutations Ron d’Allemagne
      =============
      Mon message :
      Je suis content que vous ayez pu corriger la panne. Encore une fois, merci pour l’intérêt que vous portez à ce projet. Cordialement,
      Ich freue mich, dass Sie das Problem beheben konnten. Nochmals vielen Dank für Ihr Interesse an diesem Projekt. Herzliche Grüße, Jean-Claude GENDRE.

      Répondre

Réagissez à « TCO Web interactif avec des ESP32 et des ESP8266 (1) »

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Rubrique « Projets »

Les derniers articles

Les articles les plus lus