|
|
(40 révisions intermédiaires par 2 utilisateurs non affichées) |
Ligne 1 : |
Ligne 1 : |
− | | + | #REDIRECT [[:Catégorie:RobotDuLAB]] |
− | == [[Présentation du projet]] ==
| + | |
− | <br>
| + | |
− | '''Un robot pour apprendre à programmer en classe''' <br>
| + | |
− | <br>
| + | |
− | * Utilisable en écoles primaires, collèges et lycées <br>
| + | |
− | * Toutes les pièces mécaniques sont imprimables (impression 3D – fichiers .stl fournis) <br>
| + | |
− | * Partie électronique basée sur une carte de prototypage « arduino » <br>
| + | |
− | * Libre (copiable, modifiable) et évolutif (de nombreuses options possibles) <br>
| + | |
− | <br>
| + | |
− | RoboduLAB, permet une approche ludique de l’apprentissage du code à l’école primaire, des plots au format lego permettent de personnaliser le robot.<br>
| + | |
− | | + | |
− | [[Fichier:RoboduLAB_avec_lego.jpg|sans_cadre|RoboduLAB avec paques lego et ring 16 LED|600px]]
| + | |
− | <br>
| + | |
− | En collège et en lycée RoboduLAB est un support de thème très riche pour le travail en équipes projets : conception, réalisation, expérimentation. <br>
| + | |
− | <br>
| + | |
− | La programmation se fait par assemblage de blocs (type scratch). Le programme se télécharge directement dans le robot depuis le PC ou la tablette en WIFI.<br>
| + | |
− | <br>
| + | |
− | [[Fichier:S4a.JPG|sans_cadre|Programmation par blocs|600px]]
| + | |
− | <br>
| + | |
− | | + | |
− | == [[Constitution du robot]] ==
| + | |
− | RoboduLAB est constiué d'un chassis, de deux roues montées sur des servomoteurs qui sont commandés par une carte de prototypage arduino.
| + | |
− | Il sera possible de rajouter différentes options au modèle de base :
| + | |
− | * suivi de ligne,
| + | |
− | * module WIFI,
| + | |
− | * détection des vides,
| + | |
− | * sons (MP3),
| + | |
− | * …
| + | |
− | | + | |
− | === [[Chassis]] ===
| + | |
− | | + | |
− | Le chassis est constitué d'un ensemble de pièces imprimables par une une imprimante 3D et une roulette à bille.
| + | |
− | | + | |
− | === [[Électronique]] ===
| + | |
− | | + | |
− | La partie électronique du robot comporte à minima :
| + | |
− | * une carte arduino (UNO),
| + | |
− | * deux servomoteurs à rotation continue,
| + | |
− | * un capteur à ultrasons,
| + | |
− | * une LED RGB (ou un NeoPixel Ring),
| + | |
− | * un boîtier pour les piles (6 piles AA)
| + | |
− | * un interrupteur à glissière.
| + | |
− | | + | |
− | === [[Programmes]] ===
| + | |
− | | + | |
− | Le programme nécessaire pour le fonctionnement du robot peut être :<br>
| + | |
− | - soit écrit directement en C++ et téléchargé dans la carte arduino,<br>
| + | |
− | - soit représenté par des blocs graphiques (type scratch). Il sera alors possible de produire automatiquement le code en C++ qui sera téléchargé dans le robot.
| + | |
− | | + | |
− | ==== [[Code arduino : démonstration du fonctionnement du robot en mode autonome]] ====
| + | |
− | ===== Programme sans NeoPixel Ring =====
| + | |
− | | + | |
− | Voici le programme qu'il faut éditer dans l'IDE Arduino, puis compiler et charger dans la carte Arduino
| + | |
− | <br />
| + | |
− | | + | |
− | <syntaxhighlight lang="cpp" enclose="div">
| + | |
− | /*
| + | |
− | Ce programme de démonstration permet de faire fonctionner le robot d'une manière autonome
| + | |
− | */
| + | |
− | | + | |
− | #include <Servo.h> // librairie pour servomoteur | + | |
− | | + | |
− | #define broche_servoA 3 // broche servo A
| + | |
− | #define broche_servoB 5 // broche servo B
| + | |
− | #define trig 2 // broche trig du capteur US HC-SR04
| + | |
− | #define echo 4 // broche echo du capteur US HC-SR04
| + | |
− | | + | |
− | const int MAX_SENS2=1000; // largeur impulsion pour position ANGLE_MIN degrés du servomoteur
| + | |
− | const int ARRET=1490; // largeur impulsion pour position ANGLE_MEDIANE degrés du servomoteur
| + | |
− | const int MAX_SENS1=2000; // largeur impulsion pour position ANGLE_MAX degrés du servomoteur
| + | |
− | | + | |
− | // classiquement : centrage sur 1500 - maxi sens 1 = 1000 et maxi sens 2 = 2000
| + | |
− | | + | |
− | // --- Déclaration des constantes des broches E/S numériques ---
| + | |
− | | + | |
− | long lecture_echo = 0; // variable sur 4 octets mesure de distance
| + | |
− | long cm = 0; // variable sur 4 octets pour la conversion en cm
| + | |
− | | + | |
− | //--- Création objet servomoteur
| + | |
− | Servo servoA; // crée un objet servo pour contrôler le servomoteur A (en dessous du swich ON/OFF
| + | |
− | Servo servoB; // crée un objet servo pour contrôler le servomoteur B (à gauche du servo A)
| + | |
− | | + | |
− | // La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme
| + | |
− | | + | |
− | void setup() { // debut de la fonction setup()
| + | |
− | | + | |
− | // --- ici instructions à exécuter 1 seule fois au démarrage du programme ---
| + | |
− | | + | |
− | pinMode (broche_servoA,OUTPUT); // Broche broche_servo configurée en sortie
| + | |
− | pinMode (broche_servoB,OUTPUT); // Broche broche_servo configurée en sortie
| + | |
− | pinMode (trig,OUTPUT); // broche broche trig configurée en sortie
| + | |
− | digitalWrite(trig, LOW); // met un niveau logique , LOW (BAS) sur la broche trig
| + | |
− | pinMode(echo, INPUT); // la broche echo est initialisée en entree
| + | |
− | Serial.begin(115200); // initialisation de la liaison série à 115200 bauds
| + | |
− | delay (2000); // on attend 2s
| + | |
− | } // fin de la fonction setup()
| + | |
− | // ********************************************************************************
| + | |
− | | + | |
− | // la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension
| + | |
− | | + | |
− | void loop(){ // debut de la fonction loop()
| + | |
− | | + | |
− | Avant();
| + | |
− | digitalWrite(trig, HIGH); // met un niveau logique , HIGH (HAUT) sur la broche trig
| + | |
− | delayMicroseconds(10); // attente pendant 10 microsecondes
| + | |
− | digitalWrite(trig, LOW); // met un niveau logique , LOW (BAS) sur la broche trig.
| + | |
− | lecture_echo = pulseIn(echo, HIGH); // lit la durée du niveau HAUT appliqué sur la broche echo
| + | |
− | cm = lecture_echo / 58; // conversion de la distance en cm
| + | |
− | Serial.print("Distance en cm : "); // affiche le message : "Distance en cm" sur le moniteur série
| + | |
− | Serial.println(cm); // affiche la mesure en cm avec retour à la ligne
| + | |
− | if (cm < 20) // si mesure < 10 => tourner sens aléatoire
| + | |
− | {
| + | |
− | if (millis()%2 == 1)
| + | |
− | {
| + | |
− | Droite();
| + | |
− | delay (1000);
| + | |
− | }
| + | |
− | else
| + | |
− | {
| + | |
− | Gauche();
| + | |
− | delay (1000);
| + | |
− | }
| + | |
− | }
| + | |
− | } // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
| + | |
− | | + | |
− | void Stop() {
| + | |
− | if (servoA.attached()) servoA.detach(); // détache le servomoteur de la broche = arret propre servomoteur
| + | |
− | if (servoB.attached()) servoB.detach(); // détache le servomoteur de la broche = arret propre servomoteur
| + | |
− | }
| + | |
− | | + | |
− | void Avant() {
| + | |
− | if (!servoA.attached()) servoA.attach(broche_servoA); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoA.writeMicroseconds(MAX_SENS1); // crée impulsion - sens2
| + | |
− | if (!servoB.attached()) servoB.attach(broche_servoB); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoB.writeMicroseconds(MAX_SENS2); // crée impulsion - sens1
| + | |
− | }
| + | |
− | | + | |
− | void Arriere() {
| + | |
− | if (!servoA.attached()) servoA.attach(broche_servoA); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoA.writeMicroseconds(MAX_SENS2); // crée impulsion - sens1
| + | |
− | if (!servoB.attached()) servoB.attach(broche_servoB); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoB.writeMicroseconds(MAX_SENS1); // crée impulsion - sens2
| + | |
− | }
| + | |
− | void Gauche() {
| + | |
− | if (!servoA.attached()) servoA.attach(broche_servoA); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoA.writeMicroseconds(MAX_SENS1); // crée impulsion - sens2
| + | |
− | if (!servoB.attached()) servoB.attach(broche_servoB); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoB.writeMicroseconds(MAX_SENS1); // crée impulsion - sens1
| + | |
− | }
| + | |
− | | + | |
− | void Droite() {
| + | |
− | if (!servoA.attached()) servoA.attach(broche_servoA); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoA.writeMicroseconds(MAX_SENS2); // crée impulsion - sens1
| + | |
− | if (!servoB.attached()) servoB.attach(broche_servoB); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoB.writeMicroseconds(MAX_SENS2); // crée impulsion - sens2
| + | |
− | }
| + | |
− | | + | |
− | </syntaxhighlight>
| + | |
− | | + | |
− | ===== Programme avec NeoPixel Ring =====
| + | |
− | | + | |
− | Voici le programme qu'il faut éditer dans l'IDE Arduino, puis compiler et charger dans la carte Arduino
| + | |
− | <br />
| + | |
− | | + | |
− | <syntaxhighlight lang="cpp" enclose="div">
| + | |
− | /*
| + | |
− | Ce programme de démonstration permet de faire fonctionner le robot équipé d'un Neopixel Ring d'une manière autonome
| + | |
− | */
| + | |
− | | + | |
− | #include <Servo.h> // librairie pour servomoteur
| + | |
− | #include <Adafruit_NeoPixel.h> // librairie pour NeoPixel Ring
| + | |
− | | + | |
− | #define broche_servoA 3 // broche servo A
| + | |
− | #define broche_servoB 5 // broche servo B
| + | |
− | #define trig 2 // broche trig du capteur US HC-SR04
| + | |
− | #define echo 4 // broche echo du capteur US HC-SR04
| + | |
− | #define ring 6 // broche Data du NeoPixel Ring
| + | |
− | | + | |
− | const int MAX_SENS2=1000; // largeur impulsion pour position ANGLE_MIN degrés du servomoteur
| + | |
− | const int ARRET=1490; // largeur impulsion pour position ANGLE_MEDIANE degrés du servomoteur
| + | |
− | const int MAX_SENS1=2000; // largeur impulsion pour position ANGLE_MAX degrés du servomoteur
| + | |
− | | + | |
− | // classiquement : centrage sur 1500 - maxi sens 1 = 1000 et maxi sens 2 = 2000
| + | |
− | | + | |
− | // --- Déclaration des constantes des broches E/S numériques ---
| + | |
− | | + | |
− | long lecture_echo = 0; // variable sur 4 octets mesure de distance
| + | |
− | long cm = 0; // variable sur 4 octets pour la conversion en cm
| + | |
− | | + | |
− | //--- Création objet servomoteur
| + | |
− | Servo servoA; // crée un objet servo pour contrôler le servomoteur A
| + | |
− | Servo servoB; // crée un objet servo pour contrôler le servomoteur B
| + | |
− | | + | |
− | Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, ring, NEO_GRB + NEO_KHZ800); //
| + | |
− | | + | |
− | // La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme
| + | |
− | | + | |
− | void setup() { // debut de la fonction setup()
| + | |
− | | + | |
− | // --- ici instructions à exécuter 1 seule fois au démarrage du programme ---
| + | |
− | | + | |
− | pinMode (broche_servoA,OUTPUT); // Broche broche_servo configurée en sortie
| + | |
− | pinMode (broche_servoB,OUTPUT); // Broche broche_servo configurée en sortie
| + | |
− | pinMode (trig,OUTPUT); // broche broche trig configurée en sortie
| + | |
− | digitalWrite(trig, LOW); // met un niveau logique , LOW (BAS) sur la broche trig
| + | |
− | pinMode(echo, INPUT); // la broche echo est initialisée en entree
| + | |
− | Serial.begin(115200); // initialisation de la liaison série à 115200 bauds
| + | |
− | strip.begin();
| + | |
− | strip.show(); // Initialisation du NeoPixel Ring
| + | |
− | rainbowCycle(10); // LED RING = Arc en ciel
| + | |
− | }
| + | |
− | // fin de la fonction setup()
| + | |
− | // ********************************************************************************
| + | |
− | | + | |
− | // la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension
| + | |
− | | + | |
− | void loop(){ // debut de la fonction loop()
| + | |
− | | + | |
− | Avant();
| + | |
− | digitalWrite(trig, HIGH); // met un niveau logique , HIGH (HAUT) sur la broche trig
| + | |
− | delayMicroseconds(10); // attente pendant 10 microsecondes
| + | |
− | digitalWrite(trig, LOW); // met un niveau logique , LOW (BAS) sur la broche trig.
| + | |
− | lecture_echo = pulseIn(echo, HIGH); // lit la durée du niveau HAUT appliqué sur la broche echo
| + | |
− | cm = lecture_echo / 58; // conversion de la distance en cm
| + | |
− | Serial.print("Distance en cm : "); // affiche le message : "Distance en cm" sur le moniteur série
| + | |
− | Serial.println(cm); // affiche la mesure en cm avec retour à la ligne
| + | |
− | if (cm < 20) // si mesure < 20 cm => tourner sens aléatoire
| + | |
− | {
| + | |
− | if (millis()%2 == 1)
| + | |
− | {
| + | |
− | Droite(); // appel fonction Droite()
| + | |
− | delay (1000);
| + | |
− | }
| + | |
− | else
| + | |
− | {
| + | |
− | Gauche(); // appel fonction Gauche()
| + | |
− | delay (1000);
| + | |
− | }
| + | |
− | }
| + | |
− | } // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
| + | |
− | | + | |
− | void Stop() {
| + | |
− | if (servoA.attached()) servoA.detach(); // détache le servomoteur de la broche = arret propre servomoteur
| + | |
− | if (servoB.attached()) servoB.detach(); // détache le servomoteur de la broche = arret propre servomoteur
| + | |
− | }
| + | |
− | | + | |
− | void Avant() {
| + | |
− | if (!servoA.attached()) servoA.attach(broche_servoA); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoA.writeMicroseconds(MAX_SENS2); // crée impulsion - sens2
| + | |
− | if (!servoB.attached()) servoB.attach(broche_servoB); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoB.writeMicroseconds(MAX_SENS1); // crée impulsion - sens1
| + | |
− | ringOff(); // appel fonction extinction de toutes les LED
| + | |
− | strip.setPixelColor(14, strip.Color(0,150,0)); // LED verte brillance moyenne.
| + | |
− | strip.setPixelColor(15, strip.Color(0,150,0)); // LED verte brillance moyenne.
| + | |
− | strip.setPixelColor(0, strip.Color(0,150,0)); // LED verte brillance moyenne.
| + | |
− | strip.show(); // Envoi des données vers le Ring.
| + | |
− | }
| + | |
− | | + | |
− | void Arriere() {
| + | |
− | if (!servoA.attached()) servoA.attach(broche_servoA); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoA.writeMicroseconds(MAX_SENS1); // crée impulsion - sens1
| + | |
− | if (!servoB.attached()) servoB.attach(broche_servoB); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoB.writeMicroseconds(MAX_SENS2); // crée impulsion - sens2
| + | |
− | }
| + | |
− | void Gauche() {
| + | |
− | if (!servoA.attached()) servoA.attach(broche_servoA); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoA.writeMicroseconds(MAX_SENS1); // crée impulsion - sens2
| + | |
− | if (!servoB.attached()) servoB.attach(broche_servoB); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoB.writeMicroseconds(MAX_SENS1); // crée impulsion - sens1
| + | |
− | ringOff(); // appel fonction extinction de toutes les LED
| + | |
− | for(int i=2;i<5;i++){
| + | |
− | strip.setPixelColor(i, strip.Color(150,0,0)); // LED rouge brillance moyenne.
| + | |
− | strip.show(); // Envoi des données vers le Ring.
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | void Droite() {
| + | |
− | if (!servoA.attached()) servoA.attach(broche_servoA); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoA.writeMicroseconds(MAX_SENS2); // crée impulsion - sens1
| + | |
− | if (!servoB.attached()) servoB.attach(broche_servoB); // attache le servomoteur à la broche si pas attaché
| + | |
− | servoB.writeMicroseconds(MAX_SENS2); // crée impulsion - sens2
| + | |
− | ringOff(); // appel fonction extinction de toutes les LED
| + | |
− | for(int i=10;i<13;i++){
| + | |
− | strip.setPixelColor(i, strip.Color(150,0,0)); // LED rouge brillance moyenne.
| + | |
− | strip.show(); // Envoi des données vers le Ring.
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | void ringOff()
| + | |
− | {
| + | |
− | for(int i=0;i<16;i++){
| + | |
− | strip.setPixelColor(i, strip.Color(0,0,0)); // Toutes les LED éteintes
| + | |
− | strip.show(); // Envoi des données vers le Ring.
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | void rainbowCycle(uint8_t wait) {
| + | |
− | uint16_t i, j;
| + | |
− | | + | |
− | for(j=0; j<256; j++) { // 1 cycle couleur arc en ciel j<256*n = n cycles couleur arc en ciel
| + | |
− | for(i=0; i< strip.numPixels(); i++) {
| + | |
− | strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
| + | |
− | }
| + | |
− | strip.show();
| + | |
− | delay(wait);
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | uint32_t Wheel(byte WheelPos) {
| + | |
− | WheelPos = 255 - WheelPos;
| + | |
− | if(WheelPos < 85) {
| + | |
− | return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
| + | |
− | } else if(WheelPos < 170) {
| + | |
− | WheelPos -= 85;
| + | |
− | return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
| + | |
− | } else {
| + | |
− | WheelPos -= 170;
| + | |
− | return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | </syntaxhighlight>
| + | |
− | | + | |
− | == [[Téléchargements]] ==
| + | |
− | === [[Documents de présentation]] ===
| + | |
− | === [[Pièces imprimables]] ===
| + | |
− | <br>
| + | |
− | Les pièces imprimables : base, roue, support capteur Ultra-sons et plaque pour support de piles sont téléchargeable sur Thingiverse:
| + | |
− | <br>
| + | |
− | http://www.thingiverse.com/thing:833005
| + | |
− | | + | |
− | === [[Programmes]] ===
| + | |
− | | + | |
− | [[Rajout du capteur de vide]]
| + | |