DIY: Ma Machine Inutile, découverte d’Arduino

Ça faisait quelque temps que j’avais envie de m’intéresser à la plateforme Arduino, une petite carte électronique à peine plus grosse qu’une carte de crédit, très peu chère et qui permet de faire plein de choses – électronique, domotique, robotique, … très facilement pour quiconque connaît un tout petit peu la programmation. Le web fourmille de forums et de tutoriaux qui facilitent grandement les choses, et un tout un tas de capteurs et actuateurs à bas prix sont disponibles facilement : détecteurs de lumière, accéléromètres, même des puces GPS ! et côté actuateurs, servos, moteurs, lumières, relais (pour commander des circuits haute tension), ….

Bref il ne me manquait que l’idée d’un premier robot pour me lancer, et je suis tombé par hasard sur le concept de la Most Useless Machine of the World, un tout petit robot tout simple, qui ne sert à rien, mais que l’on peut compliquer si on en a envie, et je me suis dit que ce serait un super premier projet.

Voilà ce que ça donne, présenté par mon fils Gaspard (mes deux enfants sont fans du robot, ils vont être déçus quand je vais l’apporter au travail) :

On m’a demandé les plans, donc voici !

Liste de courses

  • Une boîte en bois (que vous pouvez aussi construire vous même, j’ai fait la mienne en balsa de 5 mm), de dimensions intérieures minimum 14 x 10 x 6 cm, mais vous pouvez tabler sur 17 x 13 x 7 pour avoir plus de place)
  • Une carte Arduino, Arduino Uno par exemple car elle dispose d’un port USB qui peut servir d’alimentation et d’une alimentation, c’est plus pratique pour une première carte – j’ai vu qu’il existe des Mini ou Pro Mini, qui consomment moins en veille, mais pour lesquelles il faut fournir une alimentation stabilisée et un adaptateur USB/Série. Bref, Uno pour commencer c’est parfait.
  • Deux servos d’entrée de gamme (3 kg de couple suffiront largement, la vitesse importe peu, la pignonnerie nylon non plus :-))
  • Un interrupteur à levier et une résistance 10 kOhmsà
  • Optionnellement, un relais soit simple (mais il faut alors faire un peu plus d’électronique), soit facile à utiliser sur plateforme Arduino.

La première étape consiste à faire les branchements. Le plus simple est d’acheter quelques fils de prototypage et une platine de prototypage, mais sinon la soudure fonctionne bien aussi. Côté Arduino on peut planter des fils étamés avec de la soudure dans les broches.

Il faut que l’Arduino ouvre la boîte, lance le bras qui va rappuyer sur l’interrupteur, rentre le bras puis referme la boîte lorsqu’on appuie sur l’interrupteur.

Arduino a justement un exemple pour lire l’état d’un interrupteur : http://arduino.cc/en/Tutorial/DigitalReadSerial

Pour pouvoir lire de manière fiable si une broche est HIGH (alimentée) ou LOW (non) il faut qu’elle soit mise à la masse quand elle ne l’est pas (sinon elle « flotte » à un potentiel indéterminé). Je compte brancher l’interrupteur à la broche 2, donc je connecte la broche 2 et la broche GND (ground) avec la résistance, et la broche +5V à la broche 2 avec l’interrupteur au milieu :

DSC_9148

Ensuite, je compte alimenter les servos avec le relais pour ne pas gaspiller de courant quand la boîte ne fait rien. Le relais est contrôlé par une petite tension au borne d’un solénoïde qui permet de déplacer mécaniquement un interrupteur. J’ai choisi un relais simple à interfacer avec l’Arduino, je branche donc sa masse avec celle de l’Arduino, son VCC (+5V) avec le +5V Arduino, et sa broche de contrôle sur la broche 3 de l’Arduino :

DSC_9149

Puis, l’alimentation des servos : leur masse est en commun avec celle de l’Arduino, leur + est lui coupé ou non par le relais. On branche donc le NO (normalement ouvert) du relais aux + des servos, et le C (Commun) du relais au +5V de l’Arduino :

DSC_9150

Et enfin, on branche le fil Signal des servos aux broches 4 et 5 de l’Arduino, respectivement :

DSC_9151

Avant de faire le montage définitif, il faut vérifier le code et calibrer les servos (sinon ils vont se jeter dans la boîte et quelque chose va se casser, et ce sera pas marrant). Le code, donc. L’installation de l’environnement Arduino est facile et cross-platform (et tout leur code est libre !). Une fois que c’est fait, on peut programmer. Un programme Arduino se compose de deux fonctions principales et obligatoires, setup() exécutée au démarrage, puis loop() exécutée en boucle. Nous allons utiliser la bibliothèque de contrôle de servos, donc nous l’incluons :

#include <Servo.h>
void setup() {
}
void loop() {
}

Puis on spécifie quelques constantes pour se souvenir plus facilement des broches, des sens de déplacements et des bornes des mouvements des servos (pour l’instant à 0-45 car on n’a pas testé) :

#include <Servo.h>
int brocheInter = 2;
int brocheRelais = 3;
int brocheServoBoite = 4;
int brocheServoBras = 5;
Servo servoBoite;
int departBoite = 0; /* Ces angles seront à adapter */
int finBoite = 45;
Servo servoBras;
int departBras = 0;
int finBras = 45;
int angleLeveBras = 1; /* Pour lever le bras on procèdera degré par degré jusqu'à 
                        * ce que l'interrupteur soit refermé */
void setup() {
}
void loop() {
}

Maintenant, on initialise les broches et les servos :

 void setup() {
  /* on spécifie que la broche est liée un capteur */
  pinMode(brocheInter, INPUT);

  /* On éteint le relais */
  digitalWrite(brocheRelais, LOW);

  /* Puis on spécifie que la broche est liée à un actuateur */
  pinMode(brocheRelais, OUTPUT);

  /* On "attache" les servos à leur broche de controle */
  servoBoite.attach(brocheServoBoite);
  servoBras.attach(brocheServoBras);

  /* On initialise les servos avec leur angle de départ */
  servoBoite.write(departBoite);
  servoBras.write(departBras);
}

Puis, dans loop, on va regarder à chaque début de boucle si l’interrupteur est HIGH (ou LOW, ça dépend du sens de montage de l’interrupteur !), et en fonction, allumer les servos (et les ré-éteindre à la fin) :

void loop() {
  /* L'interrupteur est il ouvert ? */
  if(digitalRead(brocheInter) == LOW) {
    /*  Oui ! il faut le refermer ! */

    /* Allumons les servos */    
    digitalWrite(brocheRelais, HIGH);

    /* On ouvre la boite avec le servo du couvercle */
    /* On tend le servo du bras */
    /* On range le servo du bras */
    /* On ferme la boite */
    /* Mais pour l'instant, on attend juste deux secondes */
    delay(2000);

    /* Eteignons les servos */
    digitalWrite(brocheRelais, LOW);
  }
}

Ça a l’air de marcher ! alors c’est parti pour bouger nos servos ! (Pendant les tests, n’oubliez pas de ré-éteindre l’interrupteur vous-même)

void loop() {
  /* L'interrupteur est il ouvert ? */
  if(digitalRead(brocheInter) == LOW) {
    /*  Oui ! il faut le refermer ! */

    /* Allumons les servos */    
    digitalWrite(brocheRelais, HIGH);

    /* On ouvre la boite avec le servo du couvercle */
    servoBoite.write(finBoite);
    /* On attend un peu, sinon ça va trop vite dans la séquence
     * pour les servos. */
    delay(200);

    /* On tend le bras du servo, pas plus loin que sa fin de course
     * et seulement jusqu'à ce que l'interrupteur soit rebasculé.
     */
    int angleServoBras = servoBras.read();
    while (angleServoBras != finBras && digitalRead(brocheInter == LOW)) {
      angleServoBras = angleServoBras + angleLeveBras;
      servoBras.write(angleServoBras);
      /* On attend pour que le servo aie le temps de bouger */
      delay(20);
    }
    /* On parcourt un dernier degré, sinon l'interrupteur ne bascule pas 
     * et revient quand le servo le lache. */
    servoBras.write(angleServoBras + angleLeveBras);
    delay(20);

    /*On range le servo du bras */
    servoBras.write(departBras);
    delay(200);

    /* On ferme la boite */
    servoBoite.write(departBoite);
    delay(200);

    /* Eteignons les servos */
    digitalWrite(brocheRelais, LOW);
  }
}

Une fois que tout le code fonctionne, il ne reste plus qu’à positionner les servos et l’interrupteur dans la boîte pour régler les angles de départ et de fin de course. Puis à finaliser le montage.

Pour mes servos, les angles sont de 76° (fermé) à 45° (ouvert) pour  l’ouverture de la boîte, et de 138° à 60° pour le bras. Comme ils sont « à l’envers », j’ai utilisé la variable angleLeveBras (= -1) pour un code plus naturel.

Pour le bras du robot, j’ai fait un petit montage avec du balsa de 2mm :

IMG_20140114_205936_820.1

La boîte :

IMG_20140114_235042_119.1

IMG_20140114_235121_541.1

Pour le couvercle qui se soulève, un simple élastique entre la paroi et le couvercle fait le travail de retour et le tient collé au bord :

DSC_9154

Pour le couvercle côté interrupteur, j’ai mis des guides pour le caler, mais des vis sont sans doute plus simples et plus solides. Je n’ai pas osé les vis sur du balsa :

DSC_9155

Et voilà le tout :

DSC_9156

Amusez-vous bien ! Pour moi, j’ai adapté le programme pour faire plein de trucs différents (vitesse, hésitations, etc). Voici le programme qui tourne sur mon Arduino : useless_machine_c.ino