ENIB 2025 : LaGrueQuiDub : Différence entre versions

De Les Fabriques du Ponant
Aller à : navigation, rechercher
(description (résumé))
(Final)
 
(19 révisions intermédiaires par 3 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
 
Titre de la fiche expérience :
 
Titre de la fiche expérience :
==description (résumé)==
+
==Introduction/Description==
éventuelle photo de l'équipe
+
Notre but premier était de détourner le PETIT BOT pour lui donner une nouvelle fonction. Une fois cette idée en tête nous avons décidé de faire une grue à partir des éléments fournis avec le PETIT BOT.
 +
La grue sera sur 2 axes (treuil de levage et rotation de la grue) et donc commandée par 2 servomoteurs. Elle sera pilotée avec une application web sur un serveur web qui sera sur la carte D1 mini.
  
[[Fichier:LaGrueQuiDobe1.jpg|400px]]
+
==Matériel==
 +
Carton, colle chaude, ficelle (environ 2m), contrepoids, pics à brochettes en bois (une dizaine), rouleaux de scotch vide (3), servomoteurs (2), carte d1 mini, embase en polystyrène, disque en plastique
  
==Introduction==
+
==Outils==
 +
Cutter, pistolet à colle, pince coupante, ordinateur et du temps …
  
éventuelle vidéo
+
==Fichiers à joindre==
==outil et matériel==
+
code, fichier d'impression 3D, de découpe laser ou vinyle, ...
  
==fichiers à joindre==
+
==Étapes de fabrication==
code, ficher d'impression 3D, de découpe laser ou vinyle, ...
+
 
===Mettre du code Arduino===
+
===étape 1===
 +
Trouver la forme adéquate pour la grue.
 +
 
 +
[[Fichier:Grue_etape1.jpg|200px]]
 +
 
 +
===étape 2===
 +
Assembler les 2 parties de la grue et rajouter les petits bouts de pics à brochette pour consolider le tout.
 +
 
 +
[[Fichier:Grue_etape2.jpg|200px]]
 +
 
 +
===étape 3===
 +
Y ajouter le système de poulie pour faire passer la ficelle ainsi que le système de fixation du treuil.
 +
 
 +
[[Fichier:Grue_etape31.jpg|200px]][[Fichier:Grue_etape32.jpg|200px]]
 +
 
 +
===étape 4===
 +
Attacher les servomoteurs au treuil et à l’embase à l’aide de la colle chaude. Mettre la carte ainsi que les composants dans la base de la grue.
 +
 
 +
[[Fichier:Grue_etape4.jpg|200px]]
 +
 
 +
===étape 5===
 +
Couvrir les côtés de la grue d’une couche de carton pour embellir la chose et veiller à laisser accessible la batterie.
 +
 
 +
===Final===
 +
La construction de la grue est finie et doit ressembler à ça :
 +
 
 +
[[Fichier:Grue_final.jpg|200px]]
 +
==Étapes du code==
 +
 
 +
===étape 1===
 +
Créer un point d’accès wifi sur la carte ESP8266, avec un nom de point d’accès et un mot de passe.
 +
 
 +
[[Fichier:LaGrueQuiDobe1.jpg|200px]]
 +
 
 +
===étape 2===
 +
Coder l'implémentation de la page HTML avec deux curseurs et un bouton pour valider (envoyer les nouvelles valeurs de curseurs). Se connecter au réseau de notre carte et accéder à la page 192.168.1.4 pour vérifier que notre page HTML fonctionne.
 +
 
 +
===étape 3===
 +
Récupérer les valeurs des curseurs dans le code qui se trouvent sur le chemin 192.168.1.4/control, on fait cela avec une requête HTTP GET suivi d’un argument pour choisir ce que l’on veut récupérer. Exemple : server.arg("speed1") pour récupérer  la valeur du premier curseur.
 +
 
 +
===étape 3===
 +
 
 +
Une fois que l’on a les valeurs, implémenter le code qui fera tourner nos servomoteurs en fonction de nos besoins et des valeurs des curseurs.
 +
Exemples de besoins:
 +
Ralentir la rotation de la grue
 +
DeadZone du curseur vitesse du treuil
 +
 
 +
===Final===
 +
 
 +
Nous pouvons contrôler la rotation des servos moteurs avec le site internet, depuis n’importe quel navigateur web.
 +
 
 +
[[Fichier:Grue_interface.jpg|500px]]
 +
 
 +
==Sources et documentation complémentaire==
 +
[https://www.wikidebrouillard.org/wiki/Item:Servomoteur Fiche servomoteur de wikidebrouilard]
 +
 
 +
==Elément de présentation==
 +
 
 +
[[Fichier:Grue_comm.png|500px]]
 +
 
 +
==CodeV1 contrôle servo avec graphique 2axes==
 
<syntaxhighlight lang="Arduino" line>  
 
<syntaxhighlight lang="Arduino" line>  
#define PIN 9
+
#include <ESP8266WiFi.h>
#include <Arduino_GFX_Library.h>
+
#include <ESP8266WebServer.h>
 +
#include <Servo.h>
 +
 
 +
const int pwmPin = 5; //(D1 sur l'ESP8266)
 +
Servo servoG;
 +
Servo servoD;
 +
 
 +
// Crédential réseau
 +
const char* ssid = "*********";
 +
const char* password = "**********";
 +
 
 +
// Lancer le serverWeb
 +
ESP8266WebServer server(80);
 +
 
 +
// Coordonnées sliders et mémoire de détection de changement
 +
float xCoord = 0;
 +
float yCoord = 0;
 +
float lastXCoord = -1;
 +
float lastYCoord = -1;
 +
 
 +
unsigned long previousMillis = 0;
 +
const long interval = 1000;
 +
const float deadZone = 50.0;
  
 
void setup() {
 
void setup() {
   // put your setup code here, to run once:
+
   Serial.begin(115200);
  
 +
  initServos();
 +
 +
  connectToWiFi();
 +
  server.on("/", handleRoot);
 +
  server.on("/coords", handleCoords);
 +
  server.begin();
 +
  Serial.println("Serveur démarré");
 
}
 
}
  
 
void loop() {
 
void loop() {
   // put your main code here, to run repeatedly:
+
   unsigned long currentMillis = millis();
 +
  if (currentMillis - previousMillis >= interval) {
 +
    previousMillis = currentMillis;
 +
 
 +
    if (abs(xCoord - lastXCoord) > deadZone || abs(yCoord - lastYCoord) > deadZone) {
 +
      Serial.print("Coordonnées X: ");
 +
      Serial.print(xCoord);
 +
      Serial.print(", Y: ");
 +
      Serial.println(yCoord);
 +
 
 +
      createServoMovement(xCoord, yCoord);
 +
 
 +
      lastXCoord = xCoord;
 +
      lastYCoord = yCoord;
 +
    }
 +
  }
 +
  server.handleClient();
 +
}
 +
 
 +
void initServos() {
 +
  servoG.attach(5); // (D1 sur l'ESP8266)
 +
  servoD.attach(4); // (D2 sur l'ESP8266)
 +
}
 +
 
 +
void connectToWiFi() {
 +
  Serial.println("Connexion au Wi-Fi...");
 +
  WiFi.begin(ssid, password);
 +
  while (WiFi.status() != WL_CONNECTED) {
 +
    delay(500);
 +
    Serial.print(".");
 +
  }
 +
  Serial.println("\nConnecté !");
 +
  Serial.print("Adresse IP : ");
 +
  Serial.println(WiFi.localIP());
 +
}
  
 +
void handleRoot() {
 +
  String html = generateHTML();
 +
  server.send(200, "text/html", html);
 
}
 
}
  
</syntaxhighlight>
+
String generateHTML() {
 +
  return R"rawliteral(
 +
    <!DOCTYPE html>
 +
    <html>
 +
    <head>
 +
      <title>ESP8266 Interactive Page</title>
 +
      <style>
 +
        body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #f3f3f3; }
 +
        canvas { border: 1px solid black; }
 +
      </style>
 +
    </head>
 +
    <body>
 +
      <canvas id="canvas" width="500" height="500"></canvas>
 +
      <script>
 +
        const canvas = document.getElementById('canvas');
 +
        const ctx = canvas.getContext('2d');
 +
        canvas.addEventListener('mousemove', (event) => {
 +
          const rect = canvas.getBoundingClientRect();
 +
          const x = event.clientX - rect.left;
 +
          const y = event.clientY - rect.top;
 +
          ctx.clearRect(0, 0, canvas.width, canvas.height);
 +
          ctx.fillStyle = "blue";
 +
          ctx.beginPath();
 +
          ctx.arc(x, y, 5, 0, 2 * Math.PI);
 +
          ctx.fill();
 +
          // Envoyer les coordonnées au serveur
 +
          fetch(`/coords?x=${x}&y=${y}`)
 +
            .then(response => response.text())
 +
            .then(data => console.log(data))
 +
            .catch(error => console.error('Erreur:', error));
 +
        });
 +
      </script>
 +
    </body>
 +
    </html>
 +
  )rawliteral";
 +
}
  
==étapes de fabrication==
+
void handleCoords() {
indiquer autant d'étape que nécessaire, chacune illustrée par des images (photo, dessins, ...)
+
  xCoord = server.arg("x").toFloat();
 +
  yCoord = server.arg("y").toFloat();
  
===étape 1===
+
  server.send(200, "text/plain", "Coordonnées reçues et servos mis à jour !");
===étape 2===
+
}
===étape ...===
+
 
===Troubleshouting===
+
void createServoMovement(float xCoord, float yCoord) {
Quelles sont difficultés, les problèmes, quelles sont les solutions, les trucs et astuces pour que ça marche ?
+
  // Mapper xCoord de [0, 500] à [0, 180] pour le servo gauche
 +
  int angleG = map(xCoord, 0, 500, 0, 180);
 +
  servoG.write(angleG);
  
==Sources et documentation complémentaire==
+
  // Mapper yCoord de [0, 500] à [0, 180] pour le servo droit
 +
  int angleD = map(yCoord, 0, 500, 0, 180);
 +
  servoD.write(angleD);
  
==Elémlent de présentation==
+
  Serial.print("Servo gauche : ");
je met ici le document de présentation de mon projet
+
  Serial.print(angleG);
 +
  Serial.print(" degrés, Servo droit : ");
 +
  Serial.print(angleD);
 +
  Serial.println(" degrés");
 +
}
 +
</syntaxhighlight>
  
 
==ne pas modifier sous cette ligne==
 
==ne pas modifier sous cette ligne==
Ligne 47 : Ligne 221 :
  
 
[[Catégorie:Enib2025]]
 
[[Catégorie:Enib2025]]
 +
 +
[[Catégorie:Enib2025-AB]]

Version actuelle datée du 21 janvier 2025 à 16:27

Titre de la fiche expérience :

Introduction/Description

Notre but premier était de détourner le PETIT BOT pour lui donner une nouvelle fonction. Une fois cette idée en tête nous avons décidé de faire une grue à partir des éléments fournis avec le PETIT BOT. La grue sera sur 2 axes (treuil de levage et rotation de la grue) et donc commandée par 2 servomoteurs. Elle sera pilotée avec une application web sur un serveur web qui sera sur la carte D1 mini.

Matériel

Carton, colle chaude, ficelle (environ 2m), contrepoids, pics à brochettes en bois (une dizaine), rouleaux de scotch vide (3), servomoteurs (2), carte d1 mini, embase en polystyrène, disque en plastique

Outils

Cutter, pistolet à colle, pince coupante, ordinateur et du temps …

Fichiers à joindre

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

Étapes de fabrication

étape 1

Trouver la forme adéquate pour la grue.

Grue etape1.jpg

étape 2

Assembler les 2 parties de la grue et rajouter les petits bouts de pics à brochette pour consolider le tout.

Grue etape2.jpg

étape 3

Y ajouter le système de poulie pour faire passer la ficelle ainsi que le système de fixation du treuil.

Grue etape31.jpgGrue etape32.jpg

étape 4

Attacher les servomoteurs au treuil et à l’embase à l’aide de la colle chaude. Mettre la carte ainsi que les composants dans la base de la grue.

Grue etape4.jpg

étape 5

Couvrir les côtés de la grue d’une couche de carton pour embellir la chose et veiller à laisser accessible la batterie.

Final

La construction de la grue est finie et doit ressembler à ça :

Grue final.jpg

Étapes du code

étape 1

Créer un point d’accès wifi sur la carte ESP8266, avec un nom de point d’accès et un mot de passe.

LaGrueQuiDobe1.jpg

étape 2

Coder l'implémentation de la page HTML avec deux curseurs et un bouton pour valider (envoyer les nouvelles valeurs de curseurs). Se connecter au réseau de notre carte et accéder à la page 192.168.1.4 pour vérifier que notre page HTML fonctionne.

étape 3

Récupérer les valeurs des curseurs dans le code qui se trouvent sur le chemin 192.168.1.4/control, on fait cela avec une requête HTTP GET suivi d’un argument pour choisir ce que l’on veut récupérer. Exemple : server.arg("speed1") pour récupérer la valeur du premier curseur.

étape 3

Une fois que l’on a les valeurs, implémenter le code qui fera tourner nos servomoteurs en fonction de nos besoins et des valeurs des curseurs. Exemples de besoins: Ralentir la rotation de la grue DeadZone du curseur vitesse du treuil

Final

Nous pouvons contrôler la rotation des servos moteurs avec le site internet, depuis n’importe quel navigateur web.

Grue interface.jpg

Sources et documentation complémentaire

Fiche servomoteur de wikidebrouilard

Elément de présentation

Grue comm.png

CodeV1 contrôle servo avec graphique 2axes

  1  
  2 #include <ESP8266WiFi.h>
  3 #include <ESP8266WebServer.h>
  4 #include <Servo.h>
  5 
  6 const int pwmPin = 5; //(D1 sur l'ESP8266)
  7 Servo servoG;
  8 Servo servoD;
  9 
 10 // Crédential réseau
 11 const char* ssid = "*********";
 12 const char* password = "**********";
 13 
 14 // Lancer le serverWeb
 15 ESP8266WebServer server(80);
 16 
 17 // Coordonnées sliders et mémoire de détection de changement
 18 float xCoord = 0;
 19 float yCoord = 0;
 20 float lastXCoord = -1;
 21 float lastYCoord = -1;
 22 
 23 unsigned long previousMillis = 0;
 24 const long interval = 1000;
 25 const float deadZone = 50.0; 
 26 
 27 void setup() {
 28   Serial.begin(115200);
 29 
 30   initServos();
 31 
 32   connectToWiFi();
 33   server.on("/", handleRoot);
 34   server.on("/coords", handleCoords);
 35   server.begin();
 36   Serial.println("Serveur démarré");
 37 }
 38 
 39 void loop() {
 40   unsigned long currentMillis = millis();
 41   if (currentMillis - previousMillis >= interval) {
 42     previousMillis = currentMillis;
 43 
 44     if (abs(xCoord - lastXCoord) > deadZone || abs(yCoord - lastYCoord) > deadZone) {
 45       Serial.print("Coordonnées X: ");
 46       Serial.print(xCoord);
 47       Serial.print(", Y: ");
 48       Serial.println(yCoord);
 49 
 50       createServoMovement(xCoord, yCoord);
 51 
 52       lastXCoord = xCoord;
 53       lastYCoord = yCoord;
 54     }
 55   }
 56   server.handleClient();
 57 }
 58 
 59 void initServos() {
 60   servoG.attach(5); // (D1 sur l'ESP8266)
 61   servoD.attach(4); // (D2 sur l'ESP8266)
 62 }
 63 
 64 void connectToWiFi() {
 65   Serial.println("Connexion au Wi-Fi...");
 66   WiFi.begin(ssid, password);
 67   while (WiFi.status() != WL_CONNECTED) {
 68     delay(500);
 69     Serial.print(".");
 70   }
 71   Serial.println("\nConnecté !");
 72   Serial.print("Adresse IP : ");
 73   Serial.println(WiFi.localIP());
 74 }
 75 
 76 void handleRoot() {
 77   String html = generateHTML();
 78   server.send(200, "text/html", html);
 79 }
 80 
 81 String generateHTML() {
 82   return R"rawliteral(
 83     <!DOCTYPE html>
 84     <html>
 85     <head>
 86       <title>ESP8266 Interactive Page</title>
 87       <style>
 88         body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #f3f3f3; }
 89         canvas { border: 1px solid black; }
 90       </style>
 91     </head>
 92     <body>
 93       <canvas id="canvas" width="500" height="500"></canvas>
 94       <script>
 95         const canvas = document.getElementById('canvas');
 96         const ctx = canvas.getContext('2d');
 97         canvas.addEventListener('mousemove', (event) => {
 98           const rect = canvas.getBoundingClientRect();
 99           const x = event.clientX - rect.left;
100           const y = event.clientY - rect.top;
101           ctx.clearRect(0, 0, canvas.width, canvas.height);
102           ctx.fillStyle = "blue";
103           ctx.beginPath();
104           ctx.arc(x, y, 5, 0, 2 * Math.PI);
105           ctx.fill();
106           // Envoyer les coordonnées au serveur
107           fetch(`/coords?x=${x}&y=${y}`)
108             .then(response => response.text())
109             .then(data => console.log(data))
110             .catch(error => console.error('Erreur:', error));
111         });
112       </script>
113     </body>
114     </html>
115   )rawliteral";
116 }
117 
118 void handleCoords() {
119   xCoord = server.arg("x").toFloat();
120   yCoord = server.arg("y").toFloat();
121 
122   server.send(200, "text/plain", "Coordonnées reçues et servos mis à jour !");
123 }
124 
125 void createServoMovement(float xCoord, float yCoord) {
126   // Mapper xCoord de [0, 500] à [0, 180] pour le servo gauche
127   int angleG = map(xCoord, 0, 500, 0, 180);
128   servoG.write(angleG);
129 
130   // Mapper yCoord de [0, 500] à [0, 180] pour le servo droit
131   int angleD = map(yCoord, 0, 500, 0, 180);
132   servoD.write(angleD);
133 
134   Serial.print("Servo gauche : ");
135   Serial.print(angleG);
136   Serial.print(" degrés, Servo droit : ");
137   Serial.print(angleD);
138   Serial.println(" degrés");
139 }

ne pas modifier sous cette ligne