Un anémomètre WiFi -1-
Par makoto doushite le lundi, 19 novembre 2018, 21:18 - Energies Renouvelables - Lien permanent
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 :
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).
- 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.
- Insérer un roulement dans son support, puis insérer le support dans le fond.
- 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.
- 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.
- 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.
- 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.
- Reste à visser les hélices, et serrer le tout avec un écrou. (Photo en début de billet)
Le schéma :
- Pas trop compliqué…
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).
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 !
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.
- Le fichier data/js/java_vent.js, qu'on aura écrit en adaptant la librairie graphique gauge de 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
Commentaires
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 ?
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 ?
Bonjour
je viens de faire votre projet, mais lorsque je veux voir la jauge ce la ne fonction pas?
La carte est bien connecter au wifi
Merci par avance
Bonjour,
Je suis en train de faire votre anémomètre, mais je n'arrive pas à faire fonctionner correctement la carte NodeMCUv3.
le moniteur série me renvoi un message d'erreur
.
Connecté à : Livebox-D7C6
Adresse IP : 192.168.1.40
SPIFFS Mount succesfull
ISR not in IRAM!
comment puis je corriger ce problème ?
Merci d'avance.
Michael