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

38 comments on “Ma Machine Inutile, découverte d’Arduino

  1. Wow, quelle démonstration éblouissante ! :D
    Une belle pédagogie et… je ne peux m’empêcher de noter la qualité de ton orthographe, que ça fait du bien ! ;-)

  2. bonjour je trouve cela extra mais par rapport a la programmation de la carte
    et t’il possible de faire avec un seul servo un mode fun ? servo change de mouvements et de vitesse entre plusieurs sequences ?

  3. bonjour, merci pour votre excellente explication. Me permettez vous d’utiliser votre code et d’éventuellement l’adapter ? ça me servirait d’exercice d’application pour débuter !

  4. merci !
    je suis en train de régler mes angles de servos, ça à l’air de fonctionner !
    je n’ai pas mis de relais par contre , ça marchera quand même ? si j’ai bien compris il ne sert qu’à stopper la consommation de courant lorsque il n’y a pas de commandes en cours ?

  5. merci, je suis en train de régler mes angles de servos , ça a l’air de fonctionner !
    je n’ai par contre pas mis de relais, si j’ai bien compris , il sert à stopper la conso de courant lorsqu’il n’y a pas de commandes en cours ?

  6. Oui, ça permet d’éteindre complètement le servo. Finalement dans mon montage c’est peu utile (en termes d’économie d’énergie) car j’alimente l’Arduino avec un adaptateur secteur USB, mais ça me permet de le laisser brancher sans que les servos soient alimentés 24h/24…

  7. super , tout marche bien, merci pour votre aide ;-)
    seule petite différence, mon mouvement de bras est toujours le même alors que sur votre vidéo il semble être différent à chaque fois…

  8. pareil dans mon cas .. c’est deja bien mais j’aurais prefere le style ” FUN ” avec changement de sequences .. mais vu que j’y connais rien c’est la tout le probleme ^^

  9. Eric et Stef,

    Oh mais oui, vous m’y faites penser… J’ai mis le programme simple… et je l’ai adapté dans un deuxième temps pour les trucs variés…

    Je me note de retrouver le code source correspondant… Je vous tiens au courant :)

  10. Merci en tout cas pour cela est t’il possible de lire ou d’ extraire un programme televerse ??
    Perso j’ ai essayé de comprendre le code de base et de changer quelques variantes pour éviter le même mouvement mais cela n’est pas correct … vu mon niveau

  11. Eh non, on ne peut pas récupérer du code téléversé sur l’Arduino (ou alors seulement sous sa forme compilée en langage machine plutôt illisible). Mais je le retrouverai t’en fais pas :)

  12. Cool, tu fera des heureux c’est sur ^^
    vive les Machines Inutiles …

  13. Et voilou retrouvé ! Juste le temps d’ajouter du commentaire :) J’ai mis à jour le post, y’a un lien vers le code qui tourne sur mon robot tout à la fin !

  14. zut désolé te t’embéter encore mais il m’indique des erreurs dans le code….

    boite_inutile_avec_plusieurs_mouvements.ino: In function ‘void openBox(int)’:

    boite_inutile_avec_plusieurs_mouvements.ino:209:13: error: ‘servoPause’ was not declared in this scope

    boite_inutile_avec_plusieurs_mouvements.ino:221:13: error: ‘servoPause’ was not declared in this scope

    j’essaie de comprendre mais ça dépasse pour le moment mais compétences !

  15. c’est bon, j’ai trouvé l’erreur, c’est à la fin de la ligne 173 , il manque */

  16. impec ! du coup nouveau probleme chez moi ;-)
    sur ton premier code , j’avais du modifier la ligne 36 en mettant HIGH à la place de LOW pour que ça fonctionne avec mon montage mais là le code est plus compliqué ! j’ai essayé d’inverser chaque commande lié à l’interrupteur ( les digitalRead ? ) mais c’est pas bon.
    je cherche ,je cherche ….
    merci encore quand même , ça me fait un bon départ !

  17. Whouu super et grand merci …a mon tour de tester cette apres-midi en espérant etre plus chanceux que Eric …
    Et si cela fonctionne bien pourquoi pas vous faire la demo en video
    A suivre !!

  18. oup’s l’ouverture de ma boite et a droite et le bouton a gauche , j’imagine qu’il faut que je change les angles du servo non ??

  19. re oup’s j’ai rien dit c’est comme eric bouton a l’envers et ca fonctionne du tonerre … UN GRAND merci pour ton code Funny
    ps : j’aime beaucoup l’option quand on touche a rien ^^

  20. au cas ou , pour ajuster la course du servo c’est qu’elle ligne a modifier ??

  21. C’est les deux appels à initServo(), dans la fonction loop() ! (-14 à -45 pour mon servo qui ouvre, 48 à -30 pour celui qui appuie sur le bouton)

  22. bon, chez moi ça veut pas ! mais tant pis ,je décortique et j’essaie de comprendre ! j’ai l’impression que et mes servos et mon interrupteur sont interprétés à l’envers …
    je crois que je vais prendre les tutos arduino à la base et apprendre depuis le début, j’ai voulu être trop gourmand ! celui d’eskimon m’a l’air parfaitement adapté , plus qu’à tout assimiler ,je met le lien dessous , ça pourra servir à d’autres ! on se dit rendez vous dans 1 an ;-)
    http://eskimon.fr/ebook-tutoriel-arduino

  23. reglages ajustés de mon cote pour le servo
    R.A.S pour le code je laisse comme ca ^^
    bon courage Eric et merci pour tous Colin

  24. Stef , tu as utilisé aussi un relais comme sur le plan de Colin ?

  25. Non pas de relais juste un servo et un bouton pour ma version
    j’ai rajoute une led pour le cote fun simplement branche sur le 3v3 et un GND inutilise …

  26. moi aussi j’ai cru au servo dans un premier temps et en inversant le bouton comme a dit Colin c’etais bon puis reglage perso pour la course du servo …
    je sais pas quoi en penser pour t’aider :(
    bon courage en tout cas !!

  27. Salut Stef ! Merci pour la vidéo ! J’aime beaucoup ton bras qui ressemble à un coléoptère :)

  28. oui effectivement d’ou l’interêt de ton code pour lui donner plus de panache …
    mon seul regret l’ouverture de la boite que j’aurais souhaite plus grande !!
    mais c’est du detail apres tout ^^

Leave a Reply

news for few, stuff no-one cares about