Tuto pas-à-pas C++ : utiliser un servomoteur SG90 9g avec la Gamebuino Meta

Voici un tutoriel étape par étape qui vous permettra de réaliser un programme simple afin d’utiliser un servomoteur piloté par la console.

Le tuto est destiné à être réalisé avec le matériel fourni dans le pack d’accessoires Gamebuino. Toutefois vous pouvez bien entendu utiliser un autre servomoteur tant que celui-ci est compatible Arduino.

Pour ce tutoriel, il vous faut :

  • une console Gamebuino META
  • Un servomoteur 5V compatible Arduino
  • un ordinateur avec l’environnement de développement l’IDE Aduino installé

Si ce n’est pas encore fait, reportez vous à la fiche
Premiers pas (C++ 1/5) : Installation rapide du logiciel - Gamebuino pour installer l’IDE Arduino.

Si vous avez déjà les bases en programmation (ou la flemme de lire tout le tuto qui suit) vous pouvez trouver le code complet du programme réalisé ici dans le Mini-code : servomoteur

Etape 1 : Bien commencer

Cette étape est identique sur la plupart des tutos car elle constitue la base indispensable de n’ilmporte quel programme pour Gamebuino.

Pour commencer, ouvrez l’éditeur Arduino préconfiguré pour la Gamebuino

-Vous devriez avoir ceci sur votre écran :

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}

Pour l’instant, le code est un peu vide, mais on va le compléter.

  • En premier lieu on a besoin d’ajouter au tout début du fichier la ligne suivante :
#include <Gamebuino-Meta.h>

C’est ce qu’on appelle une “librairie”, elle va nous permettre d’utiliser tout un tas de fonctions sans avoir à les programmer à la main. Cette librairie contient toutes les fonctions de la Gamebuino et est très utile pour la suite.
On va ajouter deux fonctions pour que notre programme puisse fonctionner :

  • Dans la fonction setup() on ajoute un appel à la fonction gb.begin() comme suit :
void setup() {
  // put your setup code here, to run once:
  gb.begin();
}

La fonction gb.begin() permet d’initialiser la console : sans cela rien ne fonctionnera !

  • Ensuite, on ajoute la fonction waitForUpdate() dans la fonction loop :
void loop() {
  // put your main code here, to run repeatedly:
  gb.waitForUpdate();
}

La fonction waitForUpdate() permet de rafraichir le contenu de l’écran (c’est à dire dessiner dessus), gère la lecture des sons, les appuis sur les touches, bref tout ce qui donne vie à votre Gamebuino.

On a à présent une structure de programme fonctionnelle, même si elle ne fait encore rien de concret.

Les branchements

En parallèle de notre code il faut brancher le servo à la console, si possible avec le backpack.
On branche l’ alimentation (VCC, câble ROUGE) sur le pin VBAT, la masse (GND, câble BRUN) sur une masse et l’entrée de commande digitale (câble ORANGE) sur une pin digitale, ici la pin 10.

Servo Backpack Couleur Description
PWM 10 ORANGE Commande du servo
VCC VBAT ROUGE Alimentation
GND GND BRUN Masse


Etape 2 : Commander le servomoteur

Avant de faire bouger notre servo dans tous les sens il y a quelques petites choses très simples à faire.

  • On commence par ajouter la libraire <Servo.h> à notre programme avant de déclarer une variable Servo pour donner nommer notre moteur et y faire référence dans notre code :
#include <Gamebuino-Meta.h>
#include <Servo.h> // Librairie Arduino pour utilisation de servomoteurs

Servo motor;      // declaration d'un nouveau servomoteur appellé "motor"

Cela nous permet d’avoir accès à diverses fonctions nécessaires au contrôle du servo sans avoir à les coder nous-même.

Ensuite on va devoir déterminer quelle pin est utilisée pour commander notre moteur et lui donner une position “par défaut”

  • Cela se fait dans la fonction setup() comme suit :
void setup() {
  // put your setup code here, to run once:
  gb.begin();

  motor.attach(10);    // définition du port de contrôle du moteur sur le pin digital 10
  motor.write(10);     // démarrage du moteur à la position 10°
}

Notez qu’on commence à 10° et non pas 0°. C’est parce que le moteur peine un peu à atteindre les extrêmes que sont 0° et 180°. Aussi on fera en sorte de s’arrêter avant.

On peut maintenant contrôler notre servomoteur à volonté.

Ici nous allons lui assigner trois positions fixes et faire varier la position active en fonction de l’appui sur les touches droite, haut et gauche, respectivement RIGHT, UP et LEFT.

  • On va déclarer une chaîne de caractères “direction” qu’on va utiliser pour noter cette position :
#include <Servo.h> // Librairie Arduino pour utilisation de servomoteurs

Servo motor;      // declaration d'un nouveau servomoteur appellé "motor"
char *direction;  // declaration d'une string utilisée pour noter la "direction"`cpp

Maintenant passons au contrôle proprement dit.

  • Pour cela on vient modifier notre fonction loop() de la manière suivante :
void loop(){
  // put your main code here, to run repeatedly:
  gb.waitForUpdate();
  
// Changement de la position du moteur en fonction de la touche utilisée
  if (gb.buttons.pressed(BUTTON_RIGHT)){
    motor.write(10); // angle à 10°
    direction = "RIGHT";
  }
  if (gb.buttons.pressed(BUTTON_UP)){
    motor.write(90); // angle à 90°
    direction= "UP";
  }
  if (gb.buttons.pressed(BUTTON_LEFT)){
    motor.write(170); // angle à 170°
    direction = "LEFT";
  }
}

A chaque cycle on vient vérifier si une touche est pressée afin d’ajuster la position, spécifiée en angle, de notre servo. On en profite pour changer la valeur de notre chaîne “direction” en fonction de la touche enfoncée.

En lançant la compilation du programme et et le téléversant sur la console vous pouvez à présent faire bouger le servo en appuyant sur les boutons gauche, haut et droit.

Etape 3 : Ajouter une interface visuelle

Pour mieux appréhender le mouvement du servomoteur on va ajouter une petite couche visuelle à notre programme. C’est un moyen simple et rapide d’avoir un retour sur l’action de notre servo sans le regarder, très pratique quand on l’intègre dans un système fermé comme un petit robot par exemple.

Pour cela on utilisera une fonction dédiée que l’on va appeler direction_display()

  • On déclare donc cette fonction et on l’ajoute dans notre boucle loop() :
void loop(){
  // put your main code here, to run repeatedly:
  gb.waitForUpdate();
  
// Changement de la position du moteur en fonction de la touche utilisée
  if (gb.buttons.pressed(BUTTON_RIGHT)){
    motor.write(10); // angle à 10°
    direction = "RIGHT";
  }
  if (gb.buttons.pressed(BUTTON_UP)){
    motor.write(90); // angle à 90°
    direction = "UP";
  }
  if (gb.buttons.pressed(BUTTON_LEFT)){
    motor.write(170); // angle à 170°
    direction = "LEFT";
  }
  direction_display();
}

void direction_display(){
  gb.display.clear();
}

Pour le moment la fonction ne fait rien de particulier à part effacer l’écran à chaque cycle, pas de panique on va la remplir un peu plus.

On va commencer par afficher le contenu de notre chaîne “direction” à l’écran. Afficher ainsi le contenu d’une variable est un des moyens les plus simples et rapides pour vérifier le bon fonctionnement d’un programme.

  • On affiche la valeur en appelant simplement une fonction printf() dans notre fonction direction_display() :
void direction_display(){

  gb.display.clear();

  // Affichage de la direction actuelle
  gb.display.setColor(WHITE);
  gb.display.printf( " %s", direction );
}

00002
A présent on a sur l’écran une indication claire et précise de la direction de notre servomoteur. On va faire encore un peu mieux en ajoutant de petites icones en plus du texte, ça n’est pas compliqué et c’est toujours plus parlant.

On va utiliser pour cela les fonctions drawTriangle et fillTriangle pour créer de petites “flèches” à l’écran qui représenteront l’état de notre servomoteur.

  • Accrochez vous un peu ça ressemble à ceci :
void direction_display(){

 gb.display.clear();

// Affichage des flèches directionnelles avec des triangles dont on change la couleur en fonction de la position actuelle

if(direction == "UP"){
  gb.display.setColor(RED);
  gb.display.fillTriangle(gb.display.width()/2 - 5, 20, gb.display.width()/2, 10, gb.display.width()/2 + 5, 20);
}
else{
  gb.display.setColor(WHITE);
  gb.display.drawTriangle(gb.display.width()/2 - 5, 20, gb.display.width()/2, 10, gb.display.width()/2 + 5, 20);
}
if(direction == "RIGHT"){
  gb.display.setColor(RED);
  gb.display.fillTriangle(gb.display.width()/2 + 25, gb.display.height()/2, gb.display.width()/2 + 15, gb.display.height()/2 + 5, gb.display.width()/2 + 15, gb.display.height()/2 - 5);
}
else{
  gb.display.setColor(WHITE);
  gb.display.drawTriangle(gb.display.width()/2 + 25, gb.display.height()/2, gb.display.width()/2 + 15, gb.display.height()/2 + 5, gb.display.width()/2 + 15, gb.display.height()/2 - 5);
}
if(direction == "LEFT"){
  gb.display.setColor(RED);
  gb.display.fillTriangle(gb.display.width()/2 - 25, gb.display.height()/2, gb.display.width()/2 - 15, gb.display.height()/2 + 5, gb.display.width()/2 - 15, gb.display.height()/2 - 5);
}
else{
  gb.display.setColor(WHITE);
  gb.display.drawTriangle(gb.display.width()/2 - 25, gb.display.height()/2, gb.display.width()/2 - 15, gb.display.height()/2 + 5, gb.display.width()/2 - 15, gb.display.height()/2 - 5);
}

// Affichage de la direction actuelle
gb.display.setColor(WHITE);
gb.display.printf( " %s", direction );
}

00001
On utilise simplement quelques “if” et “else” pour afficher des triangles blancs vides dans nos trois directions. La direction active, c’est à dire celle du dernier appui sur une des touches que nous avons programmé (gauche, haut, droite), voit le triangle blanc vide remplacé par un triangle rouge plein.

Notez qu’ici les coordonnées des points de chaque triangle sont principalement indiquées en utilisant les valeurs de gb.display.height() et gb.display.width(), cela permet d’avoir un programme qui d’adapte automatiquement à la résolution d’écran même si on la change. Accessoirement c’est beaucoup plus facile quand on veut placer des objets à des intervalles précises sans avoir à calculer chaque coordonnée “à la main”.

Félicitations vous avez survécu à un tuto supplémentaire ! J’espère qu’il vous aura servi à apprendre quelques petites choses utiles. A vous de jouer maintenant, bidouillez votre programme pour lui faire faire d’autres choses si vous le voulez, c’est un très bon moyen d’apprendre.

:face_with_monocle: Et pour aller plus loin, pourquoi ne pas enchainer sur ce tuto de @Steph ?
Commander un servomoteur SG90 avec un potentiomètre