まこと の ブログ - Mot-clé - ESP8266MaKoTo no burogu — Journal de bord…2024-03-28T19:46:56+01:00MaKoTourn:md5:c74815e3268f2d506228368f0d9c6d01DotclearTempéro, thermomètres connectés -02-urn:md5:1d75b6e54c522158af4aa7e6d9807b822022-07-03T20:01:00+02:002022-07-05T18:44:04+02:00makoto doushiteÉlectroniqueArduinoDIYESP8266NodeMCU <p><a href="http://burogu.makotoworkshop.org/index.php?post/2022/06/25/tempero1">Précédemment sur makotoworkshop.org…</a> :<br /></p>
<blockquote><p>À priori, non, tu ne met pas ton capteur de <em>DHT22</em> dehors « comme ça », et encore moins accroché au mur de ta fenêtre.<br /></p></blockquote>
<p>C'est ce que j'ai assez vite déduit aux vues des résultats de recherche sur <em>Thingiverse</em>, en quête d'inspiration pour un modèle de boîtier.<br />
En effet, il semble finalement assez logique de se tenir aussi éloigné que possible des murs du bâtiment, au risque sinon de se retrouver à mesurer la T° résiduelle emmagasinée par celui-ci, et malgré ça, on ne peut pas non plus imaginer laisser le capteur cuire en plein soleil…<br /></p>
<blockquote><p>Une fois de plus ce fût l'occasion d'apprendre de nouvelle choses, et en cela, l’existence du « Stevenson shelter », un abris ventilé dans lequel on place les instruments de mesure pour les protéger du soleil tout en les laissant prendre le vent.<br /></p></blockquote>
<p>J'ai pu trouver le modèle qui me convenait et de l'adapter à mon besoin en le « remixant » en <em><a href="https://www.thingiverse.com/thing:5424654">Stevenson shelter pour balcon</a></em>.<br /></p>
<ul>
<li>Arès avoir imprimé toutes les pièces déterminantes en blanc, évidemment ici pour profiter de l'effet albédo, j'ai fait un essai d'assemblage de la soucoupe du bas avec la glissières.</li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc06013.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc06013_m.jpg" alt="" /></a><br />
<a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc05980.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc05980_s.jpg" alt="" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc05981.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc05981_s.jpg" alt="" /></a><br />
Grâce aux tête fraisées des vis la glissière fait son office correctement.<br /></p>
<ul>
<li>Les trous de cette soucoupe sont plus petits et destinés à être taraudés donc, pour accueillir les vis de ⌀4 mm.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc05984.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc05984_s.jpg" alt="" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc05982.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc05982_s.jpg" alt="" /></a><br /></p>
<ul>
<li>Ensuite collage du mille-feuille en m'aidant des trous prévus à l'origine pour des tiges filetées afin de bien aligner les pièces. Le capteur <em>DHT22</em> ainsi fixé à son support vient se loger au centre :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc06015.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc06015_s.jpg" alt="" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc06018.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc06018_s.jpg" alt="" /></a><br /></p>
<ul>
<li>Reste à visser la glissière en place.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc06019.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc06019_t.jpg" alt="" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc06023.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc06023_t.jpg" alt="" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc06021.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc06021_t.jpg" alt="" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc06020.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc06020_t.jpg" alt="" /></a><br /></p>
<ul>
<li>Une fois la seconde partie de la glissière fixée à la rambarde du balcon à l'aide de serre-câbles, il suffit de glisser notre <em>stevenson shelter</em> en place et de ligaturer une attache dans la boucle prévue pour éviter qu'il ne bouge.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc06025.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc06025_s.jpg" alt="" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/tempero/dsc06024.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.dsc06024_s.jpg" alt="" /></a><br /><br /></p>
<h3>À suivre…</h3>http://burogu.makotoworkshop.org/index.php?post/2022/07/03/tempero2#comment-formhttp://burogu.makotoworkshop.org/index.php?feed/atom/comments/727Tempéro, thermomètres connectés -01-urn:md5:20df9bde2d329fe6a02d270f8be9ad8a2022-06-26T21:18:00+02:002022-07-05T18:44:36+02:00makoto doushiteÉlectroniqueArduinoDIYESP8266NodeMCU <blockquote><p>Ayant pu expérimenter les capteurs de température dans le but de réguler la température interne des bornes <em><a href="http://burogu.makotoworkshop.org/index.php?post/2021/09/23/jubeat06">jubeat</a></em> et <em><a href="http://burogu.makotoworkshop.org/index.php?post/2022/05/18/sdvx5">Sound Voltex</a></em>, la thématique estivale des températures records aidant, j'ai eu envie de m'essayer à bricoler une petite station météo partielle, sachant que le boulot serait pas mal inspiré de mes précédents travaux sur l'<a href="http://burogu.makotoworkshop.org/index.php?post/2018/11/12/anemometre">anémomètre</a> (la version <em>WiFi</em>)</p></blockquote>
<p>Partielle car il manquerait un pluviomètre et l'absence d'anémomètre va permettre je pense l'utilisation d'une alimentation sur batterie solaire, mais nous étudierons cela plus tard, commençons déjà par expérimenter.<br /><br /></p>
<h3><ins>Câblage</ins> :<br /></h3>
<blockquote><p>Un capteur <em>DHT22</em> est situé à l'intérieur de l'habitat.<br />
Un autre capteur <em>DHT22</em> est placé à l'extérieur de l'habitat.<br />
Tous deux connectés sur un <em>NodeMCU</em> (plaquette à base d<em>'esp8266</em>) chargé d'envoyer les valeurs de températures et d'humidité sur un afficheur <em>LCD</em> connecté en <em>I²C</em>, et également sur un serveur web <em>influxDB</em> + <em>Grafana</em> pour tracer des courbes dans le temps.<br /></p></blockquote>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/Tempero_schema_AlimSecteur.png"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.Tempero_schema_AlimSecteur_m.png" alt="" style="display:table; margin:0 auto;" /></a><br /></p>
<ul>
<li>Voici la maquette câblée, avec le module <em>I²C</em> bien pratique, soudé au dos de l'afficheur <em>LCD</em> :</li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/20220626_123212.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.20220626_123212_s.jpg" alt="" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/tempero/20220626_123309.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.20220626_123309_s.jpg" alt="" /></a><br /><br /></p>
<h3><ins>Programme</ins> :<br /></h3>
<ul>
<li>Le code utilisé est disponible en annexe du billet<sup>[<a href="http://burogu.makotoworkshop.org/index.php?post/2022/06/25/tempero1#wiki-footnote-1" id="rev-wiki-footnote-1">1</a>]</sup> et sur mon <em>github</em>.<br /></li>
</ul>
<p><a href="https://github.com/makotoworkshop/nodeMCU_tempero_AlimSecteur">https://github.com/makotoworkshop/nodeMCU_tempero_AlimSecteur</a>.<br /></p>
<ul>
<li>J'attire cependant l'attention du bidouilleur attentif.<br /></li>
</ul>
<blockquote><p>En effet le code utilisé dans le fichier <em>ESPinfluxdb.cpp</em> n'est plus compatible avec la librairie de carte disponibles dans l<em>'Arduino IDE</em> que j'utilise pour programmer le <em>nodeMCU</em>.<br />
Pour disposer de la carte <em>NodeMCU 1.0 (ESP-12E Module)</em> dans l<em>'IDE</em> il faut avoir au préalable chargé la carte, ce qui se fait en deux temps :</p></blockquote>
<p>1 - Ajouter l'adresse <em>https://arduino.esp8266.com/stable/package_esp8266com_index.json</em> à la case <em>URL de gestionnaire de cartes supplémentaires</em> depuis le menu <em>Fichier</em> > <em>Préférences</em> > onglet <em>Paramètres</em>.<br />
2 - Ajouter la carte depuis le menu <em>Outil</em> > <em>Type de carte</em> > <em>Gestionnaire de Carte</em>, puis<br /></p>
<blockquote><p>rechercher <em>esp8268</em> et on trouve <em>esp8268 by ESP8266 Community</em> dont la dernière version est la 3.0.1, et qui refuse de compiler le code dudit fichier avec des erreurs à base de machin « deprecated blablabla use WiFiClient… ».<br />
J'ai eu beau modifier le code, je ne suis pas parvenu à circonscrire les erreurs de compilation, aussi j'ai rétrogradé à la version 2.4.2, celle-là même qui fonctionnait à l'époque de mes bricoles avec l'anémomètre<em>WiFi</em>.<br /></p></blockquote>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/Tempero02.png"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.Tempero02_m.png" alt="" /></a><br />
Au démarrage du programme, différents messages s'affichent pour indiquer la connexion au <em>WiFi</em>, puis la connexion à la base de donnée <em>influxDB</em>, ainsi qu'un avertissement en cas de problème avec les capteurs.<br /></p>
<ul>
<li>Ensuite on devrait obtenir ceci :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/20220626_124108.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.20220626_124108_m.jpg" alt="" /></a><br /><br /></p>
<h3><ins>Traceur de courbe</ins> :<br /></h3>
<ul>
<li>Synoptique de principe :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/Tempero_synoptic.png"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.Tempero_synoptic_m.png" alt="" /></a>
<a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/05/anemometre3">Mon tuto de l'époque</a> reste relativement adéquat, aussi je vous renvoie aux sections <em><strong>Configuration de la Base de données</strong></em> et <em><strong>Configuration de la Grafana</strong></em> de celui-ci.<br />
<em>Grafana</em> a quelque peu évolué depuis, et certaines captures d'écrans ne sont plus bonnes, mais l'essentiel y est, flemme d'en refaire de nouvelles.<br /></p>
<ul>
<li>Voici ce qu'on peut obtenir avec un peu de temps à configurer les graphes :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/tempero/Tempero01.png"><img src="http://burogu.makotoworkshop.org/public/electronique/tempero/.Tempero01_m.png" alt="" /></a><br /><br /></p>
<h3><a href="http://burogu.makotoworkshop.org/index.php?post/2022/07/03/tempero2">À suivre…</a></h3>
<div class="footnotes"><h4>Note</h4>
<p>[<a href="http://burogu.makotoworkshop.org/index.php?post/2022/06/25/tempero1#rev-wiki-footnote-1" id="wiki-footnote-1">1</a>] Voir ci-dessous</p></div>
http://burogu.makotoworkshop.org/index.php?post/2022/06/25/tempero1#comment-formhttp://burogu.makotoworkshop.org/index.php?feed/atom/comments/726Un Anémomètre Radio Multifonction -4-urn:md5:11950f749200a0a014f584f8e153c52d2019-12-28T12:46:00+01:002020-05-15T09:29:09+02:00makoto doushiteEnergies RenouvelablesArduinoBricolageDIYESP8266Impression3DModélisation3DNodeMCUÉlectroniqueÉolienne<p><strong>Edition du 23 Fevrier 2020, code <em>Arduino</em> et <em>esp8266</em> mis à jour.</strong><br />
Suite des études précédentes : <a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/05/anemometre3">Anémomètre</a> et <a href="http://burogu.makotoworkshop.org/index.php?post/2019/12/27/monitoring_generateur-batterie">Monitoring</a>.<br /></p>
<blockquote><p>À ce stade, vu tous mes bidules radio, il serait légitime de se demander pourquoi avoir 2 ou 3 appareils différents (l'un pour surveiller le vent, un pour la rotation de l'éolienne et un autre pour la charge de la batterie).<br />
En fait lors du développement il est naturel d'avancer par étape en ajoutant peu à peu des fonctions, cette suite de billet n'en est finalement que le reflet.<br /></p></blockquote>
<p>Il est maintenant temps de fusionner tout ça !<br /></p>
<ul>
<li>Cette fois donc, l'appareil sera chargé de récupérer les 4 informations que sont la vitesse du vent, la rotation de l'éolienne, l'énergie produite par la génératrice, et l'état de charge de la batterie; afin de les transmettre à des afficheurs et à une base de donnée pour être tracé.<br /><br /></li>
</ul>
<h3><ins>La partie émetteur</ins> :<br /></h3>
<ul>
<li>J'ai donc câblé un nouveau circuit :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/Anemometre_multifonctions_bb.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.Anemometre_multifonctions_bb_m.png" alt="" style="display:table; margin:0 auto;" /></a><br /></p>
<p><strong>Matériel requis :</strong></p>
<blockquote><p>- 1 <em>Arduino Pro Mini 5V</em>.<br />
- Un ordi avec port USB et le soft Arduino IDE.<br />
- 1 plaquette <em>HC-12</em> et son antenne.<br />
- 1 diode 1N4007.<br />
- 2 résistances 10kΩ.<br />
- 1 Capteur à effet Hall US1881 (anémo).<br />
- 1 Capteur à effet Hall 3144 (éolienne).<br />
- 1 Régulateur Négatif 9V L7909CV.<br />
- 1 condensateur électrochimique polarisé de 220µF.<br />
- 1 condensateur électrochimique polarisé de 2,2µF.<br />
- 1 condensateur électrochimique polarisé de 1µF.<br />
- 1 module ACS712 (20A) (<a href="https://www.youtube.com/watch?v=HimRh-kzkpE">Attention cependant !!</a> > Je sais que mon générateur ne dépassera pas 5A, à moins d'une tempête de vent de fin du monde…).<br /></p></blockquote>
<p><ins>Principe de fonctionnement</ins> :<br />
- À intervalle régulier, l<em>'Arduino</em> va envoyer les valeurs lues sur les entrées analogiques <em>A0</em> et <em>A1</em>, sur le port série du <em>HC-12</em>.<br />
- <em>A0</em> pour mesurer la valeur de la tension aux bornes de la batterie ( On a fabriqué un <a href="http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ProjetBatterieMesureTension">voltmètre très précis</a> câblé en parallèle ).<br />
- <em>A1</em> pour mesurer le courant sortant du générateur ( Un Ampèremètre câblé en série ).<br />
- Dés que le vent fera tourner l'anémomètre, l'interruption déclenche l'envoie des valeurs lues sur l'entrée numérique 2 (int0).<br />
- Dés que le vent fera tourner l'éolienne, l'interruption déclenche l'envoie des valeurs lues sur l'entrée numérique 3 (int1).<br /></p> <ul>
<li><strong>Programme pour l’<em>Arduino Pro Mini</em> de transmission :</strong><br /></li>
</ul>
<p><strong>Édit du 15 mai 2020 !</strong><br />
<a href="https://youtu.be/ArAcRfPpIYI?t=802">Électro-Bidouilleur a enfin sorti une vidéo sur le module <em>HC-12</em></a> et nous informe que la librairie <em><SoftwareSerial.h></em> est à éviter, ce que j'aurais bien voulu savoir à l'époque étant donné que j'ai effectivement rencontré des problèmes de réception. Il faut donc lui préférer la librairie <em><strong><AltSoftSerial.h></strong></em>. Je n'ai pas le temps de me pencher dessus, donc j'ai laissé tel quel le code suivant, sur <em>github</em> et en annexe du billet, à vous de changer la librairie.<br /></p>
<pre class="brush: cpp">/* Arduino Anemometer and Tachometer Éolienne
IN : capteur à effet Hall Anémomètre est connecté à la pin 2 = int0
IN : capteur à effet Hall Éolienne est connecté à la pin 3 = int1
OUT : HC-12 Radio Default Mode 9600bps
*/
#include <Arduino_CRC16.h> // Librairie à ajouter via le gestionnaire de lib de l'appli arduino
#include <SoftwareSerial.h>
#include <avr/sleep.h>
/****************/
/* DÉCLARATIONS */
/****************/
// Partie ANEMO
SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
unsigned long rpmVent = 0;
unsigned long rpmEol = 0;
unsigned long vitVentKMH = 0;
unsigned long vitEolRPM = 0;
unsigned long dateDernierChangementVent = 0;
unsigned long dateDernierChangementEol = 0;
unsigned long dateDernierChangementRPM = 0;
unsigned long dateDernierChangementKMH = 0;
unsigned long vitVentCourante = 0;
unsigned long vitVentDernierChangement = 0;
float intervalleKMH = 0;
float intervalleRPM = 0;
const char char_VT = 124; // vertical tab (VT)
const char char_LF = 10; // charactère saut de ligne ascii
const char char_SPACE = 32; // charactère ESPACE ascii, le meilleur caractère pour la détection de string de sscanf !
String chaine;
String message;
int rotaAnemo = 0;
int rotaEol = 0;
#define ATpin 7 // used to switch HC-12 to AT mode
// Partie MONITORING
float Courant=0;
float SupplyVoltage=12;
const int Voie_0=0; // declaration constante de broche analogique
int mesure_brute=0; // Variable pour acquisition résultat brut de conversion analogique numérique
float mesuref=0.0; // Variable pour calcul résultat décimal de conversion analogique numérique
float tension=0.0; // Variable tension mesurée
float tension_batterie=0.0; // Variable tension batterie calculée
float tension_regulateur=8925.0; // Variable tension réelle aux bornes du régulateur -9V (en mV)
int PIN_ACS712 = A1;
double Voltage = 0;
double Current = 0;
char MessageTensionBatterie[] = " VOL / "; // message to be sent; '\n' is a forced terminator char
char MessageCourant[] = " AMP"; // message to be sent; '\n' is a forced terminator char
Arduino_CRC16 crc16;
/*********/
/* SETUP */
/*********/
void setup() {
HC12.begin(9600); // Serial port to HC12
// debug uniquement, penser à commenter toutes les lignes «Serial…» pour éviter les erreurs de valeur (calcul trop long pour l'interruption)
Serial.begin(9600); // Serial port to computer
// Pin capteurs
attachInterrupt(digitalPinToInterrupt(2), rpm_vent, FALLING); // le capteur à effet Hall Anémomètre est connecté à la pin 2 = int0
attachInterrupt(digitalPinToInterrupt(3), rpm_eol, FALLING); // le capteur à effet Hall Éolienne est connecté à la pin 3 = int1
pinMode(PIN_ACS712, INPUT);
pinMode(ATpin, OUTPUT);
digitalWrite(ATpin, LOW); // Set HC-12 into AT Command mode
delay(500);
HC12.print("AT+C010"); // passer sur le canal 036 (433.4Mhz + 36x400KHz)
delay(500);
digitalWrite(ATpin, HIGH); // HC-12 en normal mode
}
/*************/
/* PROGRAMME */
/*************/
void loop() {
MesureCourant();
MesureBrute();
TensionMesuree();
TensionBatterie();
RemiseZeroVitVentKMHnew2 ();
RemiseZeroVitEolRPMnew2 ();
// Construction de la chaine
chaine = char_VT + String(vitVentKMH)+ char_SPACE + String(vitEolRPM) + char_SPACE + String(tension_batterie,3) + char_SPACE + String(Current,3); // construction du message
Serial.println ( "chaine String :" +chaine );
// Message de la forme suivante : 49 338 11.405 -12.500
// Calcul du Checksum
uint16_t const crc16_res = crc16.calc((uint8_t const *)chaine.c_str(), strlen(chaine.c_str()));
Serial.print("CRC16 = 0x");
Serial.println(crc16_res, HEX);
// Checksum joint au message
message = chaine + char_SPACE + String(crc16_res, HEX) + char_SPACE + char_LF;
Serial.println ( "message :" +message );
// send radio data
// HC12.print(chaine);
HC12.print(message);
// Message de la forme suivante : 49 338 11.405 -12.500 3cfe1c9
delay(100);
}
/*************/
/* 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 + 6.174 ) / 8.367;
Serial.print ( "vitVentKMH : " );
Serial.println ( vitVentKMH ); // affiche les rpm
Serial.println ( "" );
dateDernierChangementVent = dateCourante;
rotaAnemo = 1;
}
void rpm_eol() // appelée par l'interruption, Tachymétre rotation éolienne.
{
unsigned long dateCourante = millis();
intervalleRPM = (dateCourante - dateDernierChangementEol);
// Serial.print ( "intervalle en s : " );
// Serial.println (intervalleRPM/1000); // affiche l'intervalle de temps entre deux passages
if (intervalleRPM != 0) // attention si intervalle = 0, division par zero -> erreur
{
vitEolRPM = 60 / (intervalleRPM /1000);
}
Serial.print ( "rpm : " );
Serial.println ( vitEolRPM ); // affiche les rpm
Serial.println ( "" );
dateDernierChangementEol = dateCourante;
rotaEol = 1;
}
void RemiseZeroVitVentKMHnew2 ()
{
unsigned long dateCouranteKMH = millis();
if (rotaAnemo == 1 ){ // teste si l'Anémomètre tourne
// Serial.println ( "Anémo tourne ");
float dureeKMH = (dateCouranteKMH - dateDernierChangementKMH);
if (dureeKMH > 10000) {
rotaAnemo = 0;
dateDernierChangementKMH = dateCouranteKMH;
}
}
else // Si ça ne tourne plus (valeur plus mise à jour)
{
float dureeKMH = (dateCouranteKMH - dateDernierChangementKMH);
if (dureeKMH > 6000) // Si ça ne tourne plus depuis 16 secondes, délai un peu augmenté vis à vis du mode veille.
{
// Serial.print ( "dureeKMH : " );
// Serial.println ( dureeKMH ); // affiche les rpm
vitVentKMH = 0; // Remsise à zero !
dateDernierChangementKMH = dateCouranteKMH;
}
}
}
void RemiseZeroVitEolRPMnew2 ()
{
unsigned long dateCouranteRPM = millis();
if (rotaEol == 1 ){ // teste si l'éolienne tourne
// Serial.println ( "Éolienne tourne ");
float dureeRPM = (dateCouranteRPM - dateDernierChangementRPM);
if (dureeRPM > 10000) {
rotaEol = 0;
dateDernierChangementRPM = dateCouranteRPM;
}
}
else // Si ça ne tourne plus (valeur plus mise à jour)
{
float dureeRPM = (dateCouranteRPM - dateDernierChangementRPM);
if (dureeRPM > 6000) // Si ça ne tourne plus depuis 65 secondes (soit moins de 1 rpm), changé pour 8 sec en charge
{
// Serial.print ( "dureeRPM : " );
// Serial.println ( dureeRPM ); // affiche les rpm
vitEolRPM = 0; // Remsise à zero !
dateDernierChangementRPM = dateCouranteRPM;
}
}
}
// Partie MONITORING
void MesureCourant() {
// Serial.print("Courant : ");
// Serial.print(Courant);
// Serial.print(" A | Puissance : ");
// Serial.print(Courant*SupplyVoltage);
// Serial.println(" Watt");
// Voltage is Sensed 1000 Times for precision
for(int i = 0; i < 1000; i++) { // ça ralentis tout, mais c'est indispensable !
Voltage = (Voltage + (0.004882812 * analogRead(PIN_ACS712))); // (5 V / 1024 (Analog) = 0.0049) which converter Measured analog input voltage to 5 V Range
delay(1);
}
Voltage = Voltage /1000;
Current = (Voltage -2.5)/ 0.100; // Sensed voltage is converter to current (0.100 pour modèle 20A)
//Serial.print("\n Voltage Sensed (V) = "); // shows the measured voltage
//Serial.print(Voltage,3); // the ‘2’ after voltage allows you to display 2 digits after decimal point
//Serial.print("\t Current (A) = "); // shows the voltage measured
//Serial.println(Current,3); // the ‘2’ after voltage allows you to display 2 digits after decimal point
}
void MesureBrute() {
//-------- mesure brute --------
mesure_brute=analogRead(Voie_0);
// Serial.print ("Valeur brute = ");
// Serial.print (mesure_brute);
// Serial.println (" "); // espace de propreté
}
void TensionMesuree() {
//---------- tension mesurée ---------
mesuref=float(mesure_brute)*5000.0/1024.0;
tension=mesuref/1000.0; // en Volts
// Serial.print ("Tension = ");
// Serial.print(tension,3); // float avec 2 décimales
// Serial.println(" V "); // unité et espace de propreté
}
void TensionBatterie() {
//---------- tension batterie ---------
tension_batterie=mesuref+tension_regulateur;
tension_batterie=tension_batterie/1000.0; // en Volts
// lcd.setCursor(0,1) ; // positionne le curseur à l'endroit voulu (colonne, ligne)
// lcd.print ("Batt:");
// lcd.print (tension_batterie,2); // float avec 2 décimales
// lcd.print ("V "); // unité et espace de propreté
// Serial.print ("Batterie = ");
// Serial.print(tension_batterie,3); // float avec 2 décimales
// Serial.println(" V ");
// Serial.println(" ");
}</pre>
<p><br /></p>
<h3><ins>Le boîtier client, partie récepteur avec affichage</ins> :<br /></h3>
<ul>
<li>J'ai conservé mes deux systèmes d'affichage distinct (et donc deux <em>Arduino</em> à programmer), mais rien n'empêcherait d'utiliser un seul afficheur LCD à 4 lignes !<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/ClientAfficheur_Anemometre_multifonctions_bb.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.ClientAfficheur_Anemometre_multifonctions_bb_m.png" alt="" style="display:table; margin:0 auto;" /></a><br /></p>
<p><strong>Matériel requis :</strong></p>
<blockquote><p>- 2 <em>Arduino Pro Mini 5V</em>.<br />
- Un ordi avec port USB et le soft Arduino IDE.<br />
- 1 plaquette <em>HC-12</em> et son antenne.<br />
- 1 diode 1N4007.<br />
- 1 afficheur LCD type HD44780 16 ou 20 x 2.<br />
- 1 <em>NodeMCUv3 LoLin</em>.<br />
- 1 condensateur électrochimique polarisé de 220µF.<br />
- 12 afficheurs DLG7137.<br /></p></blockquote>
<p><br /></p>
<p><ins>Principe de fonctionnement</ins> :<br />
- Les deux <em>Arduino</em> reçoivent les valeurs transmises par le port série du <em>HC-12</em> et les affichent instantanément sur l'écran LCD (courant et tension) et les afficheurs DLG (vent et éolienne).<br />
- Le <em>NodeMCU</em> reçoit les valeurs transmises par le port série du <em>HC-12</em> et les transmet à la Base de données <em>InfluxDB</em>.<br />
- <em>Grafana</em> s'occupera de tracer les graphiques à partir des données.<br /></p>
<ul>
<li><strong>Programme pour l’Arduino Pro Mini de réception LCD :</strong> Voir en annexe du billet<sup>[<a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/30/anemometre4#wiki-footnote-1" id="rev-wiki-footnote-1">1</a>]</sup>.<br /></li>
</ul>
<ul>
<li><strong>Programme pour l’Arduino Pro Mini de réception DLG7137 :</strong> Voir en annexe du billet<sup>[<a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/30/anemometre4#wiki-footnote-2" id="rev-wiki-footnote-2">2</a>]</sup>.<br /></li>
</ul>
<ul>
<li><strong>Programme pour le <em>NodeMCU</em> de réception :</strong> Voir en annexe du billet<sup>[<a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/30/anemometre4#wiki-footnote-3" id="rev-wiki-footnote-3">3</a>]</sup>.<br /><br /></li>
</ul>
<p><strong><ins>Configuration de la <em>Grafana</em></ins> :</strong><br /></p>
<ul>
<li>Concernant cette partie, je vous laisse voir la fin de ce <a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/05/anemometre3">billet</a>, vu que c'est la même chose !<br /></li>
</ul>
<blockquote><p>Vous pourriez obtenir ce genre de chose :<br /></p></blockquote>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana_anemometre_multifonctions.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana_anemometre_multifonctions_m.jpg" alt="" style="display:table; margin:0 auto;" /></a><br />
L'observateur attentif aura remarqué que la vitesse du vent n'est ici pas logique avec la rotation de l'éolienne… Normal, je faisais des tests en rotation manuelle afin de pouvoir tracer ces graphiques.<br /></p>
<p>Le code est aussi <a href="https://github.com/makotoworkshop/Anemometre_multifonctions">documenté ici</a>, et en annexe du billet.<br /></p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/30/anemometre4#rev-wiki-footnote-1" id="wiki-footnote-1">1</a>] ci-dessous</p>
<p>[<a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/30/anemometre4#rev-wiki-footnote-2" id="wiki-footnote-2">2</a>] ci-dessous</p>
<p>[<a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/30/anemometre4#rev-wiki-footnote-3" id="wiki-footnote-3">3</a>] ci-dessous</p></div>
http://burogu.makotoworkshop.org/index.php?post/2019/08/30/anemometre4#comment-formhttp://burogu.makotoworkshop.org/index.php?feed/atom/comments/674Surveiller l'état et la charge d'une batterie 12 Voltsurn:md5:51cd7ac70dfaadea50cececcd8aa8c402019-12-27T19:53:00+01:002020-05-15T09:28:55+02:00makoto doushiteEnergies RenouvelablesArduinoBricolageDIYESP8266Impression3DModélisation3DNodeMCUÉlectroniqueÉolienne<ul>
<li>Monitorer la vitesse du vent et la rotation de l'éolienne, <a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/05/anemometre3">c'est fait !!</a><br /></li>
</ul>
<blockquote><p>Cependant quid de l'état de la batterie ?<br />
Combien d'énergie la génératrice produit-elle ?<br />
Cela est-il suffisant pour recharger la batterie ?<br /></p></blockquote>
<p>J'avais acheté un appareil pour mesurer ça en local, mais en définitive je ne m'en sert pas… Pas utile à moins d'aller au fond du jardin pour le consulter…<br /></p>
<ul>
<li>J'ai donc entrepris de construire un nouvel appareil de mesure, sur la même idée que l'Anémomètre Radio (<em>Arduino + HC-12</em>), avec transmission des données pour statistiques sur <em>Grafana</em> via <em>InfluxDB</em> (<em>NodeMCU</em>).<br /></li>
</ul>
<p><strong>Attention cependant</strong>, Si on souhaite faire fonctionner l'Anémomètre et le Monitoring en même temps, il faudra prendre soin de différencier les canaux de fonctionnement des modules <em>HC-12</em> (Voir la section <em>Setup</em> de chaque programmes)<br /><br /></p>
<h3><ins>Le monitoring Batterie, partie émetteur</ins> :<br /></h3>
<p>J'ai donc câblé un nouveau circuit :<br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/Capteur_Courant_Tension_bb.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.Capteur_Courant_Tension_bb_m.png" alt="" style="display:table; margin:0 auto;" /></a><br /></p>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04270.jpg" title="dsc04270.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc04270_s.jpg" alt="dsc04270.jpg" style="float:right; margin: 0 0 1em 1em;" /></a>
<strong>Matériel requis :</strong></p>
<blockquote><p>- 1 <em>Arduino Pro Mini 5V</em>.<br />
- Un ordi avec port USB et le soft Arduino IDE.<br />
- 1 plaquette <em>HC-12</em> et son antenne.<br />
- 1 diode 1N4007.<br />
- 1 Régulateur Négatif 9V L7909CV.<br />
- 1 condensateur électrochimique polarisé de 220µF.<br />
- 1 condensateur électrochimique polarisé de 2,2µF.<br />
- 1 condensateur électrochimique polarisé de 1µF.<br />
- 1 module ACS712 (20A) (<a href="https://www.youtube.com/watch?v=HimRh-kzkpE">Attention cependant !!</a> > Je sais que mon générateur ne dépassera pas 5A, à moins d'une tempête de vent de fin du monde…).<br /></p></blockquote>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04272.jpg" title="dsc04272.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc04272_s.jpg" alt="dsc04272.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04273.jpg" title="dsc04273.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc04273_s.jpg" alt="dsc04273.jpg" /></a><br /></p>
<p><ins>Principe de fonctionnement</ins> :<br />
- À intervalle régulier, l<em>'Arduino</em> va envoyer les valeurs lues sur les entrées analogiques <em>A0</em> et <em>A1</em>, sur le port série du <em>HC-12</em>.<br />
- <em>A0</em> pour mesurer la valeur de la tension aux bornes de la batterie ( On a fabriqué un <a href="http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ProjetBatterieMesureTension">voltmètre très précis</a> câblé en parallèle ).<br />
- <em>A1</em> pour mesurer le courant sortant du générateur ( Un Ampèremètre câblé en série ).<br /></p> <ul>
<li><strong>Programme pour l’<em>Arduino Pro Mini</em> de transmission :</strong><br /></li>
</ul>
<p><strong>Édit du 15 mai 2020 !</strong><br />
<a href="https://youtu.be/ArAcRfPpIYI?t=802">Électro-Bidouilleur a enfin sorti une vidéo sur le module <em>HC-12</em></a> et nous informe que la librairie <em><SoftwareSerial.h></em> est à éviter, ce que j'aurais bien voulu savoir à l'époque étant donné que j'ai effectivement rencontré des problèmes de réception. Il faut donc lui préférer la librairie <em><strong><AltSoftSerial.h></strong></em>. Je n'ai pas le temps de me pencher dessus, donc j'ai laissé tel quel le code suivant, sur <em>github</em> et en annexe du billet, à vous de changer la librairie.<br /></p>
<pre class="brush: cpp">#include <SoftwareSerial.h>
/****************/
/* DÉCLARATIONS */
/****************/
SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
char MessageTensionBatterie[] = " VOL / "; // message to be sent; '\n' is a forced terminator char
char MessageCourant[] = " AMP\n"; // message to be sent; '\n' is a forced terminator char
String chaine;
#define ATpin 7 // used to switch HC-12 to AT mode
float Courant=0;
float SupplyVoltage=12;
const int Voie_0=0; // declaration constante de broche analogique
int mesure_brute=0; // Variable pour acquisition résultat brut de conversion analogique numérique
float mesuref=0.0; // Variable pour calcul résultat décimal de conversion analogique numérique
float tension=0.0; // Variable tension mesurée
float tension_batterie=0.0; // Variable tension batterie calculée
float tension_regulateur=8925.0; // Variable tension réelle aux bornes du régulateur -9V (en mV)
int PIN_ACS712 = A1;
double Voltage = 0;
double Current = 0;
/*********/
/* SETUP */
/*********/
void setup() {
// Serial.begin(9600); // Debug
HC12.begin(9600); // Serial port to HC12
// Pin capteurs
pinMode(PIN_ACS712, INPUT);
pinMode(ATpin, OUTPUT);
digitalWrite(ATpin, LOW); // Set HC-12 into AT Command mode
delay(500);
HC12.print("AT+C056"); // passer sur le canal 006 (433.4Mhz + 56x400KHz)
delay(500);
digitalWrite(ATpin, HIGH); // HC-12 en normal mode
}
/*************/
/* PROGRAMME */
/*************/
void loop() {
MesureCourant();
MesureBrute();
TensionMesuree();
TensionBatterie();
chaine = String(tension_batterie,3) + MessageTensionBatterie + String(Current,3) + MessageCourant; // construction du message
Serial.println ( "chaine String : " +chaine );
HC12.print(chaine); // send radio data
delay(100);
}
/*************/
/* FONCTIONS */
/*************/
void MesureCourant() {
// Serial.print("Courant : ");
// Serial.print(Courant);
// Serial.print(" A | Puissance : ");
// Serial.print(Courant*SupplyVoltage);
// Serial.println(" Watt");
// Voltage is Sensed 1000 Times for precision
for(int i = 0; i < 1000; i++) { // ça ralentis tout, mais c'est indispensable !
Voltage = (Voltage + (0.004882812 * analogRead(PIN_ACS712))); // (5 V / 1024 (Analog) = 0.0049) which converter Measured analog input voltage to 5 V Range
delay(1);
}
Voltage = Voltage /1000;
Current = (Voltage -2.5)/ 0.100; // Sensed voltage is converter to current (0.100 pour modèle 20A)
Serial.print("\n Voltage Sensed (V) = "); // shows the measured voltage
Serial.print(Voltage,3); // the ‘2’ after voltage allows you to display 2 digits after decimal point
Serial.print("\t Current (A) = "); // shows the voltage measured
Serial.println(Current,3); // the ‘2’ after voltage allows you to display 2 digits after decimal point
}
void MesureBrute() {
//-------- mesure brute --------
mesure_brute=analogRead(Voie_0);
// Serial.print ("Valeur brute = ");
// Serial.print (mesure_brute);
// Serial.println (" "); // espace de propreté
}
void TensionMesuree() {
//---------- tension mesurée ---------
mesuref=float(mesure_brute)*5000.0/1024.0;
tension=mesuref/1000.0; // en Volts
// Serial.print ("Tension = ");
// Serial.print(tension,3); // float avec 2 décimales
// Serial.println(" V "); // unité et espace de propreté
}
void TensionBatterie() {
//---------- tension batterie ---------
tension_batterie=mesuref+tension_regulateur;
tension_batterie=tension_batterie/1000.0; // en Volts
// lcd.setCursor(0,1) ; // positionne le curseur à l'endroit voulu (colonne, ligne)
// lcd.print ("Batt:");
// lcd.print (tension_batterie,2); // float avec 2 décimales
// lcd.print ("V "); // unité et espace de propreté
Serial.print ("Batterie = ");
Serial.print(tension_batterie,3); // float avec 2 décimales
Serial.println(" V ");
// Serial.println(" ");
}</pre>
<p><br /></p>
<h3><ins>Le boîtier client, partie récepteur avec affichage</ins> :<br /></h3>
<p>Voici le montage avec un afficheur LCD standard :<br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/ClientAfficheurLCD_nodemcu_bb.png" title="ClientAfficheurLCD_nodemcu_bb.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.ClientAfficheurLCD_nodemcu_bb_m.png" alt="ClientAfficheurLCD_nodemcu_bb.png" style="display:table; margin:0 auto;" /></a><br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04268.jpg" title="dsc04268.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc04268_s.jpg" alt="dsc04268.jpg" style="float:right; margin: 0 0 1em 1em;" /></a>
<strong>Matériel requis :</strong></p>
<blockquote><p>- 1 <em>Arduino Pro Mini 5V</em>.<br />
- Un ordi avec port USB et le soft Arduino IDE.<br />
- 1 plaquette <em>HC-12</em> et son antenne.<br />
- 1 diode 1N4007.<br />
- 1 afficheur LCD type HD44780 16 ou 20 x 2.<br />
- 1 <em>NodeMCUv3 LoLin</em>.<br />
- 1 condensateur électrochimique polarisé de 220µF.<br /></p></blockquote>
<p><br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04266.jpg" title="dsc04266.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc04266_s.jpg" alt="dsc04266.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04274.jpg" title="dsc04274.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc04274_s.jpg" alt="dsc04274.jpg" /></a><br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04275.jpg" title="dsc04275.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc04275_s.jpg" alt="dsc04275.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04278.jpg" title="dsc04278.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc04278_s.jpg" alt="dsc04278.jpg" /></a><br /></p>
<ul>
<li>J'ai simulé le générateur avec une alimentation 12V et la batterie par une ampoule :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04278-79.gif"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc04278-79.gif" alt="" style="display:table; margin:0 auto;" /></a><br /></p>
<p><ins>Principe de fonctionnement</ins> :<br />
- L<em>'Arduino</em> reçoit les valeurs transmises par le port série du <em>HC-12</em> et les affiche instantanément sur l'écran LCD.<br />
- Le <em>NodeMCU</em> reçoit les valeurs transmises par le port série du <em>HC-12</em> et les transmet à la Base de données <em>InfluxDB</em>.<br />
- <em>Grafana</em> s'occupera de tracer les graphiques à partir des données.<br /></p>
<ul>
<li><strong>Programme pour l’Arduino Pro Mini de réception :</strong><br /></li>
</ul>
<p><strong>Édit du 15 mai 2020 !</strong><br />
<a href="https://youtu.be/ArAcRfPpIYI?t=802">Électro-Bidouilleur a enfin sorti une vidéo sur le module <em>HC-12</em></a> et nous informe que la librairie <em><SoftwareSerial.h></em> est à éviter, ce que j'aurais bien voulu savoir à l'époque étant donné que j'ai effectivement rencontré des problèmes de réception. Il faut donc lui préférer la librairie <em><strong><AltSoftSerial.h></strong></em>. Je n'ai pas le temps de me pencher dessus, donc j'ai laissé tel quel le code suivant, sur <em>github</em> et en annexe du billet, à vous de changer la librairie.<br /></p>
<pre class="brush: cpp">//———— Que fait ce programme ? ————
// ---> Récupére les données transmise par un module HC-12,
// ---> Affichage la mesure de la tension d'une batterie au plomb 12V sur un écran LCD.
// ---> Affichage l'intensité et la puissance fournie à la batterie par une génératrice 12V.
//———— Fonctionnalités utilisées ————
// Utilise un afficheur LCD alphanumérique2x20 en mode 4 bits
//———— Circuit à réaliser ————
// Broche 12 sur la broche RS du LCD
// Broche 11 sur la broche E du LCD
// Broche 5 sur la broche D4 du LCD
// Broche 4 sur la broche D5 du LCD
// Broche 3 sur la broche D6 du LCD
// Broche 2 sur la broche D7 du LCD
// Broche 7 sur HC-12 to AT mode
// Broche 8 HC-12 TX Pin
// Broche 9 HC-12 RX Pin
//———— Réglages possibles ————
// Canal de réception (voir setup)
// Voltage : Utilisé pour le calcul de la puissance en Watt.
// MiniC : pour régler le courant minimum mesuré en dessous duquel la valeur est forcée à 0, pour prendre
// en compte le fait que la mesure du zero ne tombe jamais pile.
#include <LiquidCrystal.h> // lib LCD
#include <SoftwareSerial.h> // lib Transmission série
//################
//# DÉCLARATIONS #
//################
//——— Radio HC-12 ———//
SoftwareSerial HC12(8, 9); // HC-12 TX Pin, HC-12 RX Pin
#define ATpin 7 // poir passer le HC-12 en AT mode
char acquis_data;
String chaine;
float Voltage=12;
float MiniC=0.08; // courant minimum mesuré en dessous duquel la valeur est forcée à 0.
float tension_batterie_float;
float Courant_float;
//——— Écran LCD ———//
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // Déclaration LCD
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // Pins LCD en mode 4 bits
byte carre00[8] = { // caractères personnalisés
B11111,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B11111
};
byte carre01[8] = {
B11111,
B00000,
B10000,
B10000,
B10000,
B10000,
B00000,
B11111
};
byte carre02[8] = {
B11111,
B00000,
B11000,
B11000,
B11000,
B11000,
B00000,
B11111
};
byte carre03[8] = {
B11111,
B00000,
B11100,
B11100,
B11100,
B11100,
B00000,
B11111
};
byte carre04[8] = {
B11111,
B00000,
B11110,
B11110,
B11110,
B11110,
B00000,
B11111
};
byte carre05[8] = {
B11111,
B00000,
B11111,
B11111,
B11111,
B11111,
B00000,
B11111
};
byte crochetouvrant[8] = {
B00011,
B00010,
B00010,
B00010,
B00010,
B00010,
B00010,
B00011
};
byte crochetfermant[8] = {
B11000,
B01000,
B01110,
B01110,
B01110,
B01110,
B01000,
B11000
};
//——— Fonction pour pemettre le map avec variable float ———
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
//#########
//# SETUP #
//#########
void setup() {
// Serial.begin(9600); // Debug
//——— HC12 ———//
HC12.begin(9600); // Serial port to HC12
pinMode(ATpin, OUTPUT);
digitalWrite(ATpin, LOW); // HC-12 en mode commande AT
delay(500);
HC12.print("AT+C056"); // passer sur le canal 056 (433.4Mhz + 56x400KHz)
delay(500);
digitalWrite(ATpin, HIGH); // HC-12 en normal mode
//——— LCD ———//
lcd.begin(20,2); // Initialise le LCD avec 20 colonnes x 2 lignes
delay(10);
lcd.print("LCD OK"); // affiche LCD OK
delay(2000);
lcd.clear();
delay(10);
lcd.createChar(0, carre00); // Les 8 caractères personnalisés
lcd.createChar(1, carre01);
lcd.createChar(2, carre02);
lcd.createChar(3, carre03);
lcd.createChar(4, carre04);
lcd.createChar(5, carre05);
lcd.createChar(6, crochetouvrant);
lcd.createChar(7, crochetfermant);
}
//#############
//# PROGRAMME #
//#############
void loop() {
Reception();
Jauge();
delay(200);
}
//#############
//# FONCTIONS #
//#############
void Reception() {
// surtout pas de delay dans cette boucle, sinon les data reçues sont erronnées.
while (HC12.available()) { // If HC-12 has data
acquis_data = HC12.read();
chaine = chaine + acquis_data;
// Serial.println (chaine); // Attention, chaine est donc une String
/* message reçu de la forme
12.665 VOL / 0.045 AMP
pour chaque ligne on fait :*/
if (chaine.endsWith("\n")) { //détection de fin de ligne : méthodes String
// Serial.println ("fin de ligne"); // debug
// String phrase = "12.665 VOL / 0.045 AMP"; //debug
char tension_batterie[5]; // chaine de 6 caractères pour stocker le texte avant le mot VOL
char Courant[3]; // chaine de 4 caractères pour stocker le texte avant le mot AMP
// sscanf(phrase.c_str(), "%s VOL / %s AMP", tension_batterie, &Courant); //debug
sscanf(chaine.c_str(), "%s VOL / %s AMP", tension_batterie, &Courant); // la chaine à parser est dans une String, avec la méthode c_str()
tension_batterie_float = atof(tension_batterie),3; // char convertie en Float, avec 3 décimales
Courant_float = atof(Courant),2; // char convertie en Float, avec 2 décimales
Serial.print("VOLTS: ");
Serial.println(tension_batterie_float,3); // float avec 3 décimales
Serial.print("AMPERES: ");
Serial.println(Courant_float,3);
Serial.print("Watt: ");
Serial.println(Courant_float*Voltage,0); // float avec 0 décimales
Serial.println(' ');
// Affichage LCD courant et Puissance
if ( Courant_float < MiniC ){ // remise à zero forcée si valeur mesurée très petite
Courant_float = 0;
}
lcd.setCursor(0,0);
lcd.print ("Power:");
lcd.print (Courant_float,2); // float avec 2 décimales
lcd.print ("A "); // unité et espace
lcd.setCursor(12,0);
lcd.write(0b01111110); // caractère : fleche, depuis le Standard Character Pattern du LCD
lcd.print (" ");
lcd.print (Courant_float*Voltage,0);
lcd.print ("Watt ");
// Affichage LCD Batterie
lcd.setCursor(0,1);
lcd.print ("Batt:");
lcd.print (tension_batterie_float,3);
lcd.print ("V ");
chaine = ""; // vide la String chaine
}
}
}
void Jauge() { // Jauge de charge batterie
lcd.setCursor(12, 1);
lcd.write(byte(6)); // crochet ouvrant
lcd.setCursor(19, 1);
lcd.write(byte(7)); // crochet fermant
float NiveauBatterie = mapfloat(tension_batterie_float, 11.4, 12.73, 0, 30); // Discrétise la valeur de la tension batterie
int NiveauBatterieBarre = (int)NiveauBatterie; // conversion en entier
if (NiveauBatterie > 30) { // en cas de dépassement des limites haute et basse et permettre l'affichage non-erroné
NiveauBatterieBarre = 30;
lcd.setCursor(13, 1);
lcd.print ("Pleine");
delay (1000);
}
else if (NiveauBatterie < 0) {
NiveauBatterieBarre = 0;
lcd.setCursor(13, 1);
lcd.print ("Erreur");
delay (1000);
}
// Serial.print ("NiveauBatterieBarre = ");
// Serial.print(NiveauBatterieBarre);
// Serial.println(" ");
switch (NiveauBatterieBarre) {
case 0:
lcd.setCursor(13, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(14, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 1:
lcd.setCursor(13, 1);
lcd.write(byte(1)); // carre01
lcd.setCursor(14, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 2:
lcd.setCursor(13, 1);
lcd.write(byte(2)); // carre02
lcd.setCursor(14, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 3:
lcd.setCursor(13, 1);
lcd.write(byte(3)); // carre03
lcd.setCursor(14, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 4:
lcd.setCursor(13, 1);
lcd.write(byte(4)); // carre04
lcd.setCursor(14, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 5:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 6:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(1)); // carre01
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 7:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(2)); // carre02
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 8:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(3)); // carre03
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 9:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(4)); // carre04
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 10:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 11:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(1)); // carre01
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 12:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(2)); // carre02
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 13:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(3)); // carre03
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 14:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(4)); // carre04
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 15:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 16:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(1)); // carre01
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 17:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(2)); // carre02
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 18:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(3)); // carre03
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 19:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(4)); // carre04
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 20:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(0)); // carre00
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 21:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(1)); // carre01
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 22:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(2)); // carre02
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 23:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(3)); // carre03
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 24:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(4)); // carre04
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 25:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(18, 1);
lcd.write(byte(0)); // carre00
break;
case 26:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(18, 1);
lcd.write(byte(1)); // carre01
break;
case 27:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(18, 1);
lcd.write(byte(2)); // carre02
break;
case 28:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(18, 1);
lcd.write(byte(3)); // carre03
break;
case 29:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(18, 1);
lcd.write(byte(4)); // carre04
break;
case 30:
lcd.setCursor(13, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(14, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(15, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(16, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(17, 1);
lcd.write(byte(5)); // carre05
lcd.setCursor(18, 1);
lcd.write(byte(5)); // carre05
break;
default:
// statements
break;
}
}</pre>
<ul>
<li><strong>Programme pour le <em>NodeMCU</em> de réception :</strong><br /></li>
</ul>
<p><strong>Édit du 15 mai 2020 !</strong><br />
<a href="https://youtu.be/ArAcRfPpIYI?t=802">Électro-Bidouilleur a enfin sorti une vidéo sur le module <em>HC-12</em></a> et nous informe que la librairie <em><SoftwareSerial.h></em> est à éviter, ce que j'aurais bien voulu savoir à l'époque étant donné que j'ai effectivement rencontré des problèmes de réception. Il faut donc lui préférer la librairie <em><strong><AltSoftSerial.h></strong></em>. Je n'ai pas le temps de me pencher dessus, donc j'ai laissé tel quel le code suivant, sur <em>github</em> et en annexe du billet, à vous de changer la librairie.<br /></p>
<pre class="brush: cpp">// Ressources :
//https://forum.arduino.cc/index.php?topic=553743.0
//https://plaisirarduino.fr/moniteur-serie/
#include "ESPinfluxdb.h" // lib ESP InfluxDB
#include <SoftwareSerial.h> // lib Transmission série
#include <ESP8266WiFi.h> // lib ESP Wifi
#include <ESP8266WiFiMulti.h>
//################
//# DÉCLARATIONS #
//################
//——— Radio HC-12 ———//
SoftwareSerial HC12(D5, D6); // HC-12 TX Pin et RX Pin
char acquis_data;
String chaine;
float Voltage=12;
float MiniC=0.08; // courant minimum mesuré en dessous duquel la valeur est forcée à 0.
float tension_batterie_float;
float Courant_float;
//——— InfluxDB ———//
const char *INFLUXDB_HOST = "xx.org";
const uint16_t INFLUXDB_PORT = xx;
const char *DATABASE = "xx";
const char *DB_USER = "xx";
const char *DB_PASSWORD = "xxxx";
Influxdb influxdb(INFLUXDB_HOST, INFLUXDB_PORT); //https://github.com/projetsdiy/grafana-dashboard-influxdb-exp8266-ina219-solar-panel-monitoring/tree/master/solar_panel_monitoring
int compteur = 1;
//——— WiFi ———//
char ssid[] = "xx";
char password[] = "xxxxx";
ESP8266WiFiMulti WiFiMulti;
//#########
//# SETUP #
//#########
void setup() {
Serial.begin(9600); // Debug
//——— HC12 ———//
HC12.begin(9600); // Serial port to HC12
//——— WiFi ———//
WiFiMulti.addAP(ssid, password); // Connection au réseau WiFi
while (WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
Serial.println ("WiFi Connecté");
//——— InfluxDB ———//
while (influxdb.opendb(DATABASE, DB_USER, DB_PASSWORD)!=DB_SUCCESS) { // Connexion à la base InfluxDB
delay(10000);
}
Serial.println ("Connexion DataBase OK");
}
//#############
//# PROGRAMME #
//#############
void loop() {
Reception();
if (compteur > 100) { // envoie la data toutes les 6 secondes (delay 10 x 100 = 1000 ms, et l'opération prend 5 secondes à transférer/écrire en base)
SendDataToInfluxdbServer();
compteur = 1;
}
else {
compteur++;
}
delay(10); // refresh la data sur l'afficheur toutes les 10 ms
}
//#############
//# FONCTIONS #
//#############
void Reception() {
// surtout pas de delay dans cette boucle, sinon les data reçues sont erronnées.
while (HC12.available()) { // If HC-12 has data
acquis_data = HC12.read();
chaine = chaine + acquis_data;
// Serial.println (chaine); // Attention, chaine est donc une String
/* message reçu de la forme
12.665 VOL / 0.045 AMP
pour chaque ligne on fait :*/
if (chaine.endsWith("\n")) { //détection de fin de ligne : méthodes String
// Serial.println ("fin de ligne"); // debug
// String phrase = "12.665 VOL / 0.045 AMP"; //debug
char tension_batterie[5]; // chaine de 6 caractères pour stocker le texte avant le mot VOL
char Courant[3]; // chaine de 4 caractères pour stocker le texte avant le mot AMP
// sscanf(phrase.c_str(), "%s VOL / %s AMP", tension_batterie, &Courant); //debug
sscanf(chaine.c_str(), "%s VOL / %s AMP", tension_batterie, &Courant); // la chaine à parser est dans une String, avec la méthode c_str()
tension_batterie_float = atof(tension_batterie),3; // char convertie en Float, avec 3 décimales
Courant_float = atof(Courant),2; // char convertie en Float, avec 2 décimales
Serial.print("VOLTS: ");
Serial.println(tension_batterie_float,3); // float avec 3 décimales
Serial.print("AMPERES: ");
Serial.println(Courant_float,3);
Serial.print("Watt: ");
Serial.println(Courant_float*Voltage,0); // float avec 0 décimales
Serial.println(' ');
// Affichage LCD courant et Puissance
if ( Courant_float < MiniC ){ // remise à zero forcée si valeur mesurée très petite
Courant_float = 0;
}
chaine = ""; // vide la String chaine
}
}
}
void SendDataToInfluxdbServer() { //Writing data with influxdb HTTP API: https://docs.influxdata.com/influxdb/v1.5/guides/writing_data/
//Querying Data: https://docs.influxdata.com/influxdb/v1.5/query_language/
dbMeasurement rowDATA("Data");
rowDATA.addField("tension_batterie", tension_batterie_float);
rowDATA.addField("Courant", Courant_float);
// Serial.println(influxdb.write(rowDATA) == DB_SUCCESS ? " - rowDATA write success" : " - Writing failed");
influxdb.write(rowDATA);
// Vide les données - Empty field object.
rowDATA.empty();
}</pre>
<p><strong><ins>Configuration de la <em>Grafana</em></ins> :</strong><br /></p>
<ul>
<li>Concernant cette partie, je vous laisse voir la fin de ce <a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/05/anemometre3">billet</a>, vu que c'est la même chose !<br /></li>
</ul>
<blockquote><p>Vous pourriez obtenir ce genre de chose :<br /></p></blockquote>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana_monitoring_batterie.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana_monitoring_batterie_m.jpg" alt="" style="display:table; margin:0 auto;" /></a><br /></p>
<p>Le code est aussi <a href="https://github.com/makotoworkshop/Monitoring_Generateur-Batterie">documenté ici</a>, et en annexe du billet.<br />
Boîtiers 3D <a href="https://www.thingiverse.com/thing:3956430">dispos sur Thingiverse</a><br /></p>
<p><ins>Ressources</ins> :<br />
<a href="https://wiki.mchobby.be/index.php?title=SENSEUR-COURANT-ACS712">https://wiki.mchobby.be/index.php?title=SENSEUR-COURANT-ACS712</a><br />
<a href="https://www.sparkfun.com/datasheets/BreakoutBoards/0712.pdf">https://www.sparkfun.com/datasheets/BreakoutBoards/0712.pdf</a><br />
<a href="http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ProjetBatterieMesureTension">http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ProjetBatterieMesureTension</a><br /><br /></p>
<h3><a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/30/anemometre4">À Suivre…</a></h3>http://burogu.makotoworkshop.org/index.php?post/2019/12/27/monitoring_generateur-batterie#comment-formhttp://burogu.makotoworkshop.org/index.php?feed/atom/comments/680Un anémomètre WiFi -3- … ha bah non, Radio !urn:md5:ad03d71345b766eac5387a5948ff51712019-08-30T16:40:00+02:002020-05-15T09:28:50+02:00makoto doushiteEnergies RenouvelablesArduinoBricolageDIYESP8266Impression3DModélisation3DMécaniqueNodeMCUVidéosÉlectroniqueÉolienne<p><a href="http://burogu.makotoworkshop.org/index.php?post/2018/11/12/anemometre">Suite de l'étude précédente</a> :<br /></p>
<p>Retour sur l'usage de l'anémomètre à base de <em>NodeMCUv3 LoLin</em> (puce ESP8266).<br />
Après quelques mois d'utilisation que peut-on conclure ?<br />
Et bien il fonctionne bien, mais… Il présente plusieurs défauts :<br /></p>
<blockquote><p>- Problème de portée, de temps en temps on perd la connexion avec le routeur <em>WiFi</em>.<br />
- Je n'ai pas beaucoup creusé, mais à priori le code que j'ai écrit finit par planter.<br />
- Il consomme beaucoup d'énergie si on envisage de rendre son alimentation autonome (batterie).<br />
- Une seule connexion est possible. C'est à dire que c'est soit <a href="http://burogu.makotoworkshop.org/index.php?post/2019/01/01/anemometre2">le module récepteur</a> qui affiche les données, soit la page web avec le manomètre.<br />
- J'aurais voulu « grapher » des statistiques, et je me voyais embarqué dans du développement complexe et laborieux pour mes maigres compétences.<br /></p></blockquote>
<p>Sur une suggestion de <em><a href="http://burogu.makotoworkshop.org/index.php?post/2018/11/12/anemometre#c18899">Chrismart</a></em>, j'ai donc décidé de revoir le projet dans une version plus fiable et proche de mes attentes.<br /><br /></p>
<h3><ins>Fonctionnalités revues et corrigées </ins> :<br /></h3>
<p>- Exit l<em>'ESP8266</em> pour la transmission de data, ça va se passer en <strong>Radio 433Mhz</strong> grâce à un module <em>HC-12</em> afin de gagner en portée.<br />
- Sans le <em>WiFi</em> qui réclamait une connexion permanente, on va pouvoir mettre les appareils en économie d'énergie lorsqu’il n'y a pas de vent.<br />
- La réception des data, va donc aussi se passer en Radio, pour se voir affichée sur le module d'affichage client avec un rafraîchissement temps réel.<br />
- Dans le boîtier Client, on garde l<em>'ESP8266</em>, qui sera chargé d'envoyer les data à un serveur Web afin de « grapher » des statistiques à l'aide d'une <em>BDD</em> InfluxDB et du grapheur <em>Grafana</em>.<br />
- Ce qui ne change pas, c'est la partie mécanique, vue dans <a href="http://burogu.makotoworkshop.org/index.php?post/2018/11/12/anemometre">le premier billet</a>.<br /></p>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/Anemo_synoptic.svg.png" title="Anemo_synoptic.svg.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.Anemo_synoptic.svg_m.png" alt="Anemo_synoptic.svg.png" style="display:table; margin:0 auto;" /></a><br />
Nous allons voir tout ça étape par étape.<br /><br /></p>
<h3><ins>L'anémomètre, partie émetteur</ins> :<br /></h3>
<p>J'ai donc câblé un nouveau circuit :<br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/Anemometre02.png" title="Anemometre02.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.Anemometre02_m.png" alt="Anemometre02.png" /></a><br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/20190802_211343.jpg" title="20190802_211343.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.20190802_211343_s.jpg" alt="20190802_211343.jpg" style="float:right; margin: 0 0 1em 1em;" /></a>
<strong>Matériel requis :</strong></p>
<blockquote><p>- 1 <em>Arduino Pro Mini 5V</em>.<br />
- 1 plaquette <em>HC-12</em> et son antenne.<br />
- 1 condensateur électrochimique polarisé de 220µF.<br />
- 1 diode 1N4007.<br />
- 1 résistance 10kΩ.<br />
- 1 Capteur à effet Hall US1881.<br />
- Un ordi avec port USB et le soft Arduino IDE.</p></blockquote>
<p>Pour permettre au montage de s'intégrer en lieu et place du <em>NodeMCUv3 LoLin</em> , j'ai tout fixé sur un morceau d'époxy.<br /></p> <p><strong>Édit du 15 mai 2020 !</strong><br />
<a href="https://youtu.be/ArAcRfPpIYI?t=802">Électro-Bidouilleur a enfin sorti une vidéo sur le module <em>HC-12</em></a> et nous informe que la librairie <em><SoftwareSerial.h></em> est à éviter, ce que j'aurais bien voulu savoir à l'époque étant donné que j'ai effectivement rencontré des problèmes de réception. Il faut donc lui préférer la librairie <em><strong><AltSoftSerial.h></strong></em>. Je n'ai pas le temps de me pencher dessus, donc j'ai laissé tel quel le code suivant, sur <em>github</em> et en annexe du billet, à vous de changer la librairie.<br /></p>
<p>Le code est aussi <a href="https://github.com/makotoworkshop/Anemometre_Arduino_Radio-HC-12_LCD/blob/master/Anemometre_Arduino_Radio-HC-12_Transmitter.ino">documenté ici</a>, et en annexe du billet :<br /></p>
<ul>
<li><strong>Programme pour l’<em>Arduino Pro Mini</em> de transmission :</strong><br /></li>
</ul>
<pre class="brush: cpp">/* Arduino Anemometer Radio Transmitter using HC-12 */
#include <SoftwareSerial.h>
/****************/
/* DÉCLARATIONS */
/****************/
SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
// le capteur à effet Hall est connecté à la pin 2 = int0
unsigned long rpmVent = 0;
unsigned long vitVentKMH = 0;
unsigned long dateDernierChangementVent = 0;
unsigned long dateDernierChangementKMH = 0;
float intervalleKMH = 0;
/*********/
/* SETUP */
/*********/
void setup() {
Serial.begin(9600); // Serial port to computer
HC12.begin(9600); // Serial port to HC12
// Pin capteurs
attachInterrupt(0, rpm_vent, FALLING);
}
/*************/
/* PROGRAMME */
/*************/
void loop() {
RemiseZeroVitVentKMH ();
delay(500);
}
/*************/
/* 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 + 6.174 ) / 8.367;
Serial.print ( "vitVentKMH : " );
Serial.println ( vitVentKMH ); // affiche les rpm
Serial.println ( "" );
HC12.print(char(vitVentKMH));
dateDernierChangementVent = dateCourante;
}
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;
}
}
}</pre>
<p>J'ai donc repris la partie <em>rpm_vent()</em> et <em>RemiseZeroVitVentKMH()</em> que j'avais élaboré dans la version <em>WiFi</em>, en ajoutant simplement l'instruction <em>HC12.print(char(vitVentKMH))</em> afin de transmettre la donnée par le module <em>HC-12</em>.<br />
Et c'est tout !<br /><br /></p>
<h3><ins>Le boîtier client, partie récepteur avec affichage</ins> :<br /></h3>
<p>Voici le montage avec un afficheur LCD standard, plus simple que mon boîtier à base d'afficheurs <em>DLG7137</em>, et qui vous permettra une réalisation aisée et rapide, mais cependant moins classe que l’usine à gaz que j’avais donc monté…<br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/ClientAfficheurLCD_bb.png" title="ClientAfficheurLCD_bb.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.ClientAfficheurLCD_bb_m.png" alt="ClientAfficheurLCD_bb.png" style="display:table; margin:0 auto;" /></a>
<strong>Matériel requis :</strong></p>
<blockquote><p>- 1 <em>Arduino Pro Mini 5V</em>.<br />
- 1 plaquette <em>HC-12</em> et son antenne.<br />
- 1 condensateur électrochimique polarisé de 220µF.<br />
- 1 diode 1N4007.<br />
- 1 afficheur LCD type HD44780 16 ou 20 x 2.<br />
- Un ordi avec port USB et le soft Arduino IDE.<br /></p></blockquote>
<p>Le code est aussi <a href="https://github.com/makotoworkshop/Anemometre_Arduino_Radio-HC-12_LCD/blob/master/Anemometre_Arduino_Radio-HC-12_Receiver.ino">documenté ici</a>, et en annexe du billet :<br /></p>
<ul>
<li><strong>Programme pour l’Arduino Pro Mini de réception :</strong><br /></li>
</ul>
<p><strong>Édit du 15 mai 2020 !</strong><br />
<a href="https://youtu.be/ArAcRfPpIYI?t=802">Électro-Bidouilleur a enfin sorti une vidéo sur le module <em>HC-12</em></a> et nous informe que la librairie <em><SoftwareSerial.h></em> est à éviter, ce que j'aurais bien voulu savoir à l'époque étant donné que j'ai effectivement rencontré des problèmes de réception. Il faut donc lui préférer la librairie <em><strong><AltSoftSerial.h></strong></em>. Je n'ai pas le temps de me pencher dessus, donc j'ai laissé tel quel le code suivant, sur <em>github</em> et en annexe du billet, à vous de changer la librairie.<br /></p>
<pre class="brush: cpp">/* Arduino Anemometer Radio Receiver using HC-12 and LCD Module */
/* The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* LCD VSS pin to ground
* LCD VCC pin to 5V
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)*/
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
SoftwareSerial HC12(8, 9); // HC-12 TX Pin, HC-12 RX Pin
/*********/
/* SETUP */
/*********/
void setup() {
Serial.begin(9600); // Serial port to computer
HC12.begin(9600); // Serial port to HC12
lcd.begin(20, 2);
lcd.setCursor(0, 0);
// Print a message to the LCD.
lcd.print(" Anemometer");
lcd.setCursor(0, 1);
lcd.print(" Test");
delay(1000);
lcd.clear();
}
/*************/
/* PROGRAMME */
/*************/
void loop() {
while (HC12.available()) { // If HC-12 has data
int incomingChar = HC12.read();
Serial.print ( "buffer : " );
Serial.println (incomingChar);
lcd.setCursor(0, 0);
lcd.print(incomingChar);
lcd.setCursor(4, 0);
lcd.print("Km/h");
}
}</pre>
<p>Pour la réception des données on récupère les caractères avec la variable <em>incomingChar</em> et on l'envoie sur l'écran avec <em>lcd.print</em>.<br /><br /></p>
<h3><ins>Le boîtier client, partie récepteur, avec statistiques graphiques</ins> :<br /></h3>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/ClientAfficheurLCD_nodemcu_bb.png" title="ClientAfficheurLCD_nodemcu_bb.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.ClientAfficheurLCD_nodemcu_bb_m.png" alt="ClientAfficheurLCD_nodemcu_bb.png" style="display:table; margin:0 auto;" /></a>
<strong>Matériel requis :</strong></p>
<blockquote><p>- 1 <em>NodeMCUv3 LoLin</em>.<br />
- Un ordi avec port USB et le soft Arduino IDE.</p></blockquote>
<ul>
<li>On conserve ici le même design que précédemment, et on ajoute simplement un <em>NodeMCU</em> (ESP8266) qui va permettre la transmission de donnée via <em>WiFi</em>.<br /></li>
</ul>
<p>Il est donc chargé d'envoyer les data à un serveur Web afin de « grapher » des statistiques à l'aide d'une base de donnée <em>InfluxDB</em> et du grapheur <em>Grafana</em>.<br /></p>
<p><em>Grafana</em> est une sorte de CMS web qui permet la visualisation et la mise en forme de données métriques. Il permet de réaliser des graphiques depuis plusieurs sources dont des bases de données de série temporelle <em>(Time Series Database</em>), et c'est <em>InfluxDB</em> qu'on va ici utiliser.<br />
Pour cette partie, il faut disposer d'un serveur web, sur lequel on va installer <em>Grafana</em> et la base de donnée 'InfluxDB''.<br />
Grâce à <a href="https://github.com/projetsdiy/grafana-dashboard-influxdb-exp8266-ina219-solar-panel-monitoring/tree/master/solar_panel_monitoring">ce projet</a>, j'ai pu récupérer le bout de code simple qui va permettre à l’<em>ESP8266</em> d'écrire en base de donnée <em>InfluxDB</em>.<br />
Il faudra donc ajouter ces deux fichiers <em>ESPinfluxdb.cpp</em> et <em>ESPinfluxdb.h</em> au sketch <em>Arduino</em> pour programmer l<em>'ESP8266</em> du <em>NodeMCU</em>.<br /></p>
<ul>
<li>On donne au programme les paramètres de connexion au <em>WiFi</em> local, les paramètres de connexion à la base de donnée, qu'elle soit dans un réseau privé ou sur une adresse publique avec un nom de domaine associé.<br /></li>
</ul>
<p>Le code est aussi <a href="https://github.com/makotoworkshop/Anemometre_Arduino_esp8266_Radio-HC-12_Grafana/tree/master/Anemometre_Arduino_Radio-HC-12_Receiver_Grafana">documenté ici</a>, et en annexe du billet :<br /></p>
<ul>
<li><strong>Programme pour le <em>NodeMCU</em> de réception :</strong><br /></li>
</ul>
<p><strong>Édit du 15 mai 2020 !</strong><br />
<a href="https://youtu.be/ArAcRfPpIYI?t=802">Électro-Bidouilleur a enfin sorti une vidéo sur le module <em>HC-12</em></a> et nous informe que la librairie <em><SoftwareSerial.h></em> est à éviter, ce que j'aurais bien voulu savoir à l'époque étant donné que j'ai effectivement rencontré des problèmes de réception. Il faut donc lui préférer la librairie <em><strong><AltSoftSerial.h></strong></em>. Je n'ai pas le temps de me pencher dessus, donc j'ai laissé tel quel le code suivant, sur <em>github</em> et en annexe du billet, à vous de changer la librairie.<br /></p>
<pre class="brush: cpp">#include "ESPinfluxdb.h"
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
/****************/
/* DÉCLARATIONS */
/****************/
const char *INFLUXDB_HOST = "domain.org"; // ou ip locale du serveur
const uint16_t INFLUXDB_PORT = 8086;
const char *DATABASE = "AnemoBDD";
const char *DB_USER = "login";
const char *DB_PASSWORD = "motdepasse";
int incomingChar;
int compteur = 1;
SoftwareSerial HC12(D5, D6); // HC-12 TX Pin, HC-12 RX Pin
ESP8266WiFiMulti WiFiMulti;
Influxdb influxdb(INFLUXDB_HOST, INFLUXDB_PORT);
/*********/
/* SETUP */
/*********/
void setup() {
Serial.begin(115200);
HC12.begin(9600); // Serial port to HC12
WiFiMulti.addAP("ssid", "password"); // indiquer ici vos paramètres WiFi
while (WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
Serial.println("Ready");
//influxdb.opendb(DATABASE, DB_USER, DB_PASSWORD);
// Connexion à la base InfluxDB - Connect to InfluxDB database
while (influxdb.opendb(DATABASE, DB_USER, DB_PASSWORD)!=DB_SUCCESS) {
Serial.println("Open database failed");
delay(10000);
}
}
/*************/
/* FONCTIONS */
/*************/
void ReceiveDataFromRadio() {
while (HC12.available()) { // If HC-12 has data
incomingChar = HC12.read();
// Serial.print ( "buffer : " );
// Serial.println (incomingChar);
}
}
void SendDataToInfluxdbServer() {
//Writing data with influxdb HTTP API: https://docs.influxdata.com/influxdb/v1.5/guides/writing_data/
//Querying Data: https://docs.influxdata.com/influxdb/v1.5/query_language/
// Envoi la vitesse du vent
dbMeasurement rowAnemo("VitesseVent");
rowAnemo.addField("VitesseVent", incomingChar);
Serial.println(influxdb.write(rowAnemo) == DB_SUCCESS ? " - Object write success" : " - Writing failed");
// Vide les données - Empty field object.
rowAnemo.empty();
}
/*************/
/* PROGRAMME */
/*************/
void loop() {
ReceiveDataFromRadio();
if (compteur > 500) { // envoie la data toutes les 5 secondes (10 ms + 500)
SendDataToInfluxdbServer();
compteur = 1;
}
else {
compteur++;
}
delay(10); // refresh la data sur l'afficheur toutes les 10 ms
// Serial.print ( "compteur = " );
// Serial.println(compteur);
}</pre>
<p>Toujours pareil, c'est la variable <em>incomingChar</em> reçue par le <em>HC-12</em> qui est envoyé périodiquement à la base de données.<br /></p>
<p><strong><ins>Configuration de la Base de données</ins> :</strong><br />
Coté serveur web donc, une fois les logiciels <em>Grafana</em> et <em>InfluxDB</em> installés, on va commencer par créer la base de donnée avec les commandes suivantes.<br /></p>
<ul>
<li>Lancer l’interpréteur de commande d’<em>InfluxDB</em> :<br /></li>
</ul>
<pre>influx</pre>
<ul>
<li>Créer la base de donnée <em>AnemoBDD</em> :<br /></li>
</ul>
<pre>create database AnemoBDD</pre>
<ul>
<li>Indiquer qu’on veut utiliser cette base :<br /></li>
</ul>
<pre>use AnemoBDD</pre>
<ul>
<li>Créer l’utilisateur de la base en spécifiant son mot de passe :<br /></li>
</ul>
<pre>create user login with password 'motdepasse'</pre>
<ul>
<li>Donner les droits d’accès complet à l’utilisateur :<br /></li>
</ul>
<pre>grant all on AnemoBDD to login</pre>
<ul>
<li>On peut vérifier avec ces commandes, puis quitter :<br /></li>
</ul>
<pre>show databases
show users
quit</pre>
<p><br /></p>
<p><strong><ins>Configuration de la <em>Grafana</em></ins> :</strong><br />
Reste à paramétrer <em>Grafana</em> avec la base <em>InfluxDB</em> en source et un tableau de bord qui récupére la donnée <em>rowAnemo</em>, sous la forme qu'on souhaitera voir afficher.<br /></p>
<ul>
<li>Ajouter une source de donnée, choisir la source de type <em>InfluxDB</em> :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana01.png" title="grafana01.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana01_s.png" alt="grafana01.png" style="float:right; margin: 0 0 1em 1em;" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana02.png" title="grafana02.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana02_s.png" alt="grafana02.png" style="float:right; margin: 0 0 1em 1em;" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana14.png" title="grafana14.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana14_s.png" alt="grafana14.png" /></a></p>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana03.png" title="grafana03.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana03_t.png" alt="grafana03.png" style="float:right; margin: 0 0 1em 1em;" /></a><br /></p>
<ul>
<li>Puis paramétrer les accès à la base <em>InfluxDB</em> :<br /></li>
</ul>
<p>On indique donc un nom de source, l’URL et le port du serveur <em>InfluxDB</em>, puis les identifiants de la base qu’on a crée auparavant.<br /><br /><br /></p>
<ul>
<li>Ensuite, créer un « tableau de bord » et ajouter une requête « Add Query » :<br /></li>
</ul>
<p>Choisir la source de donnée qu’on vient de faire, et renseigner les champs avec les valeurs du programme de l’<em>ESP8266</em>.<br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana15.png" title="grafana15.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana15_s.png" alt="grafana15.png" style="float:right; margin: 0 0 1em 1em;" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana04.png" title="grafana04.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana04_s.png" alt="grafana04.png" style="float:right; margin: 0 0 1em 1em;" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana13.png" title="grafana13.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana13_s.png" alt="grafana13.png" /></a>
<br />
Notez que si le NodeMCU est en marche et bien connecté à la base InfluxDB, ces champs proposeront les valeurs automatiquement quand on clique dessus, preuve que tout fonctionne comme prévu.<br /></p>
<ul>
<li>On passe à la partie « Visualization » ou l’on choisis le type « Graph », et on paramètre le graphique comme ceci :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana12.png" title="grafana12.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana12_s.png" alt="grafana12.png" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana05.png" title="grafana05.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana05_s.png" alt="grafana05.png" style="float:right; margin: 0 0 1em 1em;" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana06.png" title="grafana06.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana06_s.png" alt="grafana06.png" style="float:left; margin: 0 1em 1em 0;" /></a></p>
<ul>
<li>La partie « General » permet notamment de donner un nom au graphique.<br /><br /></li>
</ul>
<ul>
<li>De la même manière, j’ai ajouté une « Visualization » de type « Gauge » :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana07.png" title="grafana07.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana07_t.png" alt="grafana07.png" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana08.png" title="grafana08.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana08_t.png" alt="grafana08.png" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana09.png" title="grafana09.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana09_t.png" alt="grafana09.png" /></a><br /></p>
<ul>
<li>Il faut bien penser à utiliser l’icône en forme de disquette pour sauvegarder à chaque étapes…<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/grafana10.png" title="grafana10.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.grafana10_m.png" alt="grafana10.png" /></a><br /></p>
<h3><ins>Pour finir</ins> :<br /></h3>
<p>Nous avons donc vu une base de travail que vous pourrez adapter facilement si besoin.<br /></p>
<ul>
<li>Cependant comme j'avais ajouté une fonctionnalité supplémentaire, à savoir :</li>
</ul>
<blockquote><p>Un <strong>tachymètre</strong> qui mesure la vitesse de rotation de l'éolienne, j'ai pas mal dû modifier le code notamment pour envoyer les données en une phrase de data et ensuite bien différencier qu'elle donnée va où…<br />
Ajouté aussi la gestion d'économie d'énergie, qui, dés que l’anémomètre s'arrête de tourner, met en veille le module <em>HC-12</em>, puis l<em>'Arduino</em>, pour être réveillé dés que la rotation reprend sous le vent.<br /></p></blockquote>
<ul>
<li>Pour cette version donc, je me contente juste de poser le <a href="https://github.com/makotoworkshop/Anemometre_esp8266_Radio-HC-12_Receiver_2Hall_Grafana"><strong>>> code ici <<</strong></a> et aussi en annexe du billet.<br /></li>
</ul>
<p>Ainsi qu'une petite vidéo pour illustrer. J'y tourne mon appareil de test à la main :<br /></p>
<iframe width="640" height="360" sandbox="allow-same-origin allow-scripts" src="https://peertube.makotoworkshop.org/videos/embed/eb76a519-59c5-49d6-a0f3-125f9f6b8fbc?warningTitle=0" frameborder="0" allowfullscreen></iframe>
<p><ins>Voici les mesures de consommation</ins> : Anémomètre/Tachymètre (1 module radio + 2 capteur Hall)<br />
- 45 mA, qui tombent à 9 mA en mode veille.<br />
- <strong>5 mA en veille</strong> en dessoudant la <em>LED</em> Power de l<em>'Arduino</em>.<br />
(Déssouder le régulateur ne change pas grand chose).</p>
<h3><a href="http://burogu.makotoworkshop.org/index.php?post/2019/12/27/monitoring_generateur-batterie">À suivre…</a></h3>http://burogu.makotoworkshop.org/index.php?post/2019/08/05/anemometre3#comment-formhttp://burogu.makotoworkshop.org/index.php?feed/atom/comments/672Un anémomètre WiFi -2-urn:md5:875fe9c1d2261cc7b73799cdee7959e72019-01-05T18:56:00+01:002020-02-23T19:45:22+01:00makoto doushiteEnergies RenouvelablesArduinoBricolageDIYESP8266Impression3DModélisation3DMécaniqueNodeMCUVidéosÉlectroniqueÉolienne<p><a href="http://burogu.makotoworkshop.org/index.php?post/2018/11/12/anemometre">Suite de l'étude précédente</a> :<br /></p>
<ul>
<li>Avoir un affichage sur le web c'est bien…<br /></li>
</ul>
<p>Une petite vidéo :<br /></p>
<iframe width="640" height="360" sandbox="allow-same-origin allow-scripts" src="https://peertube.makotoworkshop.org/videos/embed/bacf06e4-83c0-4b41-aff3-085ba182338e?warningTitle=0" frameborder="0" allowfullscreen></iframe>
<ul>
<li>Mais un module d'affichage physique c'est quand même plus pratique !<br /></li>
</ul>
<p>Une petite vidéo :<br /></p>
<iframe width="640" height="360" sandbox="allow-same-origin allow-scripts" src="https://peertube.makotoworkshop.org/videos/embed/84ae22c8-7e48-434c-9324-f4d6b438e10e?warningTitle=0" frameborder="0" allowfullscreen></iframe>
<ul>
<li>Une seconde démo en vidéo, avec le programme de l'anémomètre revu et corrigé. Le rafraîchissement des valeurs se fait toutes les demi-secondes :</li>
</ul>
<iframe width="640" height="360" sandbox="allow-same-origin allow-scripts" src="https://peertube.makotoworkshop.org/videos/embed/1fe7051c-dc25-465b-8d6c-287a5d3d9d7b?warningTitle=0" frameborder="0" allowfullscreen></iframe>
<ul>
<li>J'ai donc passé quelques jours à concevoir ce boîtier client qui fonctionne à base lui aussi d'un <em>NodeMCU</em> connecté au réseau WiFi de la maison, et qui récupère les infos de vitesse transmise par l'anémomètre.<br /><br /></li>
</ul>
<h3><ins>Principe</ins> :<br /></h3>
<blockquote><p>Ce client se connecte à l'anémomètre et récupère le fichier <em>JSON</em> ( <em>http://192.168.0.34:8080/mesures.json</em>) afin de le <em>parser</em> toutes les secondes, reste alors à afficher l'information.<br /></p></blockquote>
<p>Ce sont donc des vieux afficheurs matriciel <em>DLG7137</em> qui vont faire le travail.<br />
Pour chaque afficheurs il aurait fallu employer un registre à décalage, afin de pouvoir adresser les données à afficher sur chaque matrices, comme cela à été fait sur le <em><a href="http://burogu.makotoworkshop.org/index.php?post/2018/01/16/wrrw04">WebRadioReveilWiFi</a></em>, mais ne disposant pas de suffisamment de <em>74HC595</em>, j'ai dû procéder autrement.<br />
Les <em>DLG7137</em> disposent en effet d'une pin <em>Write</em> (<em>WR/</em>) qui n'autorise l'affichage de la donnée qu'au moment où elle passe à l'état bas.<br />
Du coup en reliant tous les afficheurs entre eux et en faisant circuler l'information, il restait au programme de valider la pin <em>Write</em> du bon afficheur au bon moment pour afficher le caractère attendu sur chacun des afficheurs.<br />
Et comme le <em>NodeMCU</em> ne dispose pas de suffisamment de papattes pour pouvoir brancher les 12 pins <em>Write</em> des 12 afficheurs, j'ai donné ce travail à faire à deux registres <em>74HC595</em>, permettant ainsi d'adresser 16 pins <em>Write</em>.<br /></p>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/ClientAfficheur_bb.png" title="ClientAfficheur_bb.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.ClientAfficheur_bb_m.png" alt="ClientAfficheur_bb.png" style="display:table; margin:0 auto;" /></a><br />
<strong><ins>Note</ins> :</strong> J'ai oublié de câbler les deux condensateurs de découplage utiles aux registres <em>74HC595</em> !!<br />
Ne les oubliez-pas ! (100nF directement entres les pattes d'alimentation 8 et 16)<br /><br /></p> <h3><ins>Réalisation</ins> :<br /></h3>
<p>Pas de plaquette de circuit imprimé réalisée cette fois, par manque de temps et aussi car le boîtier serait unique, j'ai donc soudé le tout un quatre ou six heures sur une plaquette à trous, puis j'ai <a href="https://www.thingiverse.com/thing:3335805">dessiné le boîtier en 3D</a> pour impression.<br /></p>
<ul>
<li>La plaquette à trous :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03958.jpg" title="dsc03958.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03958_s.jpg" alt="dsc03958.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03960.jpg" title="dsc03960.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03960_s.jpg" alt="dsc03960.jpg" /></a><br /></p>
<ul>
<li>Le boîtier imprimé, avec un petit bouton pour appuyer sur le <em>reset</em> du <em>NodeMCU</em>.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03956.jpg" title="dsc03956.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03956_s.jpg" alt="dsc03956.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03957.jpg" title="dsc03957.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03957_s.jpg" alt="dsc03957.jpg" /></a><br /></p>
<ul>
<li>J'ai trouvé un morceau de plexis de 2mm d'épaisseur, que j'ai peint sur l'envers à l'aérographe au <em>Tamiya smoke X-19</em> afin de donner un côté fumé à ce vitrage, ensuite collé à l'intérieur du boîtier :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03961.jpg" title="dsc03961.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03961_s.jpg" alt="dsc03961.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03962.jpg" title="dsc03962.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03962_s.jpg" alt="dsc03962.jpg" /></a><br /></p>
<ul>
<li>La plaquette est mise en place en la glissant dans la rainure prévue, puis c'est au tour du couvercle :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03964.jpg" title="dsc03964.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03964_s.jpg" alt="dsc03964.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03965.jpg" title="dsc03965.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03965_s.jpg" alt="dsc03965.jpg" /></a><br /></p>
<ul>
<li>Voilà…<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03966.jpg" title="dsc03966.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03966_s.jpg" alt="dsc03966.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03969.jpg" title="dsc03969.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03969_s.jpg" alt="dsc03969.jpg" /></a>]<br /></p>
<ul>
<li>C'est classe moi j'dis :D :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03967.jpg" title="dsc03967.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03967_s.jpg" alt="dsc03967.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03971.jpg" title="dsc03971.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03971_s.jpg" alt="dsc03971.jpg" /></a><br />
Le module affiche <em>NoData</em> lorsque la transmission de donnée se passe mal, comme par exemple lorsque l'anémomètre est éteint.<br /><br /></p>
<h3><ins>Programme</ins> :<br /></h3>
<ul>
<li>Le code du <em>NodeMCU</em> est trop imposant pour être présenté correctement dans cette page, il est téléchargeable en pièce jointe ou <a href="https://github.com/makotoworkshop/01-ClientAnemometre_esp8266_Afficheurs_2ShiftRegister_01/blob/master/01-ClientAnemometre_esp8266_Afficheurs_2ShiftRegister_01.ino">consultable ici</a>.<br /><br /></li>
</ul>
<ul>
<li>Vous aurez remarqué au passage que j'ai donc connecté un second capteur à effet <em>Hall</em> pour mesurer la vitesse de rotation de l'éolienne, <a href="https://github.com/makotoworkshop/08-Anemometre_esp8266_WifiSVR_SPIFFS_2Hall_WifiUdp_V2">le code est dispo ici</a>.</li>
</ul>
<h3><a href="http://burogu.makotoworkshop.org/index.php?post/2019/08/05/anemometre3">À suivre…</a></h3>http://burogu.makotoworkshop.org/index.php?post/2019/01/01/anemometre2#comment-formhttp://burogu.makotoworkshop.org/index.php?feed/atom/comments/664Un anémomètre WiFi -1-urn:md5:45608fe5f374e514486debef5f494a402018-11-19T21:18:00+01:002019-02-23T15:21:45+01:00makoto doushiteEnergies RenouvelablesArduinoBricolageDIYESP8266Impression3DModélisation3DMécaniqueNodeMCUÉlectroniqueÉolienne<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03927.jpg" title="dsc03927.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03927_s.jpg" alt="dsc03927.jpg" style="float:right; margin: 0 0 1em 1em;" /></a></p>
<blockquote><p>Récemment on m'a indiqué l'existence d'une plaquette électronique du genre <em>Arduino</em>, mais qui a la particularité de pouvoir « faire du <em>WiFi</em> ».<br />
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 <em>idle</em> dans un coin de mon esprit malade, jusqu'à ressurgir suite à mes derniers travaux sur l'<a href="http://burogu.makotoworkshop.org/index.php?post/2018/09/28/eolienne-axe-vertical-11">Éolienne du jardin</a>…<br />
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.<br /></p></blockquote>
<ul>
<li>J'avais donc une plaquette <em>NodeMCUv3 LoLin</em> (à base de puce <em>ESP8266</em>) sous la main et après quelques tests j'ai constaté que bah c'est comme <em>Arduino</em>, rien de compliqué.<br /></li>
<li>Et puis pour faire client ou serveur Web, bah c'était pas comme <em>Arduino</em>… et qu'il faudrait se sortir les doigts…<br /></li>
</ul>
<p>Oui car on peut servir des pages web, alors on pense assez vite à ordi-phone et une jauge de visualisation.<br />
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 :<br /></p>
<blockquote><p>Pour mon projet final j'aurais besoin d'une plaquette <em>NodeMCU</em> 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).<br />
Les data seraient consultables via un navigateur sur un ordi ou un ordi-phone, sous forme de jauge de vitesse instantanée.<br />
Elles seraient aussi récupérable pour former des graphiques de statistiques.<br />
Un second <em>NodeMCU</em> avec des afficheurs à leds serait utilisé pour s'affranchir d'un ordi.<br /></p></blockquote>
<ul>
<li>Bon c'est pas forcément facile à suivre, alors voici un dessin :<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/anemometre3.png" title="anemometre3.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.anemometre3_m.png" alt="anemometre3.png" style="display:table; margin:0 auto;" /></a><br /></p>
<h3><ins>Simple anémomètre</ins> :</h3>
<ul>
<li>Bref, pour le moment on va juste fabriquer un anémomètre simple, avec une jauge sur ordi.<br /></li>
</ul>
<p>(voir même sur internet si on fait le nécessaire pour faire « sortir » les pages web).<br /><br /></p>
<p><strong>Matériel requis :</strong><br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03947.jpg" title="dsc03947.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03947_m.jpg" alt="dsc03947.jpg" /></a><br /></p>
<blockquote><p>- La mécanique <a href="https://www.thingiverse.com/thing:3222801">imprimée en 3D disponible ici</a>.<br />
- 1 Capteur à effet Hall <em>US1881</em> (absent de cette photo).<br />
- 2 aimants permanents au néodyme ∅6 mm x 3 mm (absent de cette photo).<br />
- 1 plaquette <em>NodeMCUv3 LoLin</em>.<br />
- 1 résistance 10kΩ.<br />
- 2 roulements à billes : ∅5 int x ∅10 ext x 4 mm.<br />
- 1 tige filetées : ∅5 mm de 10 mm de long.<br />
- 5 écrous de ∅5 mm.<br />
- 3 vis : ∅3 mm de 10 mm de long (tête fraisée).<br />
- 3 vis : ∅4 mm de 12-15 mm de long (tête poêlée).<br />
- Un ordi avec port USB et le soft <em>Arduino IDE</em>.<br /></p></blockquote>
<p><br /></p> <p><strong>Compétences requises :</strong><br /></p>
<blockquote><p>- Électronique.<br />
- Web design (html, css, JavaScript, Json).<br />
Où sinon t'as du temps et l'âme d'un bidouilleur et t'y arriveras !… du coup j'ai appris plein de trucs.<br /></p></blockquote>
<p><br /></p>
<p><strong>Le montage :</strong><br /></p>
<ul>
<li>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.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03944.jpg" title="dsc03944.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03944_s.jpg" alt="dsc03944.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03946.jpg" title="dsc03946.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03946_s.jpg" alt="dsc03946.jpg" /></a><br /></p>
<ul>
<li>Insérer un roulement dans son support, puis insérer le support dans le fond.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03935.jpg" title="dsc03935.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03935_s.jpg" alt="dsc03935.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03934.jpg" title="dsc03934.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03934_s.jpg" alt="dsc03934.jpg" /></a><br /></p>
<ul>
<li>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.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03936.jpg" title="dsc03936.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03936_s.jpg" alt="dsc03936.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03937.jpg" title="dsc03937.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03937_s.jpg" alt="dsc03937.jpg" /></a><br /></p>
<ul>
<li>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 <em>NodeMCU</em> se loge simplement à l'endroit prévu.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03940.jpg" title="dsc03940.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03940_s.jpg" alt="dsc03940.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03941.jpg" title="dsc03941.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03941_s.jpg" alt="dsc03941.jpg" /></a><br /></p>
<ul>
<li>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.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03943.jpg" title="dsc03943.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03943_s.jpg" alt="dsc03943.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03932.jpg" title="dsc03932.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03932_s.jpg" alt="dsc03932.jpg" /></a><br /></p>
<ul>
<li>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.<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03931.jpg" title="dsc03931.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03931_s.jpg" alt="dsc03931.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03930.jpg" title="dsc03930.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03930_s.jpg" alt="dsc03930.jpg" /></a><br /></p>
<ul>
<li>Reste à visser les hélices, et serrer le tout avec un écrou. (Photo en début de billet)<br /></li>
</ul>
<p><br /><br /></p>
<p><strong>Le schéma :</strong><br /></p>
<ul>
<li>Pas trop compliqué…<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/Anemometre01_bb.png" title="Anemometre01_bb.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.Anemometre01_bb_m.png" alt="Anemometre01_bb.png" style="display:table; margin:0 auto;" /></a><br /><br /></p>
<p><strong>Le câblage :</strong><br /></p>
<ul>
<li>C'est facile à câbler… Et il suffit de glisser le capteur à effet <em>Hall</em> dans une des deux fentes prévues. Avec le capteur <em>US1881</em> il faut placer deux aimants sur le support, un orienté pôle nord, et l'autre pôle sud (cf.<a href="https://www.sparkfun.com/datasheets/Components/General/Hall-US1881EUA.pdf">datasheet</a>).<br /></li>
</ul>
<p><a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03949.jpg" title="dsc03949.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03949_s.jpg" alt="dsc03949.jpg" /></a>
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/dsc03952.jpg" title="dsc03952.jpg"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.dsc03952_s.jpg" alt="dsc03952.jpg" /></a><br /><br /></p>
<p><strong>Programmation du <em>NodeMCU</em> :</strong><br /></p>
<ul>
<li>Pour programmer un <em>NodeMCU</em> avec l<em>'Arduino IDE</em> il faudra rajouter le support du module esp8266, voici 3 pages qui vous expliqueront comment faire : Via <a href="https://www.fais-le-toi-meme.fr/fr/electronique/tutoriel/programmes-arduino-executes-sur-esp8266-arduino-ide">fais-le-toi-meme.fr</a> ou <a href="http://henrysbench.capnfatz.com/henrys-bench/arduino-projects-tips-and-more/arduino-esp8266-lolin-nodemcu-getting-started/">henrys-bench</a>.<br /></li>
</ul>
<p>Tout le code de l'anémomètre est <a href="https://github.com/makotoworkshop/09-Anemometre_esp8266_WifiSVR_SPIFFS_Hall_WifiUdpV2">téléchargeable ici</a> ou en annexe à ce billet.<br />
Créer un dossier qui contiendra cette arborescence :<br /></p>
<pre class="brush: bash">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</pre>
<ul>
<li>Ainsi pour programmer la plaquette, il suffira de procéder au téléversement du projet <em>Arduino</em>, ça c'est comme d'habitude avec l<em>'Arduino IDE</em>.<br /></li>
</ul>
<blockquote><p>Contrairement à un <em>Arduino</em> classique, l'upload peut s'avèrer être très long, on peut donc augmenter la vitesse via le menu <em>Outils</em> et sélectionner <em>Upload Speed : 921600</em><br /></p></blockquote>
<ul>
<li>Et pour téléverser les fichiers <em>html</em>, <em>css</em> et <em>JavaScript</em>, il faudra cliquer <em>Outils</em> et cliquer <em>ESP8266 Sketch Data Upload</em>, ce qui aura pour effet d'immédiatement copier les fichiers contenu dans le dossier <em>data</em> sur la plaquette.<br /></li>
</ul>
<blockquote><p>Sauf que ce menu n'est pas disponible par défaut !<br />
Il faut en effet télécharger <a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/esp8266fs.jar">un fichier</a> à déposer dans le dossier du « carnet de croquis », sous une arborescence spécifique, ce qui donne chez moi : <em>/home/user/Arduino/tools/ESP8266FS/tool/esp8266fs.jar</em><br />
Tout est expliqué ici : <a href="https://github.com/esp8266/arduino-esp8266fs-plugin">https://github.com/esp8266/arduino-esp8266fs-plugin</a><br /></p></blockquote>
<p><br /></p>
<p><strong>Fonctionnement :</strong><br />
Ensuite ouvrir <em>Outils</em> > <em>Moniteur série </em>, qui devrait afficher l'adresse IP de la plaquette (sinon appuyer sur le bouton <em>Reset</em>), et rendez-vous sur un navigateur avec cette IP en <em>URL</em> et voila !<br />
<a href="http://burogu.makotoworkshop.org/public/electronique/anemometre/anemometre.png" title="anemometre.png"><img src="http://burogu.makotoworkshop.org/public/electronique/anemometre/.anemometre_s.png" alt="anemometre.png" style="display:table; margin:0 auto;" /></a><br />
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…<br />
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.<br /><br /></p>
<p><strong>Principe :</strong><br />
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 <em>NodeMCU</em> 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 <em>JSON</em> écrit en zone <em>SPIFFS</em>, qui est mis à jour toutes les secondes (valeur réglable au début du code <em>Arduino</em>)<br /><br /></p>
<p><strong>Présentation du contenu des fichiers :</strong><br />
J'ai commenté assez largement le code, mais n'espérez pas tout comprendre si un des langages vous échappe…<br /></p>
<p>Le fichier <em>JSON</em> ressemble à ceci :<br /></p>
<pre class="brush: js">{
"VitesseVent":"25"
}</pre>
<p>Lorsqu'on consulte la page Web, le JavaScript contenant la jauge est appelé et celui-ci récupére la valeur du <em>JSON</em> pour animer l'aiguille et afficher la valeur, toutes les secondes (en adéquation avec le réglage du code <em>Arduino</em>)<br /></p>
<ul>
<li>Le fichier <em>data/js/jquery.min.js</em> est une libraire standard (ou un truc du genre) qui se télécharge <a href="https://code.jquery.com/jquery/">sur internet</a>.<br /></li>
<li>Le fichier <em>data/js/loader.js</em> est une libraire google (ou un truc du genre) qui se télécharge chez <em><a href="https://developers.google.com/chart/">google chart</a></em>.<br /></li>
</ul>
<ul>
<li>Le fichier <em>data/js/java_vent.js</em>, qu'on aura écrit en adaptant <a href="https://developers.google.com/chart/interactive/docs/gallery/gauge">la librairie graphique <em>gauge</em></a> de <em>google chart</em>.<br /></li>
</ul>
<pre class="brush: js">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
});
});
}
}</pre>
<ul>
<li>Le fichier <em>data/css/style.css</em> pour la mise en page :</li>
</ul>
<pre class="brush: css">.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%);
}</pre>
<ul>
<li>Le fichier <em>data/index.html</em>, où l'on charge les 3 <em>JavaScripts</em> et la feuille de style <em>css</em>. Puis on y appelle le graphisme de la gauge.</li>
</ul>
<pre class="brush: xml"><!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></pre>
<ul>
<li>Le fichier <em>Anemometre_esp8266_WifiSVR_SPIFFS_Hall.ino</em>, qui contient le code C++ type « <em>Arduino</em> », pour mesurer la vitesse de rotation et envoyer les données au serveur Web.</li>
</ul>
<pre class="brush: cpp">#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
}</pre>
<p>Projet inspiré de celui-ci :<br />
<a href="https://projetsdiy.fr/projet-diy-anemometre-girouette-objet-connecte-esp8266/">https://projetsdiy.fr/projet-diy-anemometre-girouette-objet-connecte-esp8266/</a><br />
<a href="https://projetsdiy.fr/esp8266-web-serveur-partie5-gauges-graphiques-google-charts/#top_ankor">https://projetsdiy.fr/esp8266-web-serveur-partie5-gauges-graphiques-google-charts/#top_ankor</a><br /><br /></p>
<h3><a href="http://burogu.makotoworkshop.org/index.php?post/2019/01/01/anemometre2">À Suivre…</a></h3>http://burogu.makotoworkshop.org/index.php?post/2018/11/12/anemometre#comment-formhttp://burogu.makotoworkshop.org/index.php?feed/atom/comments/660