ENIB 2026 : Girouette : Différence entre versions
(→étape ...) |
(→Amélioration possible) |
||
| (9 révisions intermédiaires par le même utilisateur non affichées) | |||
| Ligne 7 : | Ligne 7 : | ||
==Introduction== | ==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== | ==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> | ||
| − | # | + | #include <WiFi.h> |
| − | #include < | + | #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() { | ||
| − | // | + | 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() { | ||
| − | // | + | // 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) + | ||
| + | "¤t=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 48 : | Ligne 169 : | ||
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. | 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=== | + | ===é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. | 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. | ||
| Ligne 56 : | Ligne 177 : | ||
===Troubleshouting=== | ===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== | ==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. | ||
| − | |||
| − | |||
| − | |||
==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 :
Sommaire
description (résumé)
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 "¤t=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