Samedi, janvier 5 2019

Un anémomètre WiFi -2-

Suite de l'étude précédente :

  • Avoir un affichage sur le web c'est bien…

Une petite vidéo :

  • Mais un module d'affichage physique c'est quand même plus pratique !

Une petite vidéo :

  • J'ai donc passé quelques jours à concevoir ce boîtier client qui fonctionne à base lui aussi d'un NodeMCU connecté au réseau WiFi de la maison, et qui récupère les infos de vitesse transmise par l'anémomètre.

Principe :

Ce client se connecte à l'anémomètre et récupère le fichier JSON ( http://192.168.0.34:8080/mesures.json) afin de le parser toutes les secondes, reste alors à afficher l'information.

Ce sont donc des vieux afficheurs matriciel DLG7137 qui vont faire le travail.
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 WebRadioReveilWiFi, mais ne disposant pas de suffisamment de 74HC595, j'ai dû procéder autrement.
Les DLG7137 disposent en effet d'une pin Write (WR/) qui n'autorise l'affichage de la donnée qu'au moment où elle passe à l'état bas.
Du coup en reliant tous les afficheurs entre eux et en faisant circuler l'information, il restait au programme de valider la pin Write du bon afficheur au bon moment pour afficher le caractère attendu sur chacun des afficheurs.
Et comme le NodeMCU ne dispose pas de suffisamment de papattes pour pouvoir brancher les 12 pins Write des 12 afficheurs, j'ai donné ce travail à faire à deux registres 74HC595, permettant ainsi d'adresser 16 pins Write.

ClientAfficheur_bb.png
Note : J'ai oublié de câbler les deux condensateurs de découplage utiles aux registres 74HC595 !!
Ne les oubliez-pas ! (100nF directement entres les pattes d'alimentation 8 et 16)

Réalisation :

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 dessiné le boîtier en 3D pour impression.

  • La plaquette à trous :

dsc03958.jpg dsc03960.jpg

  • Le boîtier imprimé, avec un petit bouton pour appuyer sur le reset du NodeMCU.

dsc03956.jpg dsc03957.jpg

  • J'ai trouvé un morceau de plexis de 2mm d'épaisseur, que j'ai peint sur l'envers à l'aérographe au Tamiya smoke X-19 afin de donner un côté fumé à ce vitrage, ensuite collé à l'intérieur du boîtier :

dsc03961.jpg dsc03962.jpg

  • La plaquette est mise en place en la glissant dans la rainure prévue, puis c'est au tour du couvercle :

dsc03964.jpg dsc03965.jpg

  • Voilà…

dsc03966.jpg dsc03969.jpg]

  • C'est classe moi j'dis :D :

dsc03967.jpg dsc03971.jpg
Le module affiche NoData lorsque la transmission de donnée se passe mal, comme par exemple lorsque l'anémomètre est éteint.

Programme :

  • Le code du NodeMCU est trop imposant pour être présenté correctement dans cette page, il est téléchargeable en pièce jointe ou consultable ici.

  • Vous aurez remarqué au passage que j'ai donc connecté un second capteur à effet Hall pour mesurer la vitesse de rotation de l'éolienne, le code est dispo ici, mais pour le moment je n'en parle pas plus car il me faudrait l'améliorer… En effet les valeurs récupérées sont relativement toujours les mêmes, des sortes de paliers en somme, ce qui ne me convient pas…

Vendredi, janvier 4 2019

Une éolienne à axe vertical -12-

Suite de l'ouvrage précédent :

L'éolienne n'avait pu être mise en place la dernière fois, faute de visserie suffisante pour terminer l'assemblage, et de coupleur de câble métallique nécessaire à la sécurisation du mât.

dsc03985.jpg

  • Nous avons donc dressé le mât sur son emplacement, vissé le boulon de sécurisation et resserré les 4 écrous du plot.

Ensuite après avoir enfoncé des piquets dans le sol, trois câbles ont été tendu pour raccorder ces piquets aux anneaux soudés au sommet du mât, grâce aux coupleurs de câble.
Sans système de tendeur à vis ce ne fût pas vraiment facile à régler, mais le mât est tout de même quasi de niveau, à 90° dans toutes les directions.
dsc03984.jpg dsc03982.jpg
dsc03981.jpg dsc03988.jpg

Ce n'est qu'ensuite que nous avons suspendu le rotor de l'éolienne au mât, je n'ai pas fait de photo du mât seul…

  • Au sommet du mât, on peut apercevoir l'anémomètre que j'avais bricolé, et contre l'axe de rotation, un aimant sécurisé au silicone (tout autre type de colle aurait fait l'affaire), passe en face de la pièce imprimée3D orange dans laquelle siège un capteur Hall, branché sur le NodeMCU de l'anémomètre, permettant de transmettre les vitesses du vents et de rotation de l'éolienne sur un boîtier récepteur (billet à venir) :

dsc03972.jpg 20181230_144315.jpg

Bon alors ces photos ont en fait été prises le lendemain, car le jour ou nous l'avons accroché, la nuit tombait, et j'ai donné les derniers coup de clef dans la pénombre…

Les ailes étaient alors repliées et nous pensions la laisser comme ça jusqu'au lendemain, mais la tentation de l'ouvrir était trop grande !

  • Une petite vidéo :

dsc03976.jpg Le lendemain j'ai donc fignolé ce qu'il y avait à fignoler, et pris tous ces clichés tranquillement, ainsi qu'une seconde vidéo.

  • Il n'y avait quasi pas de vent, on peut voir l'anémomètre s’arrêter, mais l'éolienne continue de tourner par inertie.

Car oui, pour le moment ça tourne à vide, elle sera décrochée afin d'être peinte.


dsc03979.jpg dsc03980.jpg

  • Une petite vidéo :


  • Cette éolienne Savonius est absolument silencieuse et démarre très facilement à faible vent, sachant que le haut des ailes est perché à 3m58, et le bas à 2m70.

La suite ?

L'ingénierie à donc été ici faite au fur et à mesure, rythme imposé par la nature des matériaux de récupération qui constituent cette éolienne.

Je sais que de par sa nature, cette machine à un mauvais rendement, et il est fort probable que produire du courant exploitable avec tournera à l'échec, auquel cas elle pourrait finir par exemple, en éolienne de pompage mécanique.

J'ai vu aussi que depuis le début de cet ouvrage, il y a 3 ans, pas mal d'autres travaux avaient poppé par-ci par-là, et notamment l'idée de coupler une éolienne Darrieus à l'éolienne Savonius, afin de bénéficier des avantages de ces deux types, tout en réduisant les inconvénients.

  • Malgré tout, je vais passer maintenant à l'étude de la génératrice et je fais des recherche en ce sens.

Ce projet notamment pourrait bien m'aider à avancer…
https://hackaday.io/project/159568-portal-point-generator
Sur le web il y a pas mal de documentation vidéos et photos sur le sujet, mais je constate avec déception, que côté littérature, y'a pas grand chose.
Tous les projets que j'ai pour le moment découvert semblent avancer de manière empirique et rien n'est documenté quant aux calculs électromagnétiques concernant notamment la détermination du type de fil (diamètre, nb de spires), puissances attendue, force de résistances prévue… Bref, pas de théorie.
Le soucis c'est que je ne suis pas à l'aise avec ce sujet, et soit je tombe sur ce genre de ressources donc sans théorie ni calculs expliqués, soit je trouve des cours théoriques d'électromagnétisme auxquels je ne pige rien. Pas de ressources ayant donc synthétisé les deux, simplement.

  • Si vous avez de bonnes adresses, je suis preneur !!

Voici quelques liens qui synthétisent assez bien le concept :
La conversion d'un alternateur en générateur : https://www.youtube.com/watch?v=VRaiHStZ1A8
L'explication simple de la production d'électricité : https://www.youtube.com/watch?v=ZaIn6tjfquo
http://www.fabriquer-eolienne.com/fabrication-generateur/
http://lowtechlab.org/wiki/Eolienne_200W

Lundi, novembre 19 2018

Un anémomètre WiFi -1-

dsc03927.jpg

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

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

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

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

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

anemometre3.png

Simple anémomètre :

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

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

Matériel requis :
dsc03947.jpg

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


Compétences requises :

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


Le montage :

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

dsc03944.jpg dsc03946.jpg

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

dsc03935.jpg dsc03934.jpg

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

dsc03936.jpg dsc03937.jpg

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

dsc03940.jpg dsc03941.jpg

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

dsc03943.jpg dsc03932.jpg

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

dsc03931.jpg dsc03930.jpg

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



Le schéma :

  • Pas trop compliqué…

Anemometre01_bb.png

Le câblage :

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

dsc03949.jpg dsc03952.jpg

Programmation du NodeMCU :

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

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

Anemometre_esp8266_WifiSVR_SPIFFS_Hall/Anemometre_esp8266_WifiSVR_SPIFFS_Hall.ino
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/index.html
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/css/style.css
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/js/java_vent.js
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/js/jquery.min.js
Anemometre_esp8266_WifiSVR_SPIFFS_Hall/data/js/loader.js
  • Ainsi pour programmer la plaquette, il suffira de procéder au téléversement du projet Arduino, ça c'est comme d'habitude avec l'Aruino IDE.
  • Et pour téléverser les fichiers html, css et JavaScript, il faudra cliquer sur Outils et sélectionner Upload Speed : 921600; Ensuite à nouveau Outils et cliquer ESP8266 Sketch Data Upload, ce qui aura pour effet d'immédiatement copier les fichiers contenu dans le dossier data sur la plaquette.

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

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

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

Le fichier JSON ressemble à ceci :

{
  "VitesseVent":"25"
}

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

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

      function drawChart() {    // Fonction principale : 

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

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

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

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

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

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

          $.getJSON('/mesures.json',

            function(data) {

              $.each(data,

                function(nom, valeur) {

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

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

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

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

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

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

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


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


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

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

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

À Suivre…

Jeudi, novembre 1 2018

WebRadioRéveilWifi -Fin-

Suite de l'étude précédente :

Une petite vidéo :

Mercredi, octobre 31 2018

Impression en 3D d’un capot à poussière pour affleureuse Bosch

L’utilisation de mon affleureuse génère beaucoup de poussières difficiles à capter. Pour améliorer la récupération des poussières, j’ai modelé un capot à l’aide de freecad.

De part la forme de la pièce, l’impression de supports est indispensable. Le connecteur pour l’aspirateur est standard et fait 35mm.

L’impression est réalisée en ABS avec des couches de 0.2mm.

La pièce est disponible en téléchargement sur Thingiverse.

Dimanche, septembre 30 2018

WebRadioRéveilWifi -7-

Suite de l'étude précédente :

On a vu comment intégrer l'électronique de l'horloge, et on va regarder comment intégrer tout le reste, cependant il manque la partie pilotage du Raspberry pour les commandes de la WebRadio.
Et puis quelques trucs que j'ai ajouté par la suite, comme un bouton power off et l'interfaçage avec l'arduino. J'avais fait ça sur le tas, avec des plaquettes à trous, et des bouts de schéma épars…

Je me suis donc efforcé de mettre tout cela au propre sur Kicad.

La carte interface :

  • Le Schéma structurel de la carte interface :

interfaceStructurel.png
On retrouve donc les 3 boutons utiles pour la WebRadio (Playlist1/Playlist2/Stop, Station précédente, Station suivante), un Relai pour déclencher la mise sous tension de l'ampli audio, et un autre pour allumer l'écranLCD.
Les deux relais sont pilotés par le Rpi, et celui de l'ampli est aussi piloté par l'horloge, pour permettre à l'alarme de retentir.
L'horloge est aussi reliée au Rpi pour le déclenchement de la WebRadio.

  • Le circuit de la carte interface :

interface.png
interfaceDessousCuivre.png interfaceDessusCuivre.png interfaceSerigraphie.png

  • Liste des composants:
Nom                 Type et valeur

R1 à R12            Résistances  10kΩ
C1 à C7             Condensateur 100nF
Q1, Q3, Q4          Transistor 2N2222
Q2                  Transistor BS170 ou BS138
K1 et K2            Relais D31C2100
J1 à J15            Pin Header

Voilà donc cette unique carte (avec sa petit séquelle pour le bouton power off) contient la même chose que sur les 3 cartes à trous suivantes.

  • Voici la première, qui concerne les boutons le la WebRadio :

Vous apprécierez le recyclage d'une nappe de disque dur IDE pour la connexion au Rpi.
dsc03532.jpg dsc03530.jpg

  • La deuxième, pour l'interfaçage Rpi <-> Arduino, et le pilotage via relais :

dsc03547.jpg dsc03548.jpg

  • Et la dernière, pour le bouton power off :

dsc03540.jpg dsc03541.jpg

Intégration du Raspberry Pi :

Revenons donc à l'assemblage du WebRadioReveilWifi.
On viens de le voir sur les clichés précédent, il faut fixer le Raspberry avec des vis sur la façade arrière du boitier, et le bouton power off également.

  • Avec de courtes vis de 3 mm de diamètre, et parfois des rondelles pour régler la profondeur de débattement des boutons, si nécessaire.

Intégration des boutons de commande de l'horloge :

dsc03485.jpg

  • Après avoir glissé les boutons imprimés en vert dans leur logement, il suffit de disposer le circuit, les rondelles et de visser ce montage sur le boîtier.

dsc03484.jpg dsc03486.jpg

Intégration des boutons de commande de la WebRadio :

  • Même travail pour visser la plaque à trou. C'est donc ici que j'aurais placé la carte développée en début de ce billet, si je l'avais réalisée au propre.

dsc03546.jpg dsc03534.jpg dsc03535.jpg dsc03536.jpg

Intégration de l'ampli audio :

  • Sur le prototype de la carte ampli audio il n'y avait pas de mélangeur audio, j'ai donc dû le rajouter avec une plaquette à trou, reliée avec les fils jaunes.

Le schéma et le typon de la carte de l'ampli présenté dans les billets précédents intègrent déjà le mélangeur.
dsc03544.jpg dsc03545.jpg

dsc03556.jpgLa carte de l'horloge a été remise en place, ainsi que les haut-parleurs. On pouvait donc placer la carte de l'ampli… Le dessous de la plaquette du mélangeur est isolé avec le la colle chaude, ensuite simplement collé sur l'ampli.

dsc03552.jpg dsc03553.jpg

dsc03542.jpg

Sur la face arrière il y a les fentes permettant d'accéder au potentiomètre Volume et Bass, le trou pour la led power et un jack de sortie femelle 3,5 mm a été fixé. Utile si on veut utiliser un casque.



Intégration de l'écran LCD :

L'écran LCD est un appareil qui à la base sert de retour vidéo de radar de recul pour véhicule. Je l'avais pris à l'époque, ça n'était pas cher, autour de 15€, cependant depuis on fait mieux pour autant, et surtout de meilleure qualité. La résolution max de l'écran est de 640x480, pour une piètre qualité d'image, mais reste suffisant pour être utilisé avec Kodi pour le peu qu'on règle correctement l'affichage. Reportez-vous au billet N°5.
Il se connecte simplement sur la prise RCA Jaune, en vidéo composite donc, et s'alimente en 12V… Et c'est là qu'est le hic !
J'ai tenté d'utiliser des convertisseurs DC/DC boost pour alimenter l'écran en élevant ainsi la tension de 5V à 12V, mais bien que cela fonctionne, l'utilisation avec le pilotage de l'alimentation via le relai posait problème. L'appel d'énergie au moment de la commutation était tel que le Rpi se voyait rebooté; Et l'ajout de condensateurs n'arrangeait malheureusement pas les choses.
dsc03537.jpg J'ai donc dû me résoudre à modifier l'écran, car j'avais eu l'info comme quoi il était possible d'alimenter ce type d'écran en 5V, moyennant bidouille.

  • La difficulté étant que les modèles de circuits de ces écrans là sont assez variés, les informations qu'on trouve se devaient d'être les plus précises possible… et en recoupant plusieurs (maigres) sources, j'ai donc synthétisé la bidouille comme ceci :

dsc03682.jpg dsc03680.jpg
Il fallait donc retirer la diode D4, les selfs L13 et L14, raccorder avec un bout de fil la diode D3 et le CI U2. Alors on peut injecter 5V au lieu de 12V sur le fil rouge pour voir l'écran s'allumer.
Ainsi modifié, le pilotage ON/OFF de l'écran via le relai est tout à fait fonctionnel

  • Le câble alim/vidéo étant passé par le trou prévu dans le boîtier, l'écran est vissé sur la plaquette de la charnière imprimée.

dsc03562.jpgEnsuite on assemble la charnière avec la tige d'un trombone qu'il suffit de glisser dans le trou qu'on aura agrandi avec un foret de 1 mm, et nous voilà avec un écran escamotable.
dsc03563.jpg dsc03564.jpg

Avant de refermer le boitier :

Ça y est, tout est en place, il reste à loger tout ça tranquillement…
dsc03560.jpg

  • Isoler la carte à trou d'interface dans un sac plastique, loger les nappes et câbles de connecteurs.

dsc03557.jpg dsc03558.jpg

Voici ce que ça donne en face arrière.
dsc03590.jpg dsc03589.jpg

Dernières modifs :

En façade avant il restait le trou laissé par la trappe de maintenance pour l'accès à l'arduino, sur le dessus, dans la même idée, le trou permettant de brancher un écran via HDMI, et l'écranLCD ne tiens pas debout tout seul une fois déployé.
J'ai donc modélisé/imprimé quelques pièces supplémentaires :

  • Le cache pour la trappe de façade.

Avec un trou pour y coller le capteur de lumière (ajustement éclairage des afficheurs de l'horloge) et un autre pour coller le capteur infrarouge (télécommande Kodi) dsc03661.jpg dsc03686.jpg

  • Un pied escamotable pour maintenir l'écran à la verticale.

dsc03684.jpg dsc03685.jpg

  • Un cache pour le port HDMI.

dsc03687.jpg dsc03683.jpg

Terminé !

La prochaine fois je ferais une vidéo de démonstration.
dsc03705.jpg dsc03702.jpg
dsc03700.jpg dsc03699.jpg

  • Voilà, donc cette machine fonctionne depuis un an à mon chevet, sans problème majeur autre qu'une corruption de carte SD ayant entrainé le plantage du Rpi.

Pas de réveil par la radio donc, mais j'ai quand même été réveillé par l'horloge et son alarme, étant donné qu'elle s'adresse aussi directement à l'ampli audio.
Les quelques moments où la connexion internet a été perdue, la playlist de secours en fichiers mp3 s'est déclenchée comme prévu !

  • L'appareil consomme assez peu d'énergie, entre 360 mA et 1,3 A, voici plus en détail ce que j'ai mesuré :

- Horloge : luminosité à fond (PWM 255) = 0,200 A
- Horloge : luminosité au minimun (PWM 8) = 0,028 A
- Horloge + Rpi (wifi) au repos : luminosité à fond = 0,527 A
- Horloge + Rpi (wifi) + radio avec ampli (volume au 1/4) : luminosité à fond = 0,600 A
- Horloge + Rpi (wifi) + radio avec ampli (volume au max) : luminosité à fond = 0,750 A
- Horloge + Rpi (wifi) + Kodiavec écranLCD + ampli au repos : luminosité à fond = 1,25 A
- Horloge + Rpi (wifi) + Kodi avec écranLCD + ampli : luminosité à fond = 1,3 A

À suivre…

Samedi, septembre 29 2018

Une éolienne à axe vertical -11-

Suite de l'ouvrage précédent :

  • Le plot en béton a donc eu tranquillement le temps de sécher, le socle a été vissé sur place, et était donc prêt pour y glisser la potence :

Elle sera par la suite sécurisée par un boulon afin de solidariser ces deux pièces, et aussi 3 câbles métalliques tendu, ancrés au sol.
dsc03900.jpg dsc03903.jpg

  • J'ai modélisé et imprimé un cône sur mesure pour coiffer le poteau afin d'éviter que l'eau de pluie n'y ruisselle :

dsc03905.jpg dsc03907.jpg dsc03909.jpg dsc03911.jpg

  • Après avoir défait le montage provisoire des ailes, il est temps de remonter le tout en utilisant vis, écrous et rondelles afin de tout bien ajuster, pour une rotation. des ailes la plus facile possible.

Mais avant deux trous ont été pratiqués dans la croix d'articulation pour pouvoir y fixer le ressort de maintient ouvert. Pour la même raison, deux trous également dans les ailes.
dsc03912.jpg dsc03913.jpg

  • Une petite vidéo :

Le ressort n'est pas encore dans sa position optimale et les têtes de vis gênes sa course, elles seront coupées. Il faudra prévoir un système pour gérer la tension du ressort, afin de régler la vitesse maximale de rotation de l'éolienne.

À suivre…

Dimanche, septembre 23 2018

Bouton on/off Raspberry Pi, Version µContrôleur

Comme je l'évoquais, je ne compte pas utiliser la version précédente du montage « power on/off » pour mon « Pi Hat », car le relais prendrait trop de place, j'ai donc travaillé sur cette nouvelle version à base d'un microcontrôleur Attiny85.

  • Voici donc le schéma de ce nouveau montage :

RpiOnOffAttiny85.png

  • Fonctionnement :

- Pour mettre en route le Rpi, effectuer une pression sur SW1, la sortie PB0 de l'ATtiny85 est alors mise à l'état bas pour permettre au transistor MOSFET de faire passer le 5V au Rpi.
Ici, comme pour le montage précédent, le signal TXD0 est exploité pour connaître l'état du Rpi au moment où le bouton est pressé (état bas, car Rpi éteint) .
- Pour éteindre le Rpi, presser normalement le bouton SW1, ce qui enverra le signal à la sortie PB1 de passer brièvement à l'état haut, pour déclencher un arrêt propre de GNU/Linux via le GPIO21 du Rpi, grâce au script Python3 ci-dessous.
Le pont diviseur que forment R11 et R12 permet de ne n'envoyer que 3,2V au GPIO, car rappelez-vous bien que le Rpi fonctionne en 3,3V !!
- Une fois arrêté de cette manière, le signal TXD0 passe donc à l'état bas, l'état du GPIO ayant été mémorisé, un délai est octroyé pour couper l'énergie et donc 3 secondes après la dernière activité de la led verte du Rpi, la sortie PB0 passe à l'état haut, le transistor MOSFET ne laisse plus passer le 5V au Rpi.
- Presser le bouton SW1 plus de 3 secondes et le courant sera coupé brutalement, utile en cas de plantage du Rpi
- Ce montage gère le reboot. Par contre si on utilise un sudo poweroff sur le Rpi, le courant ne sera pas coupé automatiquement comme avec le relay du montage précédent. Il faudra alors presser SW1 plus de 3 secondes.

  • Prérequis :
sudo apt-get install python3 RPi.GPIO
  • Écrire le script :
nano /home/pi/SoftOffButton.py

Avec dedans :

import RPi.GPIO as GPIO
import time
import os
import signal

print ("Soft Off Button")

GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

def button_pressed(channel):
    print ("Boutton Off pressé")
    os.system("sudo poweroff")

GPIO.add_event_detect(21, GPIO.RISING, callback=button_pressed)

signal.pause()

Pour démarrer automatiquement le programme python dés le démarrage du Raspberry, il faut créer un service :

sudo nano /etc/systemd/system/SoftOffButton.service

Avec dedans :

[Unit]
Description=Démarre le script SoftOffButton
[Service]
ExecStart=/usr/bin/python3 /home/pi/SoftOffButton.py
[Install]
WantedBy=multi-user.target

Installer le service au démarrage :

sudo systemctl --system daemon-reload
sudo systemctl enable SoftOffButton.service

Pour manipuler le service :

sudo systemctl status SoftOffButton.service
sudo systemctl start SoftOffButton.service
  • Quelques composants sont au format CMS pour le montage sur plaquette labo, car ils serviront au « Pi Hat » que je réaliserais.

20180923_215557.jpg
L'ATiny85 et le MOSFET sont câblés sur des pin header avec du fil émaillé RoadRunner super pratique, conseillé par Sacha !

  • Programme ATtiny85 :

Voici le programme à coller dans le µContrôleur, j'ai utilisé la méthode décrite par Héliox pour le programmer via un ArduinoUNO :

#define relaisMOSFET 0  //PB0, pin5
#define Bouton 2        //PB2, pin7
#define TDX0 3          //PB3, pin2
#define BoutonGPIO21 1  //PB1, pin6
#define STATE_NORMAL 0  // no button activity
#define STATE_SHORT 1   // short button press
#define STATE_LONG 2  // long button press
volatile int  resultButton = 0; // global value set by checkButton()
int EtatTXD0;
int EtatBouton;
int var = 0;

void setup() {
  attachInterrupt(0, checkButton, CHANGE);
  pinMode(Bouton, INPUT_PULLUP);
  pinMode(TDX0, INPUT);
  pinMode(BoutonGPIO21, OUTPUT);
  pinMode(relaisMOSFET, OUTPUT);
  digitalWrite(relaisMOSFET, HIGH); // power off
}

/*****************************************************************/
void checkButton() { // appelée par interruption à l'appuie sur le bouton
  /*
  * This function implements a short press and a long press and identifies between
  * the two states. Your sketch can continue processing while the button
  * function is driven by pin changes.
  * https://www.electro-tech-online.com/threads/dual-state-pushbutton-debounced-using-interrupts-for-arduino.147069/
  * Modifié par MakotoWorkshop
  */
  const unsigned long LONG_DELTA = 3000ul;               // hold seconds for a long press
  const unsigned long SHORT_DELTA = 0ul;               // hold seconds for a long press

  static int lastButtonStatus = HIGH;                                   // HIGH indicates the button is NOT pressed
  int buttonStatus;                                                                    // button atate Pressed/LOW; Open/HIGH
  static unsigned long longTime = 0ul, shortTime = 0ul; // future times to determine is button has been poressed a short or long time
  boolean Released = true, Transition = false;                  // various button states
  boolean timeoutShort = false, timeoutLong = false;    // flags for the state of the presses

  buttonStatus = digitalRead(Bouton);                // read the button state on the pin "Bouton"
  timeoutShort = (millis() > shortTime);                          // calculate the current time states for the button presses
  timeoutLong = (millis() > longTime);

  if (buttonStatus != lastButtonStatus) {                          // reset the timeouts if the button state changed
      shortTime = millis() + SHORT_DELTA;
      longTime = millis() + LONG_DELTA;
  }

  Transition = (buttonStatus != lastButtonStatus);        // has the button changed state
  Released = (Transition && (buttonStatus == HIGH)); // for input pullup circuit

  lastButtonStatus = buttonStatus;                                     // save the button status

  if ( ! Transition) {                                                                //without a transition, there's no change in input
  // if there has not been a transition, don't change the previous result
       resultButton =  STATE_NORMAL | resultButton;
       return;
  }

  if (timeoutLong && Released) {                                      // long timeout has occurred and the button was just released
       resultButton = STATE_LONG | resultButton;       // ensure the button result reflects a long press
  } else if (timeoutShort && Released) {                          // short timeout has occurred (and not long timeout) and button was just released
      resultButton = STATE_SHORT | resultButton;     // ensure the button result reflects a short press
  } else {                                                                                  // else there is no change in status, return the normal state
      resultButton = STATE_NORMAL | resultButton; // with no change in status, ensure no change in button status
  }
}
/*****************************************************************/

void loop() {
  SoftPowerONOFF();
  HardPowerOFF();   // Coupe l'alim brutalement
  delay(170);       // wait for a second
}

/*****************************************************************/
void SoftPowerONOFF() {
  EtatTXD0 = digitalRead(TDX0);

  if ((EtatTXD0 == LOW) && (resultButton == STATE_SHORT)) //POWER ON via bouton
  {
    digitalWrite(relaisMOSFET, LOW); // power on
    resultButton=STATE_NORMAL;
  }
  
  else if ((EtatTXD0 == HIGH) && (resultButton == STATE_SHORT)) //SOFT POWER OFF via bouton, étape1/2
  {
    digitalWrite(BoutonGPIO21, HIGH); // 3,2V envoyé au Rpi -> appel du Script Rpi Shutdown
    delay(200);                       
    digitalWrite(BoutonGPIO21, LOW);  // 0V
    var = 1;
    resultButton=STATE_NORMAL;
  }
  
  else if ((EtatTXD0 == LOW) && (var == 1)) //SOFT POWER OFF via bouton, étape2/2
  {
    delay(7000);    // délai pour couper l'énergie, 3 sec après la dernière activité led verte du Rpi
    digitalWrite(relaisMOSFET, HIGH);  //power off
    var = 0;
  } 
}

/*****************************************************************/
void HardPowerOFF() {
  if ((resultButton == STATE_LONG)) // appuie long sur le bouton (3 sec)
  {
    digitalWrite(relaisMOSFET, HIGH);  //power off
    resultButton=STATE_NORMAL;
  }
}

- page 1 de 99