RoboduLAB : Différence entre versions

De Wiki L.A.B
Aller à : navigation, rechercher
(Programme avec NeoPixel Ring)
(Programme sans NeoPixel Ring)
Ligne 66 : Ligne 66 :
  
 
<syntaxhighlight lang="cpp" enclose="div">
 
<syntaxhighlight lang="cpp" enclose="div">
 
 
</syntaxhighlight>
 
  
 
/*
 
/*
Ligne 170 : Ligne 167 :
 
   servoB.writeMicroseconds(MAX_SENS2); // crée impulsion - sens2
 
   servoB.writeMicroseconds(MAX_SENS2); // crée impulsion - sens2
 
}
 
}
 +
 +
</syntaxhighlight>
  
 
===== Programme avec NeoPixel Ring =====
 
===== Programme avec NeoPixel Ring =====

Version du 11 août 2016 à 10:35

Présentation du projet


Un robot pour apprendre à programmer en classe

  • Utilisable en écoles primaires, collèges et lycées
  • Toutes les pièces mécaniques sont imprimables (impression 3D – fichiers .stl fournis)
  • Partie électronique basée sur une carte de prototypage « arduino »
  • Libre (copiable, modifiable) et évolutif (de nombreuses options possibles)


RoboduLAB, permet une approche ludique de l’apprentissage du code à l’école primaire, des plots au format lego permettent de personnaliser le robot.

RoboduLAB avec paques lego et ring 16 LED
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.

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.

600px

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.
Les fichiers .stl sont téléchargeables ici : http://www.thingiverse.com/thing:833005

Électronique

Liste des différents composants du robot sans NeoPixel Ring

La partie électronique du robot comporte à minima :

  • une carte arduino (UNO),
  • deux servomoteurs à rotation continue,
  • un capteur à ultrasons,
  • un boîtier pour piles (6 piles AA)
  • un interrupteur à glissière.

Raccordement des différents éléments du robot sans NeoPixel Ring

Schéma sans ring.JPG


Raccordement des différents éléments du robot avec NeoPixel Ring

Schéma avec ring.JPG

Programmes

Le programme nécessaire pour le fonctionnement du robot peut être :
- soit écrit directement en C++ et téléchargé (téléversé) dans la carte arduino,
- soit représenté par des blocs graphiques (Blokly). 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

/*
  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_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
}

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 - sens1
  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 - sens2
  if (!servoB.attached()) servoB.attach(broche_servoB); // attache le servomoteur à la broche si pas attaché
  servoB.writeMicroseconds(MAX_SENS2); // crée impulsion - sens2
}
Programme avec NeoPixel Ring

Voici le programme qu'il faut éditer dans l'IDE Arduino, puis compiler et charger dans la carte Arduino

/*
  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);
  }
}

Programmation du robot en langage graphique (Blokly)

Pour programmer le robot en langage graphique, il faut :

  1. se connecter sur la page : https://labaixbidouille.github.io/RobotDuLAB-blockly/
  2. composer le programme en assemblant les blocs,
  3. copier le code produit dans l'IDE arduino, ou cliquer sur le bouton "Générer code",
  4. télécharger (téléverser) le code dans la carte de prototypage arduino.

Téléchargements

Documents de présentation

Pièces imprimables

Les pièces imprimables : base, roue, support capteur Ultra-sons et plaque pour support de piles sont téléchargeable sur Thingiverse:
http://www.thingiverse.com/thing:833005

Librairie RboduLAB