Bateau Snow Girouette : Différence entre versions
| (10 révisions intermédiaires par le même utilisateur non affichées) | |||
| Ligne 3 : | Ligne 3 : | ||
éventuelle photo de l'équipe | éventuelle photo de l'équipe | ||
| − | [[ | + | [[Image:selemmmm.jpg|200px]] |
==Introduction== | ==Introduction== | ||
| + | [[Fichier:Videovideovideo.mp4|400px]] | ||
| + | nous parlons assez vite dans la vidéo car nous voulions que ça fasse moins de 100Mo | ||
| − | |||
==outil et matériel== | ==outil et matériel== | ||
Pour créer la girouette low-tech qui fonctionne grâce a un code Arduino et une carte ESP32 on a besoin d'un support, | Pour créer la girouette low-tech qui fonctionne grâce a un code Arduino et une carte ESP32 on a besoin d'un support, | ||
| Ligne 15 : | Ligne 16 : | ||
On a besoin d'un moteur pour faire tourner le bateau. | On a besoin d'un moteur pour faire tourner le bateau. | ||
On a aussi besoin d'un bouton poussoir. | On a aussi besoin d'un bouton poussoir. | ||
| − | On a également utilisé des outils pour couper le carton et le papier | + | On a également utilisé des outils pour couper le carton et le papier (cutter, ciseau). |
| − | |||
| − | |||
===Mettre du code Arduino=== | ===Mettre du code Arduino=== | ||
| − | < | + | #include <WiFi.h> |
| − | #define | + | #include <HTTPClient.h> |
| − | # | + | #include <ArduinoJson.h> |
| + | #include <Stepper.h> | ||
| + | |||
| + | /* ===================== WIFI ===================== */ | ||
| + | const char* ssid = "Formation"; | ||
| + | const char* password = "Apdgo29200!"; | ||
| + | |||
| + | /* ===================== API METEO ===================== */ | ||
| + | String url = "http://api.openweathermap.org/data/2.5/weather?q=Brest&appid=12bd029c275e6bebffca8f81eb1daa44"; | ||
| + | |||
| + | /* ===================== MOTEUR ===================== */ | ||
| + | const int stepsPerRevolution = 2048; | ||
| + | |||
| + | // EXACTEMENT comme le code qui fonctionne | ||
| + | #define IN1 14 | ||
| + | #define IN2 27 | ||
| + | #define IN3 26 | ||
| + | #define IN4 25 | ||
| + | |||
| + | Stepper myStepper(stepsPerRevolution, 14, 27, 26, 25); | ||
| + | |||
| + | float angleActuel = 0.0; | ||
| + | |||
| + | /* ===================== BOUTON + LED ===================== */ | ||
| + | #define PIN_BOUTON 4 | ||
| + | #define PIN_LED 2 | ||
| + | |||
| + | bool dernierEtatBouton = HIGH; | ||
| + | unsigned long dernierAppui = 0; | ||
| + | const unsigned long debounce = 300; | ||
| + | |||
| + | /* ===================== FONCTIONS ===================== */ | ||
| + | |||
| + | float lireDirectionVent() { | ||
| + | HTTPClient http; | ||
| + | http.begin(url); | ||
| + | http.setTimeout(5000); | ||
| + | |||
| + | int httpCode = http.GET(); | ||
| + | |||
| + | if (httpCode == 200) { | ||
| + | String payload = http.getString(); | ||
| + | DynamicJsonDocument doc(2048); | ||
| + | deserializeJson(doc, payload); | ||
| + | |||
| + | float angleVent = doc["wind"]["deg"]; | ||
| + | http.end(); | ||
| + | return angleVent; | ||
| + | } | ||
| + | |||
| + | http.end(); | ||
| + | return angleActuel; | ||
| + | } | ||
| + | |||
| + | void orienterGirouette(float angleVent) { | ||
| + | |||
| + | Serial.println("Tour complet 360°"); | ||
| + | myStepper.step(stepsPerRevolution); | ||
| + | delay(200); | ||
| + | |||
| + | float erreur = angleVent - angleActuel; | ||
| + | |||
| + | if (erreur > 180) erreur -= 360; | ||
| + | if (erreur < -180) erreur += 360; | ||
| + | |||
| + | int pas = erreur * stepsPerRevolution / 360; | ||
| + | |||
| + | Serial.print("Placement final : "); | ||
| + | Serial.print(erreur); | ||
| + | Serial.println("°"); | ||
| + | |||
| + | myStepper.step(pas); | ||
| + | |||
| + | angleActuel = angleVent; | ||
| + | } | ||
| + | |||
| + | /* ===================== SETUP ===================== */ | ||
void setup() { | void setup() { | ||
| − | // | + | Serial.begin(115200); |
| + | |||
| + | myStepper.setSpeed(5); // NE PAS AUGMENTER | ||
| + | |||
| + | pinMode(PIN_BOUTON, INPUT_PULLUP); | ||
| + | pinMode(PIN_LED, OUTPUT); | ||
| + | digitalWrite(PIN_LED, LOW); | ||
| + | |||
| + | WiFi.begin(ssid, password); | ||
| + | Serial.print("Connexion WiFi"); | ||
| + | |||
| + | while (WiFi.status() != WL_CONNECTED) { | ||
| + | delay(500); | ||
| + | Serial.print("."); | ||
| + | } | ||
| + | Serial.println("\nWiFi connecté !"); | ||
} | } | ||
| + | |||
| + | /* ===================== LOOP ===================== */ | ||
void loop() { | void loop() { | ||
| − | // | + | bool etatBouton = digitalRead(PIN_BOUTON); |
| + | unsigned long maintenant = millis(); | ||
| + | |||
| + | digitalWrite(PIN_LED, etatBouton == LOW ? HIGH : LOW); | ||
| + | |||
| + | if (dernierEtatBouton == HIGH && | ||
| + | etatBouton == LOW && | ||
| + | maintenant - dernierAppui > debounce) { | ||
| + | |||
| + | dernierAppui = maintenant; | ||
| + | |||
| + | Serial.println("\nBouton appuyé !"); | ||
| + | float angleVent = lireDirectionVent(); | ||
| + | |||
| + | Serial.print("Angle du vent : "); | ||
| + | Serial.print(angleVent); | ||
| + | Serial.println("°"); | ||
| + | |||
| + | orienterGirouette(angleVent); | ||
| + | Serial.println("Terminé"); | ||
| + | } | ||
| + | |||
| + | dernierEtatBouton = etatBouton; | ||
| + | } | ||
| + | code qui tourne : | ||
| + | /* | ||
| + | Example sketch to control a 28BYJ-48 stepper motor | ||
| + | with ULN2003 driver board and Arduino UNO. | ||
| + | More info: https://www.makerguides.com | ||
| + | */ | ||
| + | |||
| + | // Include the Arduino Stepper.h library: | ||
| + | #include "Stepper.h" | ||
| + | |||
| + | // Define number of steps per rotation: | ||
| + | const int stepsPerRevolution = 2048; | ||
| + | |||
| + | // Wiring: | ||
| + | // Pin 8 to IN1 on the ULN2003 driver | ||
| + | // Pin 9 to IN2 on the ULN2003 driver | ||
| + | // Pin 10 to IN3 on the ULN2003 driver | ||
| + | // Pin 11 to IN4 on the ULN2003 driver | ||
| + | |||
| + | #define IN1 14 | ||
| + | #define IN2 27 | ||
| + | #define IN3 26 | ||
| + | #define IN4 25 | ||
| + | |||
| + | // Create stepper object called 'myStepper', note the pin order: | ||
| + | Stepper myStepper = Stepper(stepsPerRevolution, 14, 27, 26, 25); | ||
| + | |||
| + | void setup() { | ||
| + | // Set the speed to 5 rpm: | ||
| + | myStepper.setSpeed(5); | ||
| + | |||
| + | // Begin Serial communication at a baud rate of 9600: | ||
| + | Serial.begin(9600); | ||
} | } | ||
| − | + | void loop() { | |
| + | // Step one revolution in one direction: | ||
| + | Serial.println("clockwise"); | ||
| + | myStepper.step(stepsPerRevolution); | ||
| + | delay(500); | ||
| + | |||
| + | // Step one revolution in the other direction: | ||
| + | Serial.println("counterclockwise"); | ||
| + | myStepper.step(-stepsPerRevolution); | ||
| + | delay(500); | ||
| + | |||
| + | } | ||
==étapes de fabrication== | ==étapes de fabrication== | ||
=== 1ère étape de fabrication === | === 1ère étape de fabrication === | ||
| Ligne 65 : | Ligne 224 : | ||
Une fois ce concept posé et le projet de code clair pour nous on passe a la conception concrète du code. | Une fois ce concept posé et le projet de code clair pour nous on passe a la conception concrète du code. | ||
| + | [[Image:Thinkingahhb.jpeg|250px]] | ||
===étape 2: Conception du code=== | ===étape 2: Conception du code=== | ||
| + | [[Image:Codingahhb.jpeg|250px]] | ||
| − | + | ===étape 3: Tests du code avec le moteur=== | |
| − | ==étape 3: Tests du code avec le moteur== | ||
Avant d'assembler la carte et le moteur avec notre girouette il faut vérifier que le code fasse bien ce qu'on lui demande de faire. | Avant d'assembler la carte et le moteur avec notre girouette il faut vérifier que le code fasse bien ce qu'on lui demande de faire. | ||
La vérification passe par une simple phase de tests durant lesquels on vérifie que le moteur tourne bien comme on veut une fois le lancement du code, aussi simple que ça. | La vérification passe par une simple phase de tests durant lesquels on vérifie que le moteur tourne bien comme on veut une fois le lancement du code, aussi simple que ça. | ||
| Ligne 82 : | Ligne 242 : | ||
Les principales difficultés rencontrées sont d'abord d'ordre créatif, en effet il faut avoir la bonne idée, et surtout comment représenter de manière plutôt ludique notre idée. On passe d'abord par une phase de brainstorming entre les personnes du groupe et on réfléchis a la meilleure solution, dans notre cas c'est | Les principales difficultés rencontrées sont d'abord d'ordre créatif, en effet il faut avoir la bonne idée, et surtout comment représenter de manière plutôt ludique notre idée. On passe d'abord par une phase de brainstorming entre les personnes du groupe et on réfléchis a la meilleure solution, dans notre cas c'est | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
==ne pas modifier sous cette ligne== | ==ne pas modifier sous cette ligne== | ||
[[Catégorie:Enib2026]] | [[Catégorie:Enib2026]] | ||
Version actuelle datée du 22 janvier 2026 à 16:13
Titre de la fiche expérience :
Sommaire
- 1 description (résumé)
- 2 Introduction
- 3 outil et matériel
- 4 étapes de fabrication
- 4.1 1ère étape de fabrication
- 4.2 2ème étape de fabrication
- 4.3 3ème étape de fabrication
- 4.4 4ème étape de fabrication
- 4.5 étape 1: On pose le problème et structure du code
- 4.6 étape 2: Conception du code
- 4.7 étape 3: Tests du code avec le moteur
- 4.8 étape 4: Assemblage de la girouette avec la carte et phase de Tests
- 4.9 Troubleshouting
- 5 ne pas modifier sous cette ligne
description (résumé)
éventuelle photo de l'équipe
Introduction
nous parlons assez vite dans la vidéo car nous voulions que ça fasse moins de 100Mo
outil et matériel
Pour créer la girouette low-tech qui fonctionne grâce a un code Arduino et une carte ESP32 on a besoin d'un support, on utilise du carton pour créer la base (la coque en quelque sorte de notre girouette). On utilise une impression pour rendre le support plus lisible a l'image d'une boussole, le petit bateau qui indique la direction du vent est lui aussi conçu avec du carton et du papier pour faire les voiles. On a également besoin de colle pour assembler. On a besoin d'un moteur pour faire tourner le bateau. On a aussi besoin d'un bouton poussoir. On a également utilisé des outils pour couper le carton et le papier (cutter, ciseau).
Mettre du code Arduino
- include <WiFi.h>
- include <HTTPClient.h>
- include <ArduinoJson.h>
- include <Stepper.h>
/* ===================== WIFI ===================== */ const char* ssid = "Formation"; const char* password = "Apdgo29200!";
/* ===================== API METEO ===================== */ String url = "http://api.openweathermap.org/data/2.5/weather?q=Brest&appid=12bd029c275e6bebffca8f81eb1daa44";
/* ===================== MOTEUR ===================== */ const int stepsPerRevolution = 2048;
// EXACTEMENT comme le code qui fonctionne
- define IN1 14
- define IN2 27
- define IN3 26
- define IN4 25
Stepper myStepper(stepsPerRevolution, 14, 27, 26, 25);
float angleActuel = 0.0;
/* ===================== BOUTON + LED ===================== */
- define PIN_BOUTON 4
- define PIN_LED 2
bool dernierEtatBouton = HIGH; unsigned long dernierAppui = 0; const unsigned long debounce = 300;
/* ===================== FONCTIONS ===================== */
float lireDirectionVent() {
HTTPClient http; http.begin(url); http.setTimeout(5000);
int httpCode = http.GET();
if (httpCode == 200) {
String payload = http.getString();
DynamicJsonDocument doc(2048);
deserializeJson(doc, payload);
float angleVent = doc["wind"]["deg"]; http.end(); return angleVent; }
http.end(); return angleActuel;
}
void orienterGirouette(float angleVent) {
Serial.println("Tour complet 360°");
myStepper.step(stepsPerRevolution);
delay(200);
float erreur = angleVent - angleActuel;
if (erreur > 180) erreur -= 360; if (erreur < -180) erreur += 360;
int pas = erreur * stepsPerRevolution / 360;
Serial.print("Placement final : ");
Serial.print(erreur);
Serial.println("°");
myStepper.step(pas);
angleActuel = angleVent;
}
/* ===================== SETUP ===================== */
void setup() {
Serial.begin(115200);
myStepper.setSpeed(5); // NE PAS AUGMENTER
pinMode(PIN_BOUTON, INPUT_PULLUP); pinMode(PIN_LED, OUTPUT); digitalWrite(PIN_LED, LOW);
WiFi.begin(ssid, password);
Serial.print("Connexion WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connecté !");
}
/* ===================== LOOP ===================== */
void loop() {
bool etatBouton = digitalRead(PIN_BOUTON); unsigned long maintenant = millis();
digitalWrite(PIN_LED, etatBouton == LOW ? HIGH : LOW);
if (dernierEtatBouton == HIGH &&
etatBouton == LOW &&
maintenant - dernierAppui > debounce) {
dernierAppui = maintenant;
Serial.println("\nBouton appuyé !");
float angleVent = lireDirectionVent();
Serial.print("Angle du vent : ");
Serial.print(angleVent);
Serial.println("°");
orienterGirouette(angleVent);
Serial.println("Terminé");
}
dernierEtatBouton = etatBouton;
} code qui tourne : /*
Example sketch to control a 28BYJ-48 stepper motor with ULN2003 driver board and Arduino UNO. More info: https://www.makerguides.com
- /
// Include the Arduino Stepper.h library:
- include "Stepper.h"
// Define number of steps per rotation: const int stepsPerRevolution = 2048;
// Wiring: // Pin 8 to IN1 on the ULN2003 driver // Pin 9 to IN2 on the ULN2003 driver // Pin 10 to IN3 on the ULN2003 driver // Pin 11 to IN4 on the ULN2003 driver
- define IN1 14
- define IN2 27
- define IN3 26
- define IN4 25
// Create stepper object called 'myStepper', note the pin order:
Stepper myStepper = Stepper(stepsPerRevolution, 14, 27, 26, 25);
void setup() {
// Set the speed to 5 rpm: myStepper.setSpeed(5); // Begin Serial communication at a baud rate of 9600: Serial.begin(9600);
}
void loop() {
// Step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
delay(500);
// Step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
delay(500);
}
étapes de fabrication
1ère étape de fabrication
Création de la base de la girouette:
2ème étape de fabrication
Création des repères cardinaux de la boussole:
3ème étape de fabrication
Création du bateau qui fait office de girouette:
4ème étape de fabrication
Impression pour le coté esthétique et mise en place du bouton a l'intérieur de la base:
![]()
étape 1: On pose le problème et structure du code
En parallèle de la conception de la maquette on étudie la conception du code, le code a pour but grâce a une API(qui recueille la direction du vent a un instant T a Brest) qui est en relation avec la carte ESP32.
Le code analyse les données et fait tourner le moteur en fonction de la direction du vent pour que le bateau (qui est relié a l'axe de rotation du moteur) indique la bonne cardinalité selon la direction du vent.
Une fois ce concept posé et le projet de code clair pour nous on passe a la conception concrète du code.
étape 2: Conception du code
étape 3: Tests du code avec le moteur
Avant d'assembler la carte et le moteur avec notre girouette il faut vérifier que le code fasse bien ce qu'on lui demande de faire. La vérification passe par une simple phase de tests durant lesquels on vérifie que le moteur tourne bien comme on veut une fois le lancement du code, aussi simple que ça.
étape 4: Assemblage de la girouette avec la carte et phase de Tests
On assemble la carte et le moteur avec la maquette et on fait des Tests pour vérifier la rotation du moteur. Selon les résultats obtenus et la véracité des informations que la maquette nous donne(direction du vent) on compare avec les informations voulues. On effectue des ajustements pour que la direction indiquée par la proue du bateau soit juste.
Troubleshouting
Les principales difficultés rencontrées sont d'abord d'ordre créatif, en effet il faut avoir la bonne idée, et surtout comment représenter de manière plutôt ludique notre idée. On passe d'abord par une phase de brainstorming entre les personnes du groupe et on réfléchis a la meilleure solution, dans notre cas c'est