まこと の ブログ

MaKoTo no burogu — Journal de bord…

Aller au contenu | Aller au menu | Aller à la recherche

Un anémomètre WiFi -1-

dsc03927.jpg

Récemment on m'a indiqué l'existence d'une plaquette électronique du genre Arduino, mais qui a la particularité de pouvoir « faire du WiFi ».
D'abord dubitatif quant à l'utilité du truc, étant donné que je m'étais très bien passé de la chose jusqu'à présent, le truc est resté en idle dans un coin de mon esprit malade, jusqu'à ressurgir suite à mes derniers travaux sur l'Éolienne du jardin
Hé oui ! Je me suis dit que ce serait pas mal de savoir quelle vitesse de vent serait nécessaire pour pousser sur les ailes et la faire tourner, de savoir à quelle vitesse elle tournait aussi, et de pouvoir ainsi régler la tension du ressort de vitesse de rotation constante, un peu mieux qu'au… pif.

  • J'avais donc une plaquette NodeMCUv3 LoLin (à base de puce ESP8266) sous la main et après quelques tests j'ai constaté que bah c'est comme Arduino, rien de compliqué.
  • Et puis pour faire client ou serveur Web, bah c'était pas comme Arduino… et qu'il faudrait se sortir les doigts…

Oui car on peut servir des pages web, alors on pense assez vite à ordi-phone et une jauge de visualisation.
Enfin en vrai, réflexe électronicien, j'ai tout de suite pensé afficheur à leds, mais récupérer les données via du web… wé, je garde l'idée… Alors :

Pour mon projet final j'aurais besoin d'une plaquette NodeMCU en mode serveur web, perchée sur l'éolienne, pour remonter les mesures de rotation de l’anémomètre (vent) et de l'éolienne (rpm).
Les data seraient consultables via un navigateur sur un ordi ou un ordi-phone, sous forme de jauge de vitesse instantanée.
Elles seraient aussi récupérable pour former des graphiques de statistiques.
Un second NodeMCU avec des afficheurs à leds serait utilisé pour s'affranchir d'un ordi.

  • Bon c'est pas forcément facile à suivre, alors voici un dessin :

anemometre3.png

Simple anémomètre :

  • Bref, pour le moment on va juste fabriquer un anémomètre simple, avec une jauge sur ordi.

(voir même sur internet si on fait le nécessaire pour faire « sortir » les pages web).

Matériel requis :
dsc03947.jpg

- La mécanique imprimée en 3D disponible ici.
- 1 Capteur à effet Hall US1881 (absent de cette photo).
- 2 aimants permanents au néodyme ∅6 mm x 3 mm (absent de cette photo).
- 1 plaquette NodeMCUv3 LoLin.
- 1 résistance 10kΩ.
- 2 roulements à billes : ∅5 int x ∅10 ext x 4 mm.
- 1 tige filetées : ∅5 mm de 10 mm de long.
- 5 écrous de ∅5 mm.
- 3 vis : ∅3 mm de 10 mm de long (tête fraisée).
- 3 vis : ∅4 mm de 12-15 mm de long (tête poêlée).
- Un ordi avec port USB et le soft Arduino IDE.


Compétences requises :

- Électronique.
- Web design (html, css, JavaScript, Json).
Où sinon t'as du temps et l'âme d'un bidouilleur et t'y arriveras !… du coup j'ai appris plein de trucs.


Le montage :

  • Commençons par insérer les écrous dans les logements prévu après avoir percé les opercules (permettant l'impression au dessus des trous sans supports), puis à fermer la structure avec les vis de ∅3 mm.

dsc03944.jpg dsc03946.jpg

  • Insérer un roulement dans son support, puis insérer le support dans le fond.

dsc03935.jpg dsc03934.jpg

  • Préparer la tige filetée avec deux écrous bloqués à 3 mm du bord de la tige. L'idée c'est qu'une fois en place sur le roulement la tige puisse tourner librement.

dsc03936.jpg dsc03937.jpg

  • Ensuite, régler la hauteur du support d'aimants (en gris, aimants pas encore dispo sur la photo) pour qu'il soit à hauteur du logement du capteur Hall (une des petites fentes, capteur pas encore dispo sur la photo). Le NodeMCU se loge simplement à l'endroit prévu.

dsc03940.jpg dsc03941.jpg

  • Voilà, on peut mettre le roulement du haut et fermer le bas avec les vis de ∅4 mm après avoir taraudé les trous de vis. Le socle est donc ici adapté pour s'enficher sur le mât de l'éolienne, en lieu et place du cône que j'avais imprimé alors.

dsc03943.jpg dsc03932.jpg

  • Coller le chapeau à la cyanoacrylate par dessus (après avoir percé l'opercule) puis placer un écrou pas trop bas, et visser le col par dessus après l'avoir taraudé au ∅5 mm, voire même ajouté du vernis/résine de blocage au filetage. Ceci devrait permettre de protéger le boîtier et le roulement de la pluie.

dsc03931.jpg dsc03930.jpg

  • Reste à visser les hélices, et serrer le tout avec un écrou. (Photo en début de billet)



Le schéma :

  • Pas trop compliqué…

Anemometre01_bb.png

Le câblage :

  • C'est facile à câbler… Et il suffit de glisser le capteur à effet Hall dans une des deux fentes prévues. Avec le capteur US1881 il faut placer deux aimants sur le support, un orienté pôle nord, et l'autre pôle sud (cf.datasheet).

dsc03949.jpg dsc03952.jpg

Programmation du NodeMCU :

  • Pour programmer un NodeMCU avec l'Arduino IDE il faudra rajouter le support du module esp8266, voici 3 pages qui vous expliqueront comment faire : Via fais-le-toi-meme.fr ou henrys-bench.

Tout le code de l'anémomètre est téléchargeable ici ou en annexe à ce billet.
Créer un dossier qui contiendra cette arborescence :

Anemometre_esp8266_WifiSVR_SPIFFS_Hall/Anemometre_esp8266_WifiSVR_SPIFFS_Hall.ino
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/index.html
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/css/style.css
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/js/java_vent.js
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/js/jquery.min.js
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/js/loader.js
  • Ainsi pour programmer la plaquette, il suffira de procéder au téléversement du projet Arduino, ça c'est comme d'habitude avec l'Arduino IDE.

Contrairement à un Arduino classique, l'upload peut s'avèrer être très long, on peut donc augmenter la vitesse via le menu Outils et sélectionner Upload Speed : 921600

  • Et pour téléverser les fichiers html, css et JavaScript, il faudra cliquer Outils et cliquer ESP8266 Sketch Data Upload, ce qui aura pour effet d'immédiatement copier les fichiers contenu dans le dossier data sur la plaquette.

Sauf que ce menu n'est pas disponible par défaut !
Il faut en effet télécharger un fichier à déposer dans le dossier du « carnet de croquis », sous une arborescence spécifique, ce qui donne chez moi : /home/user/Arduino/tools/ESP8266FS/tool/esp8266fs.jar
Tout est expliqué ici : https://github.com/esp8266/arduino-esp8266fs-plugin


Fonctionnement :
Ensuite ouvrir Outils > Moniteur série , qui devrait afficher l'adresse IP de la plaquette (sinon appuyer sur le bouton Reset), et rendez-vous sur un navigateur avec cette IP en URL et voila !
anemometre.png
C'est une petite entrée en matière intéressante de la conception d'un « appareil connecté », j'ai découvert comment tout ça s'articule…
Plus à l'aise avec l'électronique, je touche mes limites techniques concernant la partie développement web, avec pas mal de méconnaissances du sujet qu'il faut que je travaille (wé j'en suis resté au web 1.0…), en vue dans de prochains billets, d'aborder les divers éléments liés à mes besoins plus spécifiques.

Principe :
L'aimant passe devant le capteur à effet Hall à chaque rotation de l'axe de l'anémomètre, ce qui envoie une impulsion qui est alors réccupérée par le NodeMCU pour être traitée afin de mesurer la vitesse de rotation, puis de la convertir en Km/h. Cette mesure est envoyée au serveur Web sous la forme d'un fichier JSON écrit en zone SPIFFS, qui est mis à jour toutes les secondes (valeur réglable au début du code Arduino)

Présentation du contenu des fichiers :
J'ai commenté assez largement le code, mais n'espérez pas tout comprendre si un des langages vous échappe…

Le fichier JSON ressemble à ceci :

{
  "VitesseVent":"25"
}

Lorsqu'on consulte la page Web, le JavaScript contenant la jauge est appelé et celui-ci récupére la valeur du JSON pour animer l'aiguille et afficher la valeur, toutes les secondes (en adéquation avec le réglage du code Arduino)

  • Le fichier data/js/jquery.min.js est une libraire standard (ou un truc du genre) qui se télécharge sur internet.
  • Le fichier data/js/loader.js est une libraire google (ou un truc du genre) qui se télécharge chez google chart.
google.charts.load('current', {
        'packages': ['gauge']
      });
      google.charts.setOnLoadCallback(drawChart); //  https://developers.google.com/chart/interactive/docs/gallery/gauge

      function drawChart() {    // Fonction principale : 

        // Create and populate the data table.
        var dataGaugeVent = google.visualization.arrayToDataTable([
          ['Label', 'Value'],
          ['Vent', 0],
        ]);

        // formatage avec un suffixe et # pour arrondir
        var formatter = new google.visualization.NumberFormat({
          suffix: ' Km/h',
          pattern: '#'
        });

        // définition des options documentée ici https://developers.google.com/chart/interactive/docs/gallery/gauge
        var options = {
          width: 800, height: 720,
          greenFrom:0, greenTo: 60,   // zones de couleurs
          yellowFrom:60, yellowTo: 80,
          redFrom: 80, redTo: 100,
          majorTicks: ['0', 10, 20, 0, 0, 50, 0, 0, 80, 90, 100], // graduations
          minorTicks: 5, // graduations
          max: 100, min: 0,
          animation: {
            duration: 100,  // vitesse de l'aiguille
            easing: 'linear',   // comportement de l'aiguille
          }
        };

        // init du graphisme
        var GaugeVent = new google.visualization.Gauge(document.getElementById('chart_div_vent'));

        // tracé du graphisme
        GaugeVent.draw(dataGaugeVent, options);
        updateGauge();  // exécute la fontion
        setInterval(updateGauge, 100); // appelle les données de la fonction et définit la vitesse de rafraichissement

        function updateGauge() {     // fonction de mise raffraichissement des données réccupérée dans le fichier json https://www.w3schools.com/jquery/ajax_getjson.asp

          $.getJSON('/mesures.json',

            function(data) {

              $.each(data,

                function(nom, valeur) {

                  dataGaugeVent.setValue(0, 1, valeur); // premier nb pour le N° de la gauge si plusieurs, puis 0 pour modifier le champ label (sinon:1 pour le champ Value), puis la valeur extraite du json
                  GaugeVent.draw(dataGaugeVent, options); // tracé du graphisme
                  formatter.format(dataGaugeVent, 1); // applique le formattage à la seconde collonne du tableau (1) qui correspond à la valeur

                });
            });
        }
      }
  • Le fichier data/css/style.css pour la mise en page :
.container_inner {
   background-color: #555555;
  width: 450px;
  margin-left: -165px;
  padding-left: 60px;
  padding-top: 160px;
  padding-bottom: 160px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
  • Le fichier data/index.html, où l'on charge les 3 JavaScripts et la feuille de style css. Puis on y appelle le graphisme de la gauge.
<!DOCTYPE html>
<html>
	<head>
		<title>Eolienne</title>
		<link rel="stylesheet" type="text/css" href="css/style.css">
		<script type="text/javascript" src="js/jquery.min.js"></script>
		<script type="text/javascript" src="js/loader.js"></script>
		<script type="text/javascript" src="js/java_vent.js"></script>
	</head>
  
	<body>
		<div class="container_inner">
			<div id="chart_div_vent"></div>
      </div>
	</body>
</html>
  • Le fichier Anemometre_esp8266_WifiSVR_SPIFFS_Hall.ino, qui contient le code C++ type « Arduino », pour mesurer la vitesse de rotation et envoyer les données au serveur Web.
#include <ESP8266WebServer.h>
#include <FS.h>
#include <WiFiUdp.h>  //pour upload de pgm Arduino via wifi
#include <ArduinoOTA.h> //pour upload de pgm Arduino via wifi

/****************/
/* DÉCLARATIONS */
/****************/
ESP8266WebServer server ( 8080 );   // on instancie un serveur ecoutant sur le port 80
#define pinHallAnemo D2   // le capteur à effet Hall est connecté à la pin D2
#define ssid      "xxxx"    // WiFi SSID
#define password  "****"  // WiFi password
unsigned long rpmVent = 0;
unsigned long vitVentKMH = 0;
unsigned long dateDernierChangementVent = 0;
unsigned long dateDernierChangementKMH = 0;
float intervalleKMH = 0;

/*********/
/* SETUP */
/*********/
void setup() {
  Serial.begin ( 115200 );    // init du mode débug
  // Connexion au WiFi
  WiFi.begin ( ssid, password );
  // Attente de la connexion au réseau WiFi / Wait for connection
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 ); 
    Serial.print ( "." );
  }
  // Connexion WiFi établie
  Serial.println ( "" );
  Serial.print ( "Connected to " ); Serial.println ( ssid );
  Serial.print ( "IP address: " ); Serial.println ( WiFi.localIP() );

  // Montage de la zone mémoire SPIFFS
  if (!SPIFFS.begin()) {
    Serial.println("SPIFFS Mount failed");
  } 
  else {
    Serial.println("SPIFFS Mount succesfull");
  }
  delay(50);

  // Pin capteurs
  attachInterrupt(pinHallAnemo, rpm_vent, FALLING); 
  
  // Pages web du serveur
  server.serveStatic("/js", SPIFFS, "/js");       // dossier js qui contient les fichiers JavaScripts
  server.serveStatic("/css", SPIFFS, "/css");     // dossier css qui contient les fichiers css
  server.serveStatic("/", SPIFFS, "/index.html"); // racine du serveur, pointe l'index.html
  server.on("/mesures.json", sendMesures);        // écrit le fichier json à l'appel de la fonction
  server.begin();                                 // démarre le serveur
  Serial.println ( "HTTP server started" );
  ArduinoOTA.setHostname("AnemometreWiFi");   // on donne une petit nom a notre module, pour upload de pgm Arduino via wifi
  // ArduinoOTA.setPassword((const char *)"1357");
  ArduinoOTA.begin();   // initialisation de l'OTA, pour upload de pgm Arduino via wifi
}

/*************/
/* FONCTIONS */
/*************/
void rpm_vent()   // appelée par l'interruption, Anémomètre vitesse du vent.
{ 
  unsigned long dateCourante = millis();
  intervalleKMH = (dateCourante - dateDernierChangementVent);
  Serial.print ( "intervalle en s : " );
  Serial.println (intervalleKMH/1000); // affiche l'intervalle de temps entre deux passages
  if (intervalleKMH != 0)  // attention si intervalle = 0, division par zero -> erreur
  {
    rpmVent = 60 / (intervalleKMH /1000);  
  }
  vitVentKMH = ( rpmVent / 12 );
  Serial.print ( "vitVentKMH : " );
  Serial.println ( vitVentKMH ); // affiche les rpm  
  Serial.println ( "" );
  dateDernierChangementVent = dateCourante;
}


void sendMesures()    // appelée par le serveur web
{  
 String json = "{"rpm":"" + String(vitVentKMH) + ""}";
// prépare et formate la valeur pour le fichier json sous la forme : {"VitesseVent":"0.00"}
//                          {
//                            "VitesseVent":"25"
//                          }
  server.send(200, "application/json", json);   // envoie dans le valeur dans le fichier json qui tourne en mémoire
//  Serial.println("Mesures envoyees");
}


void RemiseZeroVitVentKMH ()
{
  unsigned long dateCouranteKMH = millis();
  if (intervalleKMH == intervalleKMH) // Si ça ne tourne plus (valeur plus mise à jour)
  {  
    float dureeKMH = (dateCouranteKMH - dateDernierChangementKMH);
    if (dureeKMH > 10000) // Si ça ne tourne plus depuis 10 secondes
    {
      Serial.print ( "dureeKMH : " );
      Serial.println ( dureeKMH ); // affiche les rpm  
      vitVentKMH = 0;  // Remsise à zero !
      dateDernierChangementKMH = dateCouranteKMH;    
    }
  }
}

/*************/
/* PROGRAMME */
/*************/
void loop()
{
  server.handleClient();  // à chaque iteration, on appelle handleClient pour que les requetes soient traitees
  RemiseZeroVitVentKMH ();
  delay(100); // la boucle fait tourner sendMesures(), via handleClient, régler delais si besoin de mettre à jour le JSON qu'à une fréquence voulue plutôt qu'instantanément 
  ArduinoOTA.handle();  // régler upload speed à 9600 : verifie si un upload de programme Arduino est envoyé sur l'ESP8266
}

Projet inspiré de celui-ci :
https://projetsdiy.fr/projet-diy-anemometre-girouette-objet-connecte-esp8266/
https://projetsdiy.fr/esp8266-web-serveur-partie5-gauges-graphiques-google-charts/#top_ankor

À Suivre…

Commentaires

1. Le lundi, 7 janvier 2019, 13:28 par Chrismart

Hello,

Interessant, je vais m'en faire un, merci pour le partage :)
Par contre je vais peut etre choisir de passer en 433Mhz plutot que wifi car j'ai peur que le module consomme pas mal en envoyant des données tout le temps (le mien sera alimenté en pile).

Comment as tu prévu de l'alimenter (surtout s'il est en haut de ton mat) ?
As tu testé sa conso ?

2. Le lundi, 7 janvier 2019, 15:39 par Makoto

Il consomme effectivement autour de 100mA (de mémoire, il faudrait que je refasse des mesures), et pour le moment il est raccordé à un adaptateur secteur sur le mât, en attendant que je lui bricole un module de recharge de batterie 3,7V sur mini panneaux solaire, à moins d'attendre que l'éolienne soit capable de générer un peu de courant.
Quel type de matériel 433Mhz viserais-tu ?

Ajouter un commentaire

Les commentaires peuvent être formatés en utilisant une syntaxe wiki simplifiée.

Fil des commentaires de ce billet