C'est l'hiver ! Hiver.gif

ENIB 2026 : Girouette : Différence entre versions

De Les Fabriques du Ponant
Aller à : navigation, rechercher
(étape 2)
(Amélioration possible)
 
(8 révisions intermédiaires par le même utilisateur non affichées)
Ligne 7 : Ligne 7 :
 
==Introduction==
 
==Introduction==
  
éventuelle vidéo
+
L’objectif de ce projet est de concevoir un dispositif simple mêlant électronique, programmation et fabrication manuelle. La girouette est commandée par un servomoteur, lui-même piloté par une carte ESP32. Ce projet nous a permis de découvrir les contraintes liées au choix du matériel, à la compatibilité des bibliothèques logicielles et au prototypage rapide.
 +
 
 
==outil et matériel==
 
==outil et matériel==
 
Un servomoteur 180°
 
Un servomoteur 180°
Ligne 23 : Ligne 24 :
 
===Mettre du code Arduino===
 
===Mettre du code Arduino===
 
<syntaxhighlight lang="Arduino" line>  
 
<syntaxhighlight lang="Arduino" line>  
#define PIN 9
+
#include <WiFi.h>
#include <Arduino_GFX_Library.h>
+
#include <HTTPClient.h>
 +
#include <ArduinoJson.h>
 +
#include <ESP32Servo.h>
 +
 
 +
// ------------------- VOS PARAMETRES WIFI -------------------
 +
const char* ssid = "FABLAB 2.4";
 +
const char* password = "MonPetitPonant";
 +
 
 +
// ------------------- VOTRE LOCALISATION (Ex: Brest) -------------------
 +
// Trouvez les vôtres sur Google Maps (clic droit sur la carte)
 +
const float latitude = 48.3904;
 +
const float longitude = -4.4861;
 +
 
 +
// ------------------- PINS DE BRANCHEMENT -------------------
 +
const int servoPin = 13;  // Fil Orange du servo
 +
const int buttonPin = 12; // Un côté du bouton (l'autre au GND)
 +
 
 +
// ------------------- OBJETS ET VARIABLES -------------------
 +
Servo windServo;
 +
 
 +
// Timer pour ne pas bloquer l'API (Mise à jour toutes les 15 minutes)
 +
unsigned long lastTime = 0;
 +
unsigned long timerDelay = 900000; // 15 minutes en millisecondes
  
 
void setup() {
 
void setup() {
   // put your setup code here, to run once:
+
  Serial.begin(115200);
 +
  Serial.println("Test");
 +
 
 +
   // 1. Configuration du Servo (ESP32Servo)
 +
  windServo.setPeriodHertz(50); // Standard 50hz servo
 +
  windServo.attach(servoPin, 500, 2400); // Plage d'impulsion standard pour ESP32
 +
 
 +
  // Test de démarrage : Balayage rapide pour montrer qu'il est vivant
 +
  windServo.write(0); delay(500);
 +
 
 +
  // 2. Configuration du Bouton
 +
  pinMode(buttonPin, INPUT_PULLUP);
 +
 
 +
  // 3. Connexion WiFi
 +
  WiFi.begin(ssid, password);
 +
  Serial.print("Connexion au WiFi");
 +
  while (WiFi.status() != WL_CONNECTED) {
 +
    delay(500);
 +
    Serial.print(".");
 +
  }
  
 +
  Serial.print("\nConnected to Wi-Fi network with IP Address: ");
 +
  Serial.println(WiFi.localIP());
 +
 
 +
  // Première mise à jour immédiate
 +
  getAndDisplayWind();
 
}
 
}
  
 
void loop() {
 
void loop() {
   // put your main code here, to run repeatedly:
+
   // Vérification du timer (Automatique)
 +
  if ((millis() - lastTime) > timerDelay) {
 +
    getAndDisplayWind();
 +
  }
 +
 
 +
  // Vérification du bouton (Manuel)
 +
  // Si on appuie, on force la mise à jour
 +
  if (digitalRead(buttonPin) == LOW) {
 +
    Serial.println("Bouton pressé -> Mise à jour...");
 +
    getAndDisplayWind();
 +
    delay(1000); // Anti-rebond (attendre un peu)
 +
  }
 +
}
 +
 
 +
// Fonction principale qui fait tout le travail
 +
void getAndDisplayWind() {
 +
  if(WiFi.status() == WL_CONNECTED) {
 +
    HTTPClient http;
 +
 
 +
    // Construction de l'URL Open-Meteo
 +
    String serverPath = "https://api.open-meteo.com/v1/meteofrance?latitude=" + String(latitude) +
 +
                        "&longitude=" + String(longitude) +
 +
                        "&current=wind_direction_50m";
 +
   
 +
    Serial.println("Requete API en cours...");
 +
    http.begin(serverPath);
 +
    int httpResponseCode = http.GET();
 +
   
 +
    if (httpResponseCode > 0) {
 +
      String payload = http.getString();
 +
     
 +
      // Analyse du JSON (Parsing)
 +
      DynamicJsonDocument doc(1024);
 +
      DeserializationError error = deserializeJson(doc, payload);
 +
 
 +
      if (!error) {
 +
        // Lecture de la direction (0 à 360°)
 +
        float windDir360 = doc["current"]["wind_direction_50m"];
 +
       
 +
        Serial.print("Direction Vent Réelle : ");
 +
        Serial.print(windDir360);
 +
        Serial.println(" degrés");
 +
 
 +
        // Conversion pour le servo (360 -> 180)
 +
        moveServoToWind(windDir360);
 +
       
 +
      } else {
 +
        Serial.print("Erreur JSON: ");
 +
        Serial.println(error.c_str());
 +
      }
 +
    } else {
 +
      Serial.print("Erreur HTTP: ");
 +
      Serial.println(httpResponseCode);
 +
    }
 +
    http.end();
 +
    lastTime = millis(); // Reset du timer
 +
  } else {
 +
    Serial.println("Erreur : WiFi coupé !");
 +
  }
 +
}
 +
 
 +
void moveServoToWind(float angle360) {
 +
  // C'est ici que la "magie" opère.
 +
  // La fonction map(valeur, min_in, max_in, min_out, max_out)
 +
  // transforme l'échelle 0-360 en 0-180.
 +
 
 +
  int servoAngle = map((long)angle360, 0, 360, 0, 180);
 +
 
 +
  // Sécurité pour ne pas forcer le moteur
 +
  if (servoAngle < 0) servoAngle = 0;
 +
  if (servoAngle > 180) servoAngle = 180;
 +
 
 +
  Serial.print("Position Servo : ");
 +
  Serial.println(servoAngle);
  
 +
  windServo.write(servoAngle);
 
}
 
}
  
Ligne 41 : Ligne 162 :
 
indiquer autant d'étape que nécessaire, chacune illustrée par des images (photo, dessins, ...)
 
indiquer autant d'étape que nécessaire, chacune illustrée par des images (photo, dessins, ...)
  
===étape 1===
+
===étape 1 : Test des servomoteurs===
  
 
Nous avons commencé par tester les servomoteurs à l’aide de codes fournis sur le wiki des Débrouillards. Cependant, ces codes ne fonctionnaient pas avec les versions de la carte que nous utilisions.
 
Nous avons commencé par tester les servomoteurs à l’aide de codes fournis sur le wiki des Débrouillards. Cependant, ces codes ne fonctionnaient pas avec les versions de la carte que nous utilisions.
Ligne 56 : Ligne 177 :
  
 
===Troubleshouting===
 
===Troubleshouting===
Quelles sont difficultés, les problèmes, quelles sont les solutions, les trucs et astuces pour que ça marche ?
+
 
 +
Plusieurs difficultés ont été rencontrées au cours du projet :
 +
 
 +
Compatibilité logicielle : les codes existants ne fonctionnaient pas avec la version de la carte utilisée.
 +
Solution : adaptation du code et changement de librairie.
 +
 
 +
Choix du servomoteur : le servomoteur 360° ne permettait pas un contrôle précis de la position.
 +
Solution : remplacement par un servomoteur 180°.
 +
 
 +
Téléversement du programme : il a fallu débrancher l’ensemble du montage pour réussir à téléverser le code.
 +
Cela peut être dû au fait que l’ESP32 est tactile et potentiellement mis en sécurité par le carton, ou à un mauvais câblage. De plus, le bouton poussoir possède une polarité qui peut provoquer des dysfonctionnements s’il est mal branché.
 +
 
 +
Connexion au Wifi : la carte ne voulait pas se connecter au Wifi. Il a fallu changer de carte et de code.
 +
Trucs et astuces :
 +
 
 +
Tester le code avec un montage minimal avant l’assemblage final
 +
 
 +
Vérifier attentivement le câblage du bouton poussoir
 +
 
 +
Débrancher les éléments non indispensables lors du téléversement
 +
 
 +
===Améliorations possible===
 +
 
 +
Le Design de la maquette.
 +
 
 +
Changement de servomoteur en un servomoteur 360° qui connait sa position relative.
  
 
==Sources et documentation complémentaire==
 
==Sources et documentation complémentaire==
Ligne 71 : Ligne 217 :
 
* Traçabilité : <br>
 
* Traçabilité : <br>
 
Chаque ехtrait de cоde généré avес l'аidе de l'IA dоit êtrе accоmpagné de la sоurce, ainsi que du prоmpt eхact qui a été utilisé pоur sа créatiоn, afin d'аssurеr une évaluatiоn clаire dе vоtre prоcessus.
 
Chаque ехtrait de cоde généré avес l'аidе de l'IA dоit êtrе accоmpagné de la sоurce, ainsi que du prоmpt eхact qui a été utilisé pоur sа créatiоn, afin d'аssurеr une évaluatiоn clаire dе vоtre prоcessus.
 
 
POUR REUSSIR A TELEVERSER IL A FALLUT QU'ON DEBRANCHE LE TOUT DU AU FAIT QUE L'ESP 32 SOIT TACTILE, DONC POTENTIELLEMENT MIS EN SECURITE AVEC LE CARTON PU ALORS DU A UN MAUVAIS CABLAGE CAR LE BOUTON POUSSOIR A UNE POLARITE.
 
  
 
==Elément de présentation==
 
==Elément de présentation==

Version actuelle datée du 20 janvier 2026 à 15:51

Titre de la fiche expérience :

description (résumé)

Equipegirouette.jpg

Introduction

L’objectif de ce projet est de concevoir un dispositif simple mêlant électronique, programmation et fabrication manuelle. La girouette est commandée par un servomoteur, lui-même piloté par une carte ESP32. Ce projet nous a permis de découvrir les contraintes liées au choix du matériel, à la compatibilité des bibliothèques logicielles et au prototypage rapide.

outil et matériel

Un servomoteur 180°

Un bouton poussoir

Une carte ESP32 Wroom-32

Du carton

Du scotch

fichiers à joindre

code, ficher d'impression 3D, de découpe laser ou vinyle, ...

Mettre du code Arduino

  1  
  2 #include <WiFi.h>
  3 #include <HTTPClient.h>
  4 #include <ArduinoJson.h>
  5 #include <ESP32Servo.h>
  6 
  7 // ------------------- VOS PARAMETRES WIFI -------------------
  8 const char* ssid = "FABLAB 2.4";
  9 const char* password = "MonPetitPonant";
 10 
 11 // ------------------- VOTRE LOCALISATION (Ex: Brest) -------------------
 12 // Trouvez les vôtres sur Google Maps (clic droit sur la carte)
 13 const float latitude = 48.3904;
 14 const float longitude = -4.4861;
 15 
 16 // ------------------- PINS DE BRANCHEMENT -------------------
 17 const int servoPin = 13;  // Fil Orange du servo
 18 const int buttonPin = 12; // Un côté du bouton (l'autre au GND)
 19 
 20 // ------------------- OBJETS ET VARIABLES -------------------
 21 Servo windServo;
 22 
 23 // Timer pour ne pas bloquer l'API (Mise à jour toutes les 15 minutes)
 24 unsigned long lastTime = 0;
 25 unsigned long timerDelay = 900000; // 15 minutes en millisecondes
 26 
 27 void setup() {
 28   Serial.begin(115200);
 29   Serial.println("Test");
 30 
 31   // 1. Configuration du Servo (ESP32Servo)
 32   windServo.setPeriodHertz(50); // Standard 50hz servo
 33   windServo.attach(servoPin, 500, 2400); // Plage d'impulsion standard pour ESP32
 34   
 35   // Test de démarrage : Balayage rapide pour montrer qu'il est vivant
 36   windServo.write(0); delay(500);
 37 
 38   // 2. Configuration du Bouton
 39   pinMode(buttonPin, INPUT_PULLUP);
 40 
 41   // 3. Connexion WiFi
 42   WiFi.begin(ssid, password);
 43   Serial.print("Connexion au WiFi");
 44   while (WiFi.status() != WL_CONNECTED) {
 45     delay(500);
 46     Serial.print(".");
 47   }
 48 
 49   Serial.print("\nConnected to Wi-Fi network with IP Address: ");
 50   Serial.println(WiFi.localIP());
 51   
 52   // Première mise à jour immédiate
 53   getAndDisplayWind();
 54 }
 55 
 56 void loop() {
 57   // Vérification du timer (Automatique)
 58   if ((millis() - lastTime) > timerDelay) {
 59     getAndDisplayWind();
 60   }
 61 
 62   // Vérification du bouton (Manuel)
 63   // Si on appuie, on force la mise à jour
 64   if (digitalRead(buttonPin) == LOW) {
 65     Serial.println("Bouton pressé -> Mise à jour...");
 66     getAndDisplayWind();
 67     delay(1000); // Anti-rebond (attendre un peu)
 68   }
 69 }
 70 
 71 // Fonction principale qui fait tout le travail
 72 void getAndDisplayWind() {
 73   if(WiFi.status() == WL_CONNECTED) {
 74     HTTPClient http;
 75 
 76     // Construction de l'URL Open-Meteo
 77     String serverPath = "https://api.open-meteo.com/v1/meteofrance?latitude=" + String(latitude) + 
 78                         "&longitude=" + String(longitude) + 
 79                         "&current=wind_direction_50m";
 80     
 81     Serial.println("Requete API en cours...");
 82     http.begin(serverPath);
 83     int httpResponseCode = http.GET();
 84     
 85     if (httpResponseCode > 0) {
 86       String payload = http.getString();
 87       
 88       // Analyse du JSON (Parsing)
 89       DynamicJsonDocument doc(1024);
 90       DeserializationError error = deserializeJson(doc, payload);
 91 
 92       if (!error) {
 93         // Lecture de la direction (0 à 360°)
 94         float windDir360 = doc["current"]["wind_direction_50m"];
 95         
 96         Serial.print("Direction Vent Réelle : ");
 97         Serial.print(windDir360);
 98         Serial.println(" degrés");
 99 
100         // Conversion pour le servo (360 -> 180)
101         moveServoToWind(windDir360);
102         
103       } else {
104         Serial.print("Erreur JSON: ");
105         Serial.println(error.c_str());
106       }
107     } else {
108       Serial.print("Erreur HTTP: ");
109       Serial.println(httpResponseCode);
110     }
111     http.end();
112     lastTime = millis(); // Reset du timer
113   } else {
114     Serial.println("Erreur : WiFi coupé !");
115   }
116 }
117 
118 void moveServoToWind(float angle360) {
119   // C'est ici que la "magie" opère.
120   // La fonction map(valeur, min_in, max_in, min_out, max_out)
121   // transforme l'échelle 0-360 en 0-180.
122   
123   int servoAngle = map((long)angle360, 0, 360, 0, 180);
124 
125   // Sécurité pour ne pas forcer le moteur
126   if (servoAngle < 0) servoAngle = 0;
127   if (servoAngle > 180) servoAngle = 180;
128 
129   Serial.print("Position Servo : ");
130   Serial.println(servoAngle);
131 
132   windServo.write(servoAngle);
133 }

étapes de fabrication

indiquer autant d'étape que nécessaire, chacune illustrée par des images (photo, dessins, ...)

étape 1 : Test des servomoteurs

Nous avons commencé par tester les servomoteurs à l’aide de codes fournis sur le wiki des Débrouillards. Cependant, ces codes ne fonctionnaient pas avec les versions de la carte que nous utilisions. Cela nous a amenés à utiliser une intelligence artificielle comme aide ponctuelle : nous lui avons fourni le code du site et demandé d’utiliser une autre librairie compatible.

Au départ, nous avons utilisé un servomoteur 360°. Ce type de servomoteur ne permet pas de définir une position précise, seulement de commander une rotation ou un arrêt. Pour cette raison, nous sommes finalement passés à un servomoteur 180°, capable de connaître et atteindre une position angulaire précise.

étape 2 : Conception du prototype

Nous avons ensuite conçu le prototype physique en découpant du carton afin de créer la structure de la girouette. Les différents composants (ESP32, servomoteur, bouton poussoir) ont été positionnés et fixés à l’aide de scotch pour permettre des ajustements rapides.

étape 3 : Assemblage et tests

Une fois le prototype assemblé, nous avons procédé à des tests de fonctionnement pour vérifier la rotation du servomoteur, la réaction au bouton poussoir et la stabilité de l’ensemble.

Troubleshouting

Plusieurs difficultés ont été rencontrées au cours du projet :

Compatibilité logicielle : les codes existants ne fonctionnaient pas avec la version de la carte utilisée. Solution : adaptation du code et changement de librairie.

Choix du servomoteur : le servomoteur 360° ne permettait pas un contrôle précis de la position. Solution : remplacement par un servomoteur 180°.

Téléversement du programme : il a fallu débrancher l’ensemble du montage pour réussir à téléverser le code. Cela peut être dû au fait que l’ESP32 est tactile et potentiellement mis en sécurité par le carton, ou à un mauvais câblage. De plus, le bouton poussoir possède une polarité qui peut provoquer des dysfonctionnements s’il est mal branché.

Connexion au Wifi : la carte ne voulait pas se connecter au Wifi. Il a fallu changer de carte et de code. Trucs et astuces :

Tester le code avec un montage minimal avant l’assemblage final

Vérifier attentivement le câblage du bouton poussoir

Débrancher les éléments non indispensables lors du téléversement

Améliorations possible

Le Design de la maquette.

Changement de servomoteur en un servomoteur 360° qui connait sa position relative.

Sources et documentation complémentaire

  • Rédаctiоn et illustratiоn :

Pоur tоus vоs trаvauх, qu'ils sоient écrits оu visuels, l'utilisatiоn de l'intеlligеnce artificiеllе générativе, que сe sоit pоur le teхte оu les images, n'еst pas conseillé.

  • Prоgrammаtiоn :

En сe qui cоncernе la prоgrаmmatiоn, il est еssentiеl de ne pаs faire dе l'IA vоtrе prеmier rеcоurs. Cоncеntrеz-vоus d'abоrd sur vоtre prоpre lоgiquе, votre experience еt lеs ressоurcеs disponibles.

  • Transpаrence et dосumеntatiоn :

Si vоus utilisеz l'IA pоur déblоquer оu améliоrеr une pаrtiе de vоtre cоdе, il est cruciаl de l'indiquеr сlairеmеnt dans vоtre dосumentatiоn tеchniquе.

  • Traçabilité :

Chаque ехtrait de cоde généré avес l'аidе de l'IA dоit êtrе accоmpagné de la sоurce, ainsi que du prоmpt eхact qui a été utilisé pоur sа créatiоn, afin d'аssurеr une évaluatiоn clаire dе vоtre prоcessus.

Elément de présentation

je met ici le document de présentation de mon projet

Fichier:Vent d’Où-est.pdf

ne pas modifier sous cette ligne