Loading icon
Réalisation DIY interface web

Voici un article que je voulais faire depuis un moment. Sur le web il y a déjà des articles expliquant comment faire tel ou tel chose mais 99% du temps c’est une connexion avec une application style « Blynk ». Moi ça ne me convient pas ! Car il faut télécharger l’application, se créer un compte (dans la plupart des cas) et rester bloqué avec ce que propose l’application.

C’est pourquoi, aujourd’hui on va voir comment utiliser nouvelle carte (une WeMos D1 mini Pro) pour récupérer une température, l’humidité et pouvoir actionner une lampe via notre smartphone.

Le tout se trouvera dans une page Web que l’on va réaliser et de ce fait on contrôlera tout : design, sécurité, action etc.

Plusieurs avantages :

  • avoir une interface pour tout contrôler
  • faire travailler les langages web avec l’arduino (et pourquoi pas réaliser des actions automatiquement)
  • gestion du design (on aura quelque chose de différent et adapter à nos besoins)
  • faire travailler les technos web et utiliser l’arduino juste pour les données

Il y a aussi des inconvénients :

  • il faut s’y connaitre un minimum sur les technos web
  • cela prend plus de temps pour la mise en œuvre

Ce qu’on va faire

On va réaliser une page web classique. Le WeMos va récupérer la température et l’humidité via le capteur et renvoyer l’info au format JSON afin de pouvoir la lire côté techno web. Il y aura également une action sur le WeMos permettant d’allumer ou éteindre une lampe (ici une Led)

Côté Web, on aura la page qui listera 3 choses :

  • un bouton permettant d’allumer ou d’éteindre la Led
  • la température
  • l’humidité

A chaque fois qu’on ira sur cette page, un appel se fera vers le WeMos afin de récupérer la température et l’humidité et ensuite on affichera les données. On récupérera aussi l’état de notre Led : allumé ou éteinte ?

Le bouton permettant d’allumer ou d’éteindre la Led sera un bouton classique web et au clic sur ce dernier, cela enverra une action au WeMos pour allumer ou éteindre la Led.

On va toucher à pas mal de langage :

  • html / css / js pour réaliser la petite page web
  • et évidemment la carte D1 mini (mais une autre carte avec le wifi fonctionnera tout aussi bien)

Et comme on a envie de s’amuser on va faire en sorte que tout ceci fonctionne sur batterie.

Prérequis

La page Web

On va faire simple pour notre exemple et prendre un code sur codepen que je vais un petit peu adapter.

L’idée va être d’avoir à gauche « Activer le GPIO » afin de pouvoir dire en cliquant dessus : active toi ou désactive toi. Ensuite ce qui sera relié au GPIO peut être tout et n’importe quoi :

  • un relais
  • une led
  • un cerveau
  • etc..

Le reste des éléments sera uniquement de l’affichage afin de nous donner les informations du capteur de température/humidité.

(le code de la page sera disponible à la fin de l’article)

Le schéma de branchement

C’est du classique, ici on branche juste plusieurs choses :

  • un capteur DHT22 relié au WeMos D1 mini Pro (sur une PIN digital : ici D7)
  • une led relié au WeMos D1 mini Pro (sur une PIN digital : ici D1)
  • 2 résistances de 470KΩ et 1MΩ de pour notre pont diviseur de tension que l’on reliera au WeMos D1 mini Pro (sur le PIN analog : A0)

Pourquoi un pont diviseur de tension ?

La réponse est simple, les PINS analog sur le WeMos sont limités à 3,2V MAX donc il faut abaisser les 4,2V afin d’éviter de tout faire cramer.

C’est quoi un pont diviseur ? Je vous laisse aller voir mon autre article détaillant le sujet 🙂

En simplifié : on va faire en sorte que sur le PIN A0 on ne dépasse pas 3,2V et on va utiliser le PIN A0 pour connaitre le voltage de la batterie afin de l’afficher.

Pour ce faire on va avoir besoin de 2 résistances :

  • R1 de 400KΩ
  • R2 de 1MΩ

Vous pouvez trouver les valeurs des résistances via mon article ci-dessus. J’ai volontairement choisis des résistances afin d’avoir une tension de 3v (et non de 3,2v) histoire d’avoir une marge de sécurité.

N’ayant pas de résistance de 400KΩ sous la main, j’ai utilisé la plus proche que j’avais à savoir une de 470KΩ donc j’obtiens une tension de 2,9v. Et c’est avec cette info que l’on va voir le reste du projet.

Place au code

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

// ajout de la lib DHT
#include <DHT.h>
// création d'une constante qui aura pour nom DHTTYPE et pour valeur DHT22
#define DHTTYPE DHT22

// initialisation de la PIN qui recoit les datas de notre module
// dans mon cas, la PIN digital 7
const int DHT22_PIN = D7;

// Le pin que l'on va utiliser pour notre Led
const int LED_PIN = D1;

// Permet de lancer le serveur sur le port 80
ESP8266WebServer server(80);

// initialisation de la class DHT22 via le mot clé DHT
// dht minuscule est simplement le nom que je lui donne, on pourrait l'appeler captain sans souci :) mais plus le code est clair et plus la lecture sera simple
// en paramètre, la PIN et la lib
DHT dht(DHT22_PIN, DHTTYPE);


#ifndef STASSID
#define STASSID "Captain"
#define STAPSK  "arduino"
#endif

/**
 * J’initialise des variables pour la suite :)
 */
int result = 0;
unsigned int raw=0;
float volt=0.0;

// R1 : 470K
// R2 : 1M

const float coeff_pont = 0.68; // R2 / ( R1 + R2 ) R1 et R2 en ohms


const float TensionAnalog = 3.2;

void setup() {
  /**
   * on force l'IP Fixe et on tente de se connecter au Wifi
   */
  IPAddress ip(192, 168, 1, 97);
  IPAddress dns(192,168,1,254);
  IPAddress gateway(192,168,1,254);
  IPAddress subnet(255, 255, 255, 0);

  WiFi.config(ip, dns, gateway, subnet);
  
  WiFi.begin(STASSID, STAPSK);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  pinMode(A0, INPUT);
  pinMode(LED_PIN, OUTPUT);
  dht.begin();

  /**
 * Configuration des routes
 */
  server.on("/dht", HTTP_GET, viewDht); // retourne les données du capteur au format json
  server.on("/led", HTTP_GET, viewLed); // retourne l'état de la led au format json
  server.on("/volt", HTTP_GET, viewVolt); // retourne l'état de la batterie
  server.on("/led", HTTP_POST, updateLed); // permet de modifier l'état de la led et retourne le nouvel état au format json
  
  server.onNotFound(viewNotFound); // Il faut penser aux urls qui n'existent pas (les 404)

  // Lancement du serveur
  server.begin();
}

void loop() {
    

  if ((WiFi.status() == WL_CONNECTED)) {
      server.handleClient();
  
  }
  
  delay(500);
}


/**
 * Gestion des 404 : un simple texte
 */
void viewNotFound() {
  server.send(404, "text/plain", "404: Not found");
}

/**
 * 
 */
void viewVolt() {
  
    raw = analogRead(A0); 
    float tension_bat = ((raw * ( TensionAnalog / 1024)) / coeff_pont);

  /**
 * Configuration de la variable JSON pour le return
 */
  String messageResponse = "\"voltage\":\n";
  messageResponse += String(tension_bat) ;
  

/**
 * Access-Control-Allow-Origin est très IMPORTANT ! 
 * Cela renvoie une réponse indiquant si les ressources peuvent être partagées avec une origine donnée
 * Dans notre cas, je lui dit : tu partages avec tout le monde
 */
  server.sendHeader("Access-Control-Allow-Origin", "*");
  server.send(200, "application/json", "{" + messageResponse + "}");
}

/**
 * Mise à jour de la led
 */
void updateLed() {

  // si le paramètre qu'on a envoyé (show) vaut on allume sinon on éteind
  if (server.arg("show") == "1") {
    digitalWrite(LED_PIN, HIGH);
    result = 1;
  } else {
    digitalWrite(LED_PIN, LOW);
    result = 0;
  }

  /**
 * Configuration de la variable JSON pour le return
 */
  String messageResponse = "\"currentLed\":\n";
  messageResponse += result;
  

/**
 * Access-Control-Allow-Origin est très IMPORTANT ! 
 * Cela renvoie une réponse indiquant si les ressources peuvent être partagées avec une origine donnée
 * Dans notre cas, je lui dit : tu partages avec tout le monde
 */
  server.sendHeader("Access-Control-Allow-Origin", "*");
  server.send(200, "application/json", "{" + messageResponse + "}");
}

/**
 * Fonction permettant de savoir si la led est allumé ou éteinte
 * Dans le HTML de la fonction viewWeb() j'ai mis en place un appel fetch (javascript) afin d'appeler cette route (avec une methode GET) : [votre_IP]/led par exemple : http://192.168.1.42/led
 * Cette fonction retourne un format json pour dire 0 ou 1 si la led est éteinte ou allumé
 */
void viewLed() {
  int currentLed = 0;
  /**
   * On récupère l'info du PIN : HIGH ou LOW donc 1 ou 0
   * Si on est HIGH => cela signifie que la LED est allumé, donc la variable currentLed passe à 1
   * Sinon on fait rien car la variable currentLed est déjà à 0
   */
  if (digitalRead(LED_PIN)) {
    currentLed = 1;
  }

/**
 * Configuration de la variable JSON pour le return
 */
  String messageResponse = "\"currentLed\":\n";
  messageResponse += currentLed;

/**
 * Access-Control-Allow-Origin est très IMPORTANT ! 
 * Cela renvoie une réponse indiquant si les ressources peuvent être partagées avec une origine donnée
 * Dans notre cas, je lui dit : tu partages avec tout le monde
 */
  server.sendHeader("Access-Control-Allow-Origin", "*");
  server.send(200, "application/json", "{" + messageResponse + "}");
}


/**
 * Fonction permettant de récupérer les données du capteur de température
 */
void viewDht() {
   float h = dht.readHumidity(); 
   float t = dht.readTemperature(); 
   

/**
 * Configuration de la variable JSON pour le return
 */
  String messageResponse = "\"temperature\":\n";
  messageResponse += String(t);
  messageResponse += ",\"humi\":\n";
  messageResponse += String(h);
          


/**
 * Access-Control-Allow-Origin est très IMPORTANT ! 
 * Cela renvoie une réponse indiquant si les ressources peuvent être partagées avec une origine donnée
 * Dans notre cas, je lui dit : tu partages avec tout le monde
 */
  server.sendHeader("Access-Control-Allow-Origin", "*");
  server.send(200, "application/json", "{" + messageResponse + "}");
}

Le code est assez simple, c’est du code qu’on a déjà vu mais simplement avec un webserver et des routes sur lesquelles les actions s’exécutent.

La seule petite chose qui change est la partie sur la récupération du voltage de la batterie :

raw = analogRead(A0); 
((raw * ( TensionAnalog / 1024 )) / coeff_pont);
  • on récupère la valeur analog (raw)
  • TensionAnalog correspond au voltage max du WeMos sur les PINS analog
  • 1024 est la valeur max du pin analog
  • coeff_pont correspond au coefficient de notre point diviseur de tension (R2 / (R1 + R2))

Petite précision : Récupérer la tension de la batterie via le PIN analog est pratique mais pas 100% fiable. C’est pratique pour de petit projet ne demandant pas un calcul très précis donc dans notre cas c’est parfait mais si vous souhaitez être précis, il faudra vous tourner vers d’autres système et façon de faire.
Ici ,l’idée c’est uniquement d’avoir une estimation du niveau de batterie, donc personnellement je prendrais les valeurs MIN et MAX de ma batterie 18650 donc 3v et 4,2v.
Ensuite je prendrais une petite sécurité : 3,2v et 4v et je ferais mes calcules par rapport au nouveau MIN et MAX. 100% Pour 4v et 0% pour 3,2v et j’irais de 10% en 10% afin d’avoir la plage de valeurs complète.

Une fois le code en place sur le WeMos, il reste plus qu’a se rendre sur la page HTML et op tout devrait fonctionner comme il faut.

Si vous avez un souci, pensez à regarder les points suivant :

  • l’IP est la bonne ?
  • l’assignation de l’IP fixe est correcte (il peut y avoir des changements en fonction de votre BOX internet, cet article peut vous aider)
  • si vous avez d’autres résistances, il faudra penser à corriger la variable coeff_pont

Points d’améliorations

Ce projet vous permet de bien prendre en main le webserver et ensuite d’y faire tout ce que vous voulez. Et l’avantage d’utiliser des technos Web pour récupérer les infos permet d’aller encore plus loin.

Par exemple :

  • utiliser php et MySQL afin de stocker les valeurs du capteur de température et la tension de la batterie. Cela permettrait d’avoir un affichage rapide de la page (pas comme ici car à chaque rechargement on fait des requêtes vers le WeMos et ce n’est pas très optimisé). Le mieux serait d’utiliser le WeMos en mode DeepSleep afin que ce dernier se réveille chaque heure afin d’envoyer les infos à une page PHP qui s’occuperait de stocker le tout en base de données. De ce fait à chaque fois qu’on afficherait la page, on aurait les données de la base et non des connexions directe du WeMos. L’autre avantage est qu’on peut utiliser les technos Web pour réaliser des fonctions différentes comme par exemple : des graphes de températures, des alertes après un certain seuil de la batterie, etc.

Démo

Téléchargement HTML WEMOS Webserver Téléchargement du Sketch Wemos Webserver

Si cet article vous a plu, n’hésitez pas à laisser un commentaire, noter et partager l’article.

Partage :
Share on Facebook
Facebook
Tweet about this on Twitter
Twitter
0
J'aimerais avoir votre avis, merci de commenter.x