Je suis tombé sur une vidéo Youtube de Jéjé l’ingé pour réaliser l’horloge de retour vers le futur :

Et j’ai décidé de la réaliser

Matériel nécessaire

Liste du matériel nécessaire :

  • Un ESP32
  • 2 Leds vertes
  • 2 Leds rouges
  • 2 Leds jaunes
  • 3 afficheurs rouges TM1637
  • 3 afficheurs verts TM1637
  • 3 afficheurs jaunes TM1637
  • 4 résistances de 270 Ohm
  • 1 connecteur d’alimentation
  • 2 wago
  • Du PLA pour l’impression 3D
  • Colle super glue cyanoacrylate
  • Colle vinylique 
  • Pistolet colle à chaud
  • Peinture argent
  • Une plaque de circuit imprimé de prototypage

L’impression 3D

Les plans pour l’impression sont disponible sur thingiverse : https://www.thingiverse.com/thing:5890727

J’ai mis un radeau (couche d’accroche) pour l’impression et je regrette car les faces avants ne sont pas très belles, elles sont striés.

Le collage

Collage des différents éléments imprimé en 3D à l’aide de la colle cyanoacrylate.

Il faut ensuite peindre l’horloge à la bombe argent.

Le montage électronique

Nous passons maintenant à l’électronique, voici le schéma de montage mis à disposition avec les plan 3D sur Thingiverse https://www.thingiverse.com/thing:5890727 par Jéjé l’ingé :

Il faut commencer par souder entre eux les 3 afficheurs de chaque couleur avec les CLK entre eux, les GND entre eux, les 5v entre eux puis des fils unique pour chaque DIO de chaque afficheurs.

Il faut ensuite réaliser les leds pour le AM et PM avec les résistances et la gaine thermo rétractable. Il faut faire une led rouge, les deux leds vertes et une led jaune, les deux autre led (la rouge et la jaune) ne sont pas raccordés, elles sont factices.

Ensuite il faut réaliser le montage dans l’horloge imprimé en 3D. J’ai utilisé la super glue pour fixer les leds et de la colle à chaud pour fixer les afficheurs.

Pour finir il faut souder les différents fils à l’ESP32, pour cela j’ai utilisé une plaque de circuit imprimé que l’on utilise pour les prototypage afin de me faciliter la vie pour souder les différents fils à l’ESP32. Vous retrouvez pour chaque fils le numéro de patte de l’ESP32 sur le schéma de montage à savoir :

Pour les afficheurs du haut rouges :

  • Afficheurs rouge CLK en 13
  • Afficheur month/day DIO en 14
  • Afficheur year DIO en 15
  • Afficheur hour/minute DIO en 16

Pour les afficheurs du milieu verts :

  • Afficheurs vert CLK en 17
  • Afficheur month/day DIO en 18
  • Afficheur year DIO en 19
  • Afficheur hour/minute DIO en 21

Pour les afficheurs du bas jaunes :

  • Afficheurs jaunes CLK en 17
  • Afficheur month/day DIO en 18
  • Afficheur year DIO en 19
  • Afficheur hour/minute DIO en 21

Pour les deux leds vertes

  • Une en 32
  • Une en 33

Les 2 autres leds avec résistance (non factice) une rouge et une jaunes sont directement raccordé sur le 5v.

D’ailleurs pour toutes les bornes 5v et toute les bornes GND, on utilise les 2 wago pour les raccorder ensemble.

Programmation de l’ESP 32

Il faut maintenant téléverser le programme de Jéjé l’ingé, disponible avec les plan 3D sur Thingiverse https://www.thingiverse.com/thing:5890727, sur l’ESP32 à l’aide de l’arduino IDE.

#include "Arduino.h"
#include "TM1637Display.h"
#include "ArduinoJson.h"
#include "WiFiManager.h"
#include "NTPClient.h"


// Module connection pins (Digital Pins)
#define red_CLK 13
#define red1_DIO 14
#define red2_DIO 15
#define red3_DIO 16

#define green_CLK 17
#define green1_DIO 18
#define green2_DIO 19
#define green3_DIO 21

#define orange_CLK 22
#define orange1_DIO 23
#define orange2_DIO 25
#define orange3_DIO 26

#define greenAM 32
#define greenPM 33

bool res;
//========================USEFUL VARIABLES=============================
int UTC = 2; // UTC + value in hour - Summer time
const long utcOffsetInSeconds = 3600; // Offset in second
int Display_backlight = 255;

//Set the red displays
int red_day = 26;
int red_month = 10;
int red_year = 1985;
int red_hour = 9;
int red_minute = 00;

//set the orange displays
int orange_day = 12;
int orange_month = 11;
int orange_year = 1955;
int orange_hour = 06;
int orange_minute = 38;

//=====================================================================

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds*UTC);

TM1637Display green1(green_CLK, green1_DIO);
TM1637Display green2(green_CLK, green2_DIO);
TM1637Display green3(green_CLK, green3_DIO);

TM1637Display red1(red_CLK, red1_DIO);
TM1637Display red2(red_CLK, red2_DIO);
TM1637Display red3(red_CLK, red3_DIO);

TM1637Display orange1(orange_CLK, orange1_DIO);
TM1637Display orange2(orange_CLK, orange2_DIO);
TM1637Display orange3(orange_CLK, orange3_DIO);

void setup()
{ 
  pinMode(32, OUTPUT);
  pinMode(33, OUTPUT);
  Serial.begin(115200);
  
    WiFiManager manager;    
     
   manager.setTimeout(180);
  //fetches ssid and password and tries to connect, if connections succeeds it starts an access point with the name called "BTTF_CLOCK" and waits in a blocking loop for configuration
  res = manager.autoConnect("BTTF_CLOCK","password");
  
  if(!res) {
  Serial.println("failed to connect and timeout occurred");
  ESP.restart(); //reset and try again
  }
  

  delay(3000);


  timeClient.begin();
  red1.setBrightness(Display_backlight);
  red2.setBrightness(Display_backlight);
  red3.setBrightness(Display_backlight);
  
  green1.setBrightness(Display_backlight);
  green2.setBrightness(Display_backlight);
  green3.setBrightness(Display_backlight);

  orange1.setBrightness(Display_backlight);
  orange2.setBrightness(Display_backlight);
  orange3.setBrightness(Display_backlight);

}

void loop()
{
  timeClient.update();
  Serial.print("Time: ");
  Serial.println(timeClient.getFormattedTime());
  unsigned long epochTime = timeClient.getEpochTime();
  struct tm *ptm = gmtime ((time_t *)&epochTime); 
  int currentYear = ptm->tm_year+1900;
  Serial.print("Year: ");
  Serial.println(currentYear);
  
  int monthDay = ptm->tm_mday;
  Serial.print("Month day: ");
  Serial.println(monthDay);

  int currentMonth = ptm->tm_mon+1;
  Serial.print("Month: ");
  Serial.println(currentMonth);
  
red1.showNumberDecEx(red_month,0b01000000,true,2,0);
red1.showNumberDecEx(red_day,0b01000000,true,2,2);
red2.showNumberDecEx(red_year,0b00000000,true);
red3.showNumberDecEx(red_hour,0b01000000,true,2,0);
red3.showNumberDecEx(red_minute,0b01000000,true,2,2);


green1.showNumberDecEx(currentMonth,0b01000000,true,2,0);
green1.showNumberDecEx(monthDay,0b01000000,true,2,2);
green2.showNumberDecEx(currentYear,0b00000000,true);
green3.showNumberDecEx(timeClient.getHours(),0b01000000,true,2,0);
green3.showNumberDecEx(timeClient.getMinutes(),0b01000000,true,2,2);


orange1.showNumberDecEx(orange_month,0b01000000,true,2,0);
orange1.showNumberDecEx(orange_day,0b01000000,true,2,2);
orange2.showNumberDecEx(orange_year,0b00000000,true);
orange3.showNumberDecEx(orange_hour,0b01000000,true,2,0);
orange3.showNumberDecEx(orange_minute,0b01000000,true,2,2);

if((currentMonth*30 + monthDay) >= 121 && (currentMonth*30 + monthDay) < 331){
timeClient.setTimeOffset(utcOffsetInSeconds*UTC);} // Change daylight saving time - Summer
else {timeClient.setTimeOffset((utcOffsetInSeconds*UTC) - 3600);} // Change daylight saving time - Winter


if(timeClient.getHours()>=13){
  digitalWrite(greenAM,0);
  digitalWrite(greenPM,1);}
  
else if(timeClient.getHours()==12){
  digitalWrite(greenAM,0);
  digitalWrite(greenPM,1);}

else{
  digitalWrite(greenAM,1);
  digitalWrite(greenPM,0);}

delay(20);

}

Il y a pas mal de bibliothèques utilisés, il est donc nécessaire de les installer à savoir :

  • Arduino
  • TM1637Display
  • ArduinoJson
  • WifiManager
  • NTPClient

Une fois le programme télétransmis, vous devez vous connecter à l’aide de votre téléphone sur le wifi de l’ESP32 nommé BTTF_CLOCK. Il faut ensuite cliquer sur Configure Wifi afin de sélectionner votre réseau wifi et saisir le mot mot de passe dans l’interface de l’ESP32.

Veuillez bien noter l’adresse IP de l’ESP32 sur votre réseau wifi, elle se trouve en haut de l’écran lorsque vous configurez le Wifi, nous allons nous en servir dans l’amélioration de l’horloge plus bas dans cet article.

L’horloge est maintenant connecté au Wifi et va mettre à jour automatiquement la date et l’heure de l’horloge.

Les finissions

J’ai imprimé et découpé les différents éléments à coller sur l’horloge, aussi disponible avec les plans 3D sur Thingiverse https://www.thingiverse.com/thing:5890727. Je les ai collé avec la colle vinylique et ca fonctionne bien.

Je suis super content de cette horloge proposé, je le rappel, par Jéjé l’ingé.

Amélioration

J’ai décidé de faire une amélioration pour pouvoir changer les dates « Destination Time » et « Last Time Departed ». Actuellement, pour modifier ces deux dates, vous êtes obligé de passer par la modification du programme et ensuite de le téléverser à nouveau sur l’ESP.

Voici la partie du programme ou vous pouvez modifier les dates affichés.

//Set the red displays
int red_day = 26;
int red_month = 10;
int red_year = 1985;
int red_hour = 9;
int red_minute = 00;

//set the orange displays
int orange_day = 12;
int orange_month = 11;
int orange_year = 1955;
int orange_hour = 06;
int orange_minute = 38;

Mais en améliorant le programme, en y ajoutant un serveur Web, nous allons pouvoir soit par l’intermédiaire d’un formulaire, soit par une API, modifier les deux dates.

Il faut rajouter une bibliothèque supplémentaire : WebServer

#include "WebServer.h"

Il faut déclarer le serveur sur le port 80 (http):

// Déclaration du serveur web sur le port 80
WebServer server(80);

Dans la section void setup(), il faut déclarer les différentes pages web accessibles et démarrer le serveur web :

  // on déclare la page api correspondant à la fonction handleAPI_html
  server.on("/api",handleAPI_html);
  // on déclare la page update suite à la validation du formulaire correspondant à la fonction handleUpdate
  server.on("/update",handleUpdate);
  // on déclare la page d'accueil et/ou index.html avec le formulaire de mise à jour de la date correspondant à la fonction hanfleRoot
  server.on("/",handleRoot);
  // on démarre le serveur web
  server.begin();

Pour la partie API, la fonction handleAPI_html dans laquelle on va imaginer une commande setlastime qui va permettre de passer les paramètres month, day, year, hour et minute avec des valeurs pour modifier la date de « Last Time Departed », et une commande setdestime qui va permettre de passer les paramètres month, day, year, hour et minute avec des valeurs pour modifier la date de « Destination Time ».

// Fonction handleAPI_html
// exemple /api?cmd=setdestime&day=14&month=07&year=1974&hour=10&minute=10
// cmd = setdestime ou setlastime 
// setdestime pour mettre une destination time
// setlastime pour mettre une last time departed
void handleAPI_html(){
  String reponse;
  if(server.args() >0) {
    if(server.argName(0) == "cmd") {
      if(server.args()==6) {
        //commande avec 5 valeur
        if(server.arg(0) == "setdestime") {
          int i;
          for(i=1;i<6;i++)
          {
            if(server.argName(i) == "day") {
            red_day = server.arg(i).toInt();
          }
          if(server.argName(i) == "month") {
            red_month = server.arg(i).toInt();
          }
          if(server.argName(i) == "year") {
            red_year = server.arg(i).toInt();
          }
          if(server.argName(i) == "hour") {
            red_hour = server.arg(i).toInt();
          }
          if(server.argName(i) == "minute") {
            red_minute = server.arg(i).toInt();
          }
          }
          reponse = "1";
        }
        else if(server.arg(0) == "setlastime") {
          int i;
          for(i=1;i<6;i++)
          {
            if(server.argName(i) == "day") {
            orange_day = server.arg(i).toInt();
          }
          if(server.argName(i) == "month") {
            orange_month = server.arg(i).toInt();
          }
          if(server.argName(i) == "year") {
            orange_year = server.arg(i).toInt();
          }
          if(server.argName(i) == "hour") {
            orange_hour = server.arg(i).toInt();
          }
          if(server.argName(i) == "minute") {
            orange_minute = server.arg(i).toInt();
          }
          }
          reponse = "1";
        }
        else reponse = "COMMANDE INCONNU !";

      }
      else reponse = "PROBLEME D'ARGUMENTS!";
    }
    else reponse = "ARGUMENT INCORRECT !";
    server.send(200, "text/plain", reponse);
  }
  else {
    reponse = "APPEL API SANS PARAMETRE...";
    server.send(200, "text/plain", reponse);
  }
}

Pour le formulaire de mise à jour, la déclaration de la page html et la fonction handleRoot dans laquelle on va afficher le formulaire avec les valeurs des dates actuelles.

// Page html du formulaire
const char index_html[] PROGMEM = R"=====(
<!DOCTYPE html>

<html>
<head>
  <meta charset="utf-8">
  <title>Back To The Futur</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
  <link rel="stylesheet" href="https://www.w3schools.com/lib/w3-theme-blue.css">
</head>
<body>

<header class="w3-container w3-card-4 w3-theme">
  <h1>HORLOGE</h1>
</header>
  <img style="width:100%;max-width:350px" src="https://upload.wikimedia.org/wikipedia/fr/thumb/8/88/Retour_vers_le_futur_Logo.svg/1200px-Retour_vers_le_futur_Logo.svg.png" width="250px">
<br/><br/>
<div class="w3-panel">
  <div class="w3-row">
    <div class="s12">
    <form action="/update" method="get">
      <strong>Destination Time</strong><br/>
      <label>Month</label>
      <input type="text" name="month1" size="2" value="%month1%"></input>
    
      <label>Day</label>
      <input type="text" name="day1" size="2"  value="%day1%"></input>
    
      <label>Year</label>
      <input type="text" name="year1" size="4"  value="%year1%"></input>
    
      <label>Hour</label>
      <input type="text" name="hour1" size="2"  value="%hour1%"></input>
    
      <label>Minutes</label>
      <input type="text" name="minute1" size="2"  value="%minute1%"></input>
    
      <br/><br/>
      <strong>Last Time Departed</strong><br/>
      <label>Month</label>
      <input type="text" name="month2" size="2"  value="%month2%"></input>
    
      <label>Day</label>
      <input type="text" name="day2" size="2"  value="%day2%"></input>
    
      <label>Year</label>
      <input type="text" name="year2" size="4"  value="%year2%"></input>
    
      <label>Hour</label>
      <input type="text" name="hour2" size="2"  value="%hour2%"></input>
    
      <label>Minutes</label>
      <input type="text" name="minute2" size="2"  value="%minute2%"></input>
    
      <br/><br/>

      <div class="w3-row">
        <div class="s12">
          <input type="submit" class="w3-btn w3-ripple w3-blue" value="Envoyer">
    
    </form>
    </div>
  </div>
</div>
</body>
</html>
)=====";

// Fonction page d'accueil avec formulaire html
void handleRoot(){
  String temp(reinterpret_cast<const __FlashStringHelper *>(index_html));
  String jour1 = String(red_day);
  temp.replace("%day1%",jour1);
  String mois1 = String(red_month);
  temp.replace("%month1%",mois1);
  String annee1 = String(red_year);
  temp.replace("%year1%",annee1);
  String heure1 = String(red_hour);
  temp.replace("%hour1%",heure1);
  String minute1 = String(red_minute);
  temp.replace("%minute1%",minute1);
  String jour2 = String(orange_day);
  temp.replace("%day2%",jour2);
  String mois2 = String(orange_month);
  temp.replace("%month2%",mois2);
  String annee2 = String(orange_year);
  temp.replace("%year2%",annee2);
  String heure2 = String(orange_hour);
  temp.replace("%hour2%",heure2);
  String minute2 = String(orange_minute);
  temp.replace("%minute2%",minute2);
  server.send(200, "text/html",temp);
};

Pour la mise à jour, la fonction handleUpdate qui met à jour les dates et qui affiche à nouveau le formulaire avec les valeurs à jour.

// Fonction d'update des valeurs issus du formualire
void handleUpdate(){
  int i;
  for(i=0;i<11;i++){
    Serial.println(server.argName(i));
    Serial.println(server.arg(i));
  }
  String reponse;
  if(server.args() >0) {
      if(server.args()==10) {
          int i;
          for(i=0;i<10;i++)
          {
            if(server.argName(i) == "month1") {
              red_month = server.arg(i).toInt();
            }
            if(server.argName(i) == "day1") {
              red_day = server.arg(i).toInt();
            }
            if(server.argName(i) == "year1") {
              red_year = server.arg(i).toInt();
            }
            if(server.argName(i) == "hour1") {
              red_hour = server.arg(i).toInt();
            }
            if(server.argName(i) == "minute1") {
              red_minute = server.arg(i).toInt();
            }
            if(server.argName(i) == "month2") {
              orange_month = server.arg(i).toInt();
            }          
            if(server.argName(i) == "day2") {
              orange_day = server.arg(i).toInt();
            }
            if(server.argName(i) == "year2") {
              orange_year = server.arg(i).toInt();
            }
            if(server.argName(i) == "hour2") {
              orange_hour = server.arg(i).toInt();
            }
            if(server.argName(i) == "minute2") {
              orange_minute = server.arg(i).toInt();
            }
          }
        //reponse = "MISE A JOUR EFFECTUE";
        //server.send(200, "text/plain", reponse);
        String temp(reinterpret_cast<const __FlashStringHelper *>(index_html));
        String jour1 = String(red_day);
        temp.replace("%day1%",jour1);
        String mois1 = String(red_month);
        temp.replace("%month1%",mois1);
        String annee1 = String(red_year);
        temp.replace("%year1%",annee1);
        String heure1 = String(red_hour);
        temp.replace("%hour1%",heure1);
        String minute1 = String(red_minute);
        temp.replace("%minute1%",minute1);
        String jour2 = String(orange_day);
        temp.replace("%day2%",jour2);
        String mois2 = String(orange_month);
        temp.replace("%month2%",mois2);
        String annee2 = String(orange_year);
        temp.replace("%year2%",annee2);
        String heure2 = String(orange_hour);
        temp.replace("%hour2%",heure2);
        String minute2 = String(orange_minute);
        temp.replace("%minute2%",minute2);
        server.send(200, "text/html",temp);

      }
      else {
        reponse = "PROBLEME D'ARGUMENTS !";
        server.send(200, "text/plain", reponse);
      }
  }
  else {
    reponse = "APPEL SANS PARAMETRE...";
    server.send(200, "text/plain", reponse);
  }
};

Pour finir, il faut rajouter dans le void Loop(), la fonction qui permet d’écouter les requêtes http :

// On écoute les requete http client
server.handleClient();

Le programme complet

Voici le programme complet modifié :

// Programme écris par jéjé l'ingé : https://jeje-linge.fr/
// Et modifié par Romain Planel : https://romain.planel.fr/

#include "Arduino.h"
#include "TM1637Display.h"
#include "ArduinoJson.h"
#include "WiFiManager.h"
#include "NTPClient.h"
#include "WebServer.h"

// Module connection pins (Digital Pins)
#define red_CLK 13
#define red1_DIO 14
#define red2_DIO 15
#define red3_DIO 16

#define green_CLK 17
#define green1_DIO 18
#define green2_DIO 19
#define green3_DIO 21

#define orange_CLK 22
#define orange1_DIO 23
#define orange2_DIO 25
#define orange3_DIO 26

#define greenAM 32
#define greenPM 33

// Page html du formulaire
const char index_html[] PROGMEM = R"=====(
<!DOCTYPE html>

<html>
<head>
  <meta charset="utf-8">
  <title>Back To The Futur</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
  <link rel="stylesheet" href="https://www.w3schools.com/lib/w3-theme-blue.css">
</head>
<body>

<header class="w3-container w3-card-4 w3-theme">
  <h1>HORLOGE</h1>
</header>
  <img style="width:100%;max-width:350px" src="https://upload.wikimedia.org/wikipedia/fr/thumb/8/88/Retour_vers_le_futur_Logo.svg/1200px-Retour_vers_le_futur_Logo.svg.png" width="250px">
<br/><br/>
<div class="w3-panel">
  <div class="w3-row">
    <div class="s12">
    <form action="/update" method="get">
      <strong>Destination Time</strong><br/>
      <label>Month</label>
      <input type="text" name="month1" size="2" value="%month1%"></input>
    
      <label>Day</label>
      <input type="text" name="day1" size="2"  value="%day1%"></input>
    
      <label>Year</label>
      <input type="text" name="year1" size="4"  value="%year1%"></input>
    
      <label>Hour</label>
      <input type="text" name="hour1" size="2"  value="%hour1%"></input>
    
      <label>Minutes</label>
      <input type="text" name="minute1" size="2"  value="%minute1%"></input>
    
      <br/><br/>
      <strong>Last Time Departed</strong><br/>
      <label>Month</label>
      <input type="text" name="month2" size="2"  value="%month2%"></input>
    
      <label>Day</label>
      <input type="text" name="day2" size="2"  value="%day2%"></input>
    
      <label>Year</label>
      <input type="text" name="year2" size="4"  value="%year2%"></input>
    
      <label>Hour</label>
      <input type="text" name="hour2" size="2"  value="%hour2%"></input>
    
      <label>Minutes</label>
      <input type="text" name="minute2" size="2"  value="%minute2%"></input>
    
      <br/><br/>

      <div class="w3-row">
        <div class="s12">
          <input type="submit" class="w3-btn w3-ripple w3-blue" value="Envoyer">
    
    </form>
    </div>
  </div>
</div>
</body>
</html>
)=====";

bool res;
//========================USEFUL VARIABLES=============================
int UTC = 2; // UTC + value in hour - Summer time
const long utcOffsetInSeconds = 3600; // Offset in second
int Display_backlight = 255;

//Set the red displays
int red_day = 26;
int red_month = 10;
int red_year = 1985;
int red_hour = 9;
int red_minute = 00;

//set the orange displays
int orange_day = 12;
int orange_month = 11;
int orange_year = 1955;
int orange_hour = 06;
int orange_minute = 38;

//=====================================================================

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds*UTC);

TM1637Display green1(green_CLK, green1_DIO);
TM1637Display green2(green_CLK, green2_DIO);
TM1637Display green3(green_CLK, green3_DIO);

TM1637Display red1(red_CLK, red1_DIO);
TM1637Display red2(red_CLK, red2_DIO);
TM1637Display red3(red_CLK, red3_DIO);

TM1637Display orange1(orange_CLK, orange1_DIO);
TM1637Display orange2(orange_CLK, orange2_DIO);
TM1637Display orange3(orange_CLK, orange3_DIO);

// Déclaration du serveur web sur le port 80
WebServer server(80);

// Fonction handleAPI_html
// exemple /api?cmd=setdestime&day=14&month=07&year=1974&hour=10&minute=10
// cmd = setdestime ou setlastime 
// setdestime pour mettre une destination time
// setlastime pour mettre une last time departed
void handleAPI_html(){
  String reponse;
  if(server.args() >0) {
    if(server.argName(0) == "cmd") {
      if(server.args()==6) {
        //commande avec 5 valeur
        if(server.arg(0) == "setdestime") {
          int i;
          for(i=1;i<6;i++)
          {
            if(server.argName(i) == "day") {
            red_day = server.arg(i).toInt();
          }
          if(server.argName(i) == "month") {
            red_month = server.arg(i).toInt();
          }
          if(server.argName(i) == "year") {
            red_year = server.arg(i).toInt();
          }
          if(server.argName(i) == "hour") {
            red_hour = server.arg(i).toInt();
          }
          if(server.argName(i) == "minute") {
            red_minute = server.arg(i).toInt();
          }
          }
          reponse = "1";
        }
        else if(server.arg(0) == "setlastime") {
          int i;
          for(i=1;i<6;i++)
          {
            if(server.argName(i) == "day") {
            orange_day = server.arg(i).toInt();
          }
          if(server.argName(i) == "month") {
            orange_month = server.arg(i).toInt();
          }
          if(server.argName(i) == "year") {
            orange_year = server.arg(i).toInt();
          }
          if(server.argName(i) == "hour") {
            orange_hour = server.arg(i).toInt();
          }
          if(server.argName(i) == "minute") {
            orange_minute = server.arg(i).toInt();
          }
          }
          reponse = "1";
        }
        else reponse = "COMMANDE INCONNU !";

      }
      else reponse = "PROBLEME D'ARGUMENTS!";
    }
    else reponse = "ARGUMENT INCORRECT !";
    server.send(200, "text/plain", reponse);
  }
  else {
    reponse = "APPEL API SANS PARAMETRE...";
    server.send(200, "text/plain", reponse);
  }
}


// Fonction page d'accueil avec formulaire html
void handleRoot(){
  String temp(reinterpret_cast<const __FlashStringHelper *>(index_html));
  String jour1 = String(red_day);
  temp.replace("%day1%",jour1);
  String mois1 = String(red_month);
  temp.replace("%month1%",mois1);
  String annee1 = String(red_year);
  temp.replace("%year1%",annee1);
  String heure1 = String(red_hour);
  temp.replace("%hour1%",heure1);
  String minute1 = String(red_minute);
  temp.replace("%minute1%",minute1);
  String jour2 = String(orange_day);
  temp.replace("%day2%",jour2);
  String mois2 = String(orange_month);
  temp.replace("%month2%",mois2);
  String annee2 = String(orange_year);
  temp.replace("%year2%",annee2);
  String heure2 = String(orange_hour);
  temp.replace("%hour2%",heure2);
  String minute2 = String(orange_minute);
  temp.replace("%minute2%",minute2);
  server.send(200, "text/html",temp);
};


// Fonction d'update des valeurs issus du formualire
void handleUpdate(){
  int i;
  for(i=0;i<11;i++){
    Serial.println(server.argName(i));
    Serial.println(server.arg(i));
  }
  String reponse;
  if(server.args() >0) {
      if(server.args()==10) {
          int i;
          for(i=0;i<10;i++)
          {
            if(server.argName(i) == "month1") {
              red_month = server.arg(i).toInt();
            }
            if(server.argName(i) == "day1") {
              red_day = server.arg(i).toInt();
            }
            if(server.argName(i) == "year1") {
              red_year = server.arg(i).toInt();
            }
            if(server.argName(i) == "hour1") {
              red_hour = server.arg(i).toInt();
            }
            if(server.argName(i) == "minute1") {
              red_minute = server.arg(i).toInt();
            }
            if(server.argName(i) == "month2") {
              orange_month = server.arg(i).toInt();
            }          
            if(server.argName(i) == "day2") {
              orange_day = server.arg(i).toInt();
            }
            if(server.argName(i) == "year2") {
              orange_year = server.arg(i).toInt();
            }
            if(server.argName(i) == "hour2") {
              orange_hour = server.arg(i).toInt();
            }
            if(server.argName(i) == "minute2") {
              orange_minute = server.arg(i).toInt();
            }
          }
        //reponse = "MISE A JOUR EFFECTUE";
        //server.send(200, "text/plain", reponse);
        String temp(reinterpret_cast<const __FlashStringHelper *>(index_html));
        String jour1 = String(red_day);
        temp.replace("%day1%",jour1);
        String mois1 = String(red_month);
        temp.replace("%month1%",mois1);
        String annee1 = String(red_year);
        temp.replace("%year1%",annee1);
        String heure1 = String(red_hour);
        temp.replace("%hour1%",heure1);
        String minute1 = String(red_minute);
        temp.replace("%minute1%",minute1);
        String jour2 = String(orange_day);
        temp.replace("%day2%",jour2);
        String mois2 = String(orange_month);
        temp.replace("%month2%",mois2);
        String annee2 = String(orange_year);
        temp.replace("%year2%",annee2);
        String heure2 = String(orange_hour);
        temp.replace("%hour2%",heure2);
        String minute2 = String(orange_minute);
        temp.replace("%minute2%",minute2);
        server.send(200, "text/html",temp);

      }
      else {
        reponse = "PROBLEME D'ARGUMENTS !";
        server.send(200, "text/plain", reponse);
      }
  }
  else {
    reponse = "APPEL SANS PARAMETRE...";
    server.send(200, "text/plain", reponse);
  }
};

void setup()
{ 
  pinMode(32, OUTPUT);
  pinMode(33, OUTPUT);
  Serial.begin(115200);
  
    WiFiManager manager;    
     
   manager.setTimeout(180);
  //fetches ssid and password and tries to connect, if connections succeeds it starts an access point with the name called "BTTF_CLOCK" and waits in a blocking loop for configuration
  res = manager.autoConnect("BTTF_CLOCK","password");

  if(!res) {
  Serial.println("failed to connect and timeout occurred");
  ESP.restart(); //reset and try again
  }
  

  delay(3000);


  timeClient.begin();
  red1.setBrightness(Display_backlight);
  red2.setBrightness(Display_backlight);
  red3.setBrightness(Display_backlight);
  
  green1.setBrightness(Display_backlight);
  green2.setBrightness(Display_backlight);
  green3.setBrightness(Display_backlight);

  orange1.setBrightness(Display_backlight);
  orange2.setBrightness(Display_backlight);
  orange3.setBrightness(Display_backlight);

  // on déclare la page api correspondant à la fonction handleAPI_html
  server.on("/api",handleAPI_html);
  // on déclare la page update suite à la validation du formulaire correspondant à la fonction handleUpdate
  server.on("/update",handleUpdate);
  // on déclare la page d'accueil et/ou index.html avec le formulaire de mise à jour de la date correspondant à la fonction hanfleRoot
  server.on("/",handleRoot);
  // on démarre le serveur web
  server.begin();

}

void loop()
{
  timeClient.update();
  Serial.print("Time: ");
  Serial.println(timeClient.getFormattedTime());
  unsigned long epochTime = timeClient.getEpochTime();
  struct tm *ptm = gmtime ((time_t *)&epochTime); 
  int currentYear = ptm->tm_year+1900;
  Serial.print("Year: ");
  Serial.println(currentYear);
  
  int monthDay = ptm->tm_mday;
  Serial.print("Month day: ");
  Serial.println(monthDay);

  int currentMonth = ptm->tm_mon+1;
  Serial.print("Month: ");
  Serial.println(currentMonth);
  
red1.showNumberDecEx(red_month,0b01000000,true,2,0);
red1.showNumberDecEx(red_day,0b01000000,true,2,2);
red2.showNumberDecEx(red_year,0b00000000,true);
red3.showNumberDecEx(red_hour,0b01000000,true,2,0);
red3.showNumberDecEx(red_minute,0b01000000,true,2,2);


green1.showNumberDecEx(currentMonth,0b01000000,true,2,0);
green1.showNumberDecEx(monthDay,0b01000000,true,2,2);
green2.showNumberDecEx(currentYear,0b00000000,true);
green3.showNumberDecEx(timeClient.getHours(),0b01000000,true,2,0);
green3.showNumberDecEx(timeClient.getMinutes(),0b01000000,true,2,2);


orange1.showNumberDecEx(orange_month,0b01000000,true,2,0);
orange1.showNumberDecEx(orange_day,0b01000000,true,2,2);
orange2.showNumberDecEx(orange_year,0b00000000,true);
orange3.showNumberDecEx(orange_hour,0b01000000,true,2,0);
orange3.showNumberDecEx(orange_minute,0b01000000,true,2,2);

if((currentMonth*30 + monthDay) >= 121 && (currentMonth*30 + monthDay) < 331){
timeClient.setTimeOffset(utcOffsetInSeconds*UTC);} // Change daylight saving time - Summer
else {timeClient.setTimeOffset((utcOffsetInSeconds*UTC) - 3600);} // Change daylight saving time - Winter


if(timeClient.getHours()>=13){
  digitalWrite(greenAM,0);
  digitalWrite(greenPM,1);}
  
else if(timeClient.getHours()==12){
  digitalWrite(greenAM,0);
  digitalWrite(greenPM,1);}

else{
  digitalWrite(greenAM,1);
  digitalWrite(greenPM,0);}

// On écoute les requete http client
server.handleClient();

delay(20);

}

C’est maintenant terminé, on va téléverser notre programme sur l’ESP32 à l’aide de l’arduino IDE et pouvoir tester. Pour information, j’ai eu beaucoup de problèmes indépendants de mon programme qui ne présentait aucune erreur lors de la vérification mais lors du téléversement j’avais beaucoup d’erreurs java. J’ai du mettre à jour l’arduino IDE pour faire disparaitre ces erreurs java.

Test de l’amélioration

Il y a donc maintenant deux moyens de mettre à jour les dates « Destination Time » et « Last Time Departed », soit pas le formulaire, soit par l’API.

Par l’API

A l’aide de votre téléphone ou de votre pc, vous pouvez maintenant lancer une requête http comme par exemple :

http://adresse_ip_esp32/api?cmd=setdestime&day=01&month=01&year=2054&hour=10&minute=43

Et :
http://adresse_ip_esp32/api?cmd=setlastime&day=08&month=05&year=1945&hour=16&minute=10

Et vous avez votre horloge avec des deux dates qui sont maintenant modifiées.

Par le formulaire

A l’aide de votre téléphone ou de votre PC, lancez la requête http://adresse_ip_esp32/ dans votre navigateur, vous tombez sur le formulaire suivant :

Sur téléphone

Sur PC

Je modifie les dates et j’envoie, les deux dates de l’horloge se mettent à jour :


0 commentaire

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *