Boite à coucou

Description ici d’un petit projet débuté avec le club robot, et qui répondait à quelques contraintes propices à la créativité… Objectif : proposer une « brique » pédagogique et ludique.

1. le projet devait être contenu dans une petite boite en plastique de 6 x 7 x 5 cm (donc plutôt avec une Arduino Nano…) ;

2. le projet devait proposer un montage simple et peu coûteux, pour être reproductible et bidouillable facilement (côte hardware, comme côté code).

J’ai choisi de mon côté un principe très basique mais qui fait son petit effet. Il s’agit d’animer une figurine et d’allumer une led lorsqu’on tapote sur la boite (détection de choc avec le piezo). Un couple d’aimants se charge du côté « magique » de la chose : le servo moteur avec son extension de palonnier surmonté d’un aimant vient entraîner une figurine en surface. Un peu de décor là-dessus, et voici une petite saynète pour les enfants.

Pour les ingrédients électroniques :

  • 1 Arduino Nano
  • 1 Servo moteur SG90
  • 1 led RGB Neopixel Adafruit
  • 1 buzzer piezo
  • 1 résistance 1M ohm
  • Du fil électrique pour relier ce petit monde !

Autres ingrédients :

  • La boite plastique en question, je sais plus où ça se trouve, mais ça se trouve… au pire on fait une boite en carton…
  • Bois à découper à la laser (3mm épaisseur, petite chute A6 environ)
  • 2 petits aimants, ou 3, ou 4… (3mm de diamètre)
  • 1 petite figurine au choix (moi j’ai pris un oiseau lego mais tu fais ce que tu veux!)

Outils :

  • Un fablab ! (accès à machine de découpe laser…)
  • 1 Poste à souder et de l’étain…
  • 1 pistocolle chargé à bloc !
  • Colle à bois
  • Un peu de peinture si tu veux peindre ton château!

Côté code Arduino

Rien de bien méchant côté code (c’était le but), mais l’astuce d’utiliser un piezo pour la détection de choc est très chouette (vu ici).

J’ai essayé de commenter le plus possible pour que les débutants puissent s’en emparer, mais j’ai surtout joué à créer des fonctions intégrant des variables (+rigolo qd on débute, de jouer avec des paramètres pour comprendre ce qu’il se passe je trouve).

Petite subtilité qui me taraudait quand même, je me suis échiné à créer une petite décélération avant l’arrêt du servo moteur. Ça rend le truc plus doux, et c’était un petit challenge. Sachant qu’il y a plein d’autres façon de le faire sans doute! Vous pouvez dérouler le code ci-dessous :

Voir le code Arduino

[code lang= »arduino »] //////////////////////////// ///// A. DÉCLARATIONS ////// //////////////////////////// // 1. LED RGB NEOPIXEL #include <Adafruit_NeoPixel.h> // Bibliothèque pour led RGB Adafruit NeoPixel const int ledPin = 3; // La pin où est connectée la Led const int nbLed = 1; // Le nombre de LED utilisées dans la guirlande int luminLed = 255; // instensité lumineuse des leds, de 0 (min) à 255 (max) Adafruit_NeoPixel ampoule(nbLed, ledPin, NEO_GRB + NEO_KHZ800); // 2. Servo moteur SG90 #include <Servo.h> // Bibliothèque pour servo moteurs const int servoPin = 11; // La pin où est connecté le servo moteur float angle; const int angleMin = 580; // angle min const int angleMax = 2500; // angle max // on peut tester ces valeurs min et max d’un servo via le code d’Eskimon, cf "Programme de test": // https://eskimon.fr/tuto-arduino-602-un-moteur-qui-a-de-la-t%C3%AAte-le-servomoteur#pr%C3%A9parer-le-terrain Servo monServo; // 3. Actionneur : buzzer piezo const int piezoPin = 0; // La pin analogique où est connecté le piezzo qui sert d’actionneur //////////////////////////////////////////////////// ///// B. INITIALISATION (JOUÉ UNE SEULE FOIS) ////// //////////////////////////////////////////////////// void setup() { // on place le servo à son point de départ, ici l’angle 0° monServo.attach(servoPin, angleMin, angleMax); angle = 0; monServo.write(angle); delay(1000); // pour laisser le temps au servo de se positionner monServo.detach(); // on détache le servo pour éviter les grésillements // On allume la led en vert pour prévenir que l’initialisation est terminée ampoule.begin(); // Initialise la guirlande de leds ampoule.setBrightness(luminLed); // Initialise l’instensité lumineuse light(0, 255, 0, 1); // Une 1ère fonction : on allume en vert pendant 1 seconde (R, G, B, durée en secondes) } /////////////////////////////////////////////////// //// C. BOUCLE PRINCIPALE (JOUÉE TOUT LE TEMPS) /// /////////////////////////////////////////////////// void loop() { if (analogRead(piezoPin) >= 1) { // si le piezo détecte un choc mouvServo(5, 1.5, 50); // fonction mouvement du servo moteur intégrant : // 1. l’interval de temps entre chaque mouvement // 2. le pas (la vitesse, si négatif, change de sens) // 3. la valeur d’angle à l’approche de laquelle on commence à décélérer light(255, 0, 0, 5); mouvServo(20, -1, 25); // un mouvement plus lent avec l’interval à 20, et un retour en arrière avec une valeur négative -1 en vitesse } } //////////////////////// /// D. LES FONCTIONS /// //////////////////////// // 1. Allumage led RGB void light(byte R, byte G, byte B, int duree) { // notre fonction intègre les valeurs Rouge, Vert, Bleu des Led (valeurs de 0 à 255), puis la durée ampoule.setPixelColor(0, ampoule.Color(R, G, B)); // on défini les couleurs appelée dans la fonction à la led 0 (la première de la guirlande) ampoule.show(); // on active l’allumage delay(duree * 1000); // durée exprimée en secondes (1000 millisecondes) ampoule.setPixelColor(0, ampoule.Color(0, 0, 0)); // on éteind après le delay ampoule.show(); // } // 2. mouvemnet servo moteur void mouvServo(float interval, float vitesse, int seuilApproche) { monServo.attach(servoPin, angleMin, angleMax); for (int i = 0; i <= 300; i++) { // peut importe la valeur finale de la boucle, j’en sors avant, avec des return monServo.write(angle); angle = angle + vitesse; if (angle >= 180) { // si on atteind ou dépasse 180°, alors on se met à 180° et on sort de la fonction angle = 180; monServo.detach(); return; } else if (angle <= 0) { // si on atteind ou dépasse en négatif 0°, alors on se remet à 0° et on sort de la fonction angle = 0; monServo.detach(); return; } // ici commence le test pour la décélération qui joue sur l’augmentation exponentielle de l’interval de temps if (((angle > (180 – seuilApproche)) && (vitesse > 0)) // Si on arrive vers l’angle max alors qu’on incrémente… || ((angle < seuilApproche) && (vitesse < 0))) { // … ou si on arrive vers l’angle min alors qu’on décrémente… interval = interval * 1.1; // … alors on augmente l’interval de temps entre chaque mouvement d’angle } // fin test décélération delay(interval); } } [/code]

Côté laser

Un petit peu de découpe laser pour ajuster le bazar dans la boite, créer un palonnier à aimant, et pour faire un mini-refuge-château à notre oiseau peureux. À télécharger en 2 fichiers svg zippés ici.

Pour la structure, il suffit de coller les 2 petites équerres avec de la colle à bois. On peut ensuite renter en force (ou coller) le petit aimant de 3mm dans le trou du palonnier, puis insérer cet éléments autour d’un palonnier classique vendu avec votre servo. On positionne (en force) le servo moteur au milieu de la structure en se servant de la fente rectangulaire découpée.
On peut pistocoller l’arduino-nano (pins vers le haut) en se servant des trous découpés dans le bois (il faudra peut-être « élaguer » les 6 pins centrales si ça gêne).

Idées et évolutions…

Avec tout ça, il me semble qu’il y a plein de possibilités :
• changer la scène avec d’autre décors et/ou personnages (voiture, bateau, petit chien avec sa niche…)
• jouer à créer de l’aléatoire dans la led RGB ou dans le mouvement.
• Détecter un double-choc, par rapport à un choc simple, pour proposer 2 actions différentes.
• faire s’allumer progressivement la led lorsque le personnage s’approche…
• Autoriser la détection de choc pendant un mouvement (faire de nouveau « peur » au petit oiseau alors qu’il s’apprête à sortir de son refuge…)

Plein de petits défis sympa sur cette base. À vos suggestion !

Laisser un commentaire