RoboduLAB
Constitution du robot
RoboduLAB est constitué d'un châssis avec une roulette à bille, de deux roues montées sur des servomoteurs qui sont commandés par une carte de prototypage arduino et d'un capteur à ultrasons.
Il sera possible de rajouter différentes options au modèle de base :
- LED RGB, ou NeoPixel Ring
- 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
Raccordement des différents éléments du robot avec NeoPixel Ring
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 :
- se connecter sur la page : http://robotdulab.labaixbidouille.com
- composer le programme en assemblant les blocs,
- copier le code produit dans l'IDE arduino, ou cliquer sur le bouton "Télécharger",
- télécharger (téléverser) le code dans la carte de prototypage arduino.
Téléchargements
Documents de présentation
https://github.com/LabAixBidouille/RobotDuLAB-blockly/blob/gh-pages/Plaquette%20robodulab-2.pdf
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
Bibliothèque RobotDuLAB
La bibliothèque arduino "RoboduLAB" peur être téléchargée ici : https://github.com/LabAixBidouille/RobotDuLAB-arduino-library