Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Compagnon robot Asi (Anansi)

Composants et fournitures

Arduino Nano R3
× 1
Micro-servomoteur SG90
× 1
Module d'affichage matriciel à LED rouge MAX7219
× 1
Support de 4 piles AA
une batterie lithium-ion 3.7 200mah fonctionne également
× 1
vis
× 1
Coquilles de moule de bombe de bain en plastique acrylique transparent
× 1
Adafruit Trinket - Mini Microcontrôleur - Logique 5V
× 1

Outils et machines nécessaires

Imprimante 3D (générique)
Pistolet à colle chaude (générique)

À propos de ce projet

Histoire

Ce projet devait à l'origine être un Xpider, de Thingiverse. Ensuite, je dis Archimède d'Alex Glow. Cela m'a époustouflé. J'en voulais un tellement. Donc, j'ai commencé à travailler sur mon propre compagnon robotique. Je pensais que je n'étais pas du genre chouette et je voulais que mon familier soit spécial. Puis je me suis souvenu de l'histoire africaine d'Anansi l'araignée, le filou et le dieu des histoires. J'ai décidé de concevoir le bot avec l'idée d'une histoire, et c'est ainsi qu'Asi est né (c'est en fait Asi_v4, les v1-3 étaient des prototypes).

Assemblage

Le design original était un Xpider, mais je l'ai pris d'un cran, j'ai modifié beaucoup de choses à travers beaucoup de choses à la porte et vous savez, j'ai bricolé. Ce sont la plupart des pièces que vous devez imprimer.

L'assemblage est assez explicite mais voici quand même quelques photos.

Pour l'électronique, vous pouvez généralement les mettre en haut ou en bas de la tête (votre choix), mais le servo doit être fixé comme tel. Assurez-vous que l'équipement est dessus, s'il vous plaît.

Asi est contrôlé par deux microcontrôleurs, un Trinket et un Arduino Nano. Le Trinket contrôle le mouvement de l'œil, grâce au servo, il tourne d'avant en arrière à des intervalles aléatoires. L'Arduino Nano contrôle l'œil. C'est aussi aléatoire lorsqu'il regarde autour de lui et ainsi, les gens supposent généralement qu'il les regarde.

Remarque, je les ai sur deux petites planches à pain qui sont connectées en guirlande avec 4 piles AA. (Vous pouvez également utiliser une batterie lithium-ion 3,7 200 mAh. Avec la batterie li-on, j'ai eu des moments pour une raison quelconque où cela ne fonctionnait pas, donc j'utiliserais deux batteries au lithium séparées et les attacherais au même interrupteur marche/arrêt donc tout commence en même temps.)

La tête est juste une sphère de Noël que j'ai reçue pendant les vacances. J'ai pris du recul et l'ai légèrement pulvérisé avec de la peinture en aérosol noire. Ensuite, prenez de la colle chaude et collez-la sur le morceau de cou d'Asi et BOUM voilà la tête !

Enfin, comment je le porte. J'ai juste pris du fil d'armature et l'ai enfilé à travers les trous de la partie inférieure d'Asi, et je les ai enveloppés sur mon sac à dos.

Code

  • Asi Eye
  • Asi Neck avec bibelot
Asi Eye Arduino
le code pour Asi eye
#include //Nous devons toujours inclure la bibliothèque LedControl#include "LedControl.h"/* Créer l'objet LetControl, définir les connexions des broches Nous avons 2 MAX72XX pour les yeux. */#define PIN_EYES_DIN 12#define PIN_EYES_CS 11#define PIN_EYES_CLK 10LedControl lc =LedControl(PIN_EYES_DIN, PIN_EYES_CLK, PIN_EYES_CS, 2);// rotationbool rotateMatrix0 =false; // fait pivoter la matrice 0 de 180 degbool rotateMatrix1 =false; // fait pivoter 1 matrice de 180 degrés // définit le globe oculaire sans octet de pupille eyeBall[8]={ B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B01111110, B00111100};byte eyePupil =B11100111; // stocke l'état actuel de LEDsbyte eyeCurrent[8];int currentX;int currentY;int cntLoop =0;int cntEffect =0;// positions min et max#define MIN -2#define MAX 2// delays#define DELAY_BLINK 40// effectuer un effet tous les # d'itérations de boucle, 0 pour désactiver #define EFFECT_ITERATION 4/* Arduino setup*/void setup() { // MAX72XX est en mode d'économie d'énergie au démarrage, nous devons faire un appel de réveil lc.shutdown(0,false); lc.shutdown(1,false); // définit la luminosité sur faible lc.setIntensity(0,1) ; lc.setIntensity(1,1) ; // efface les deux modules lc.clearDisplay(0); lc.clearDisplay(1); // Test LED // octet de ligne verticale b =B10000000; for (int c=0; c<=7; c++) { for (int r=0; r<=7; r++) { setRow(0, r, b); setRow(1, r, b); } b =b>> 1; retard (50); } // module complet b =B11111111; for (int r=0; r<=7; r++) { setRow(0, r, b); setRow(1, r, b); } délai (500); // efface les deux modules lc.clearDisplay(0); lc.clearDisplay(1); retard (500); // graine aléatoire randomSeed(analogRead(0)); // centre des yeux, clignement fou displayEyes(0, 0); retard (2000); blinkEyes(vrai, faux); blinkEyes(faux, vrai); delay(1000);}/* boucle Arduino*/void loop() { // se déplacer vers une position aléatoire, attendre un temps aléatoire moveEyes(random(MIN, MAX + 1), random(MIN, MAX + 1), 50); retard (aléatoire (5, 7) * 500); // temps de clignotement ? if (aléatoire (0, 5) ==0) { délai (500); cligner des yeux(); retard (500); } // temps d'effet ? if (EFFECT_ITERATION> 0) { cntLoop++ ; if (cntLoop ==EFFECT_ITERATION) { cntLoop =0; si (cntEffect> 6) cntEffect =0 ; switch(cntEffect) { case 0 :// croise les yeux crossEyes(); retard(1000); Pause; cas 1 :// tour rond roundSpin(2); retard(1000); Pause; cas 2 :// spin fou crazySpin(2); retard(1000); Pause; cas 3 :// yeux meth methEyes(); retard(1000); Pause; case 4:// œil paresseux lazyEye(); retard(1000); Pause; case 5:// clignement fou blinkEyes(true, false); blinkEyes(faux, vrai); retard(1000); Pause; cas 6 :// glowEyes(3) ; retard(1000); Pause; par défaut :pause ; } cntEffet++; } }}/* Cette méthode fait clignoter les deux yeux*/void blinkEyes(){ blinkEyes(true, true);}/* Cette méthode fait clignoter les yeux selon les paramètres fournis*/void blinkEyes(boolean blinkLeft, boolean blinkRight){ // blink ? if (!blinkLeft &&!blinkRight) return; // fermer les paupières pour (int i=0; i<=3; i++) { if (blinkLeft) { setRow(0, i, 0); setRow (0, 7-i, 0); } if (blinkRight) { setRow(1, i, 0); setRow(1, 7-i, 0); } retard(DELAY_BLINK); } // Ouvrir les paupières pour (int i=3; i>=0; i--) { if (blinkLeft) { setRow(0, i, eyeCurrent[i]); setRow(0, 7-i, eyeCurrent[7-i]); } if (blinkRight) { setRow(1, i, eyeCurrent[i]); setRow(1, 7-i, eyeCurrent[7-i]); } retard(DELAY_BLINK); }}/* Cette méthode déplace les yeux vers la position centrale, puis se déplace horizontalement avec un enroulement autour des bords.*/void crazySpin(int times){ if (times ==0) return; moveEyes(0, 0, 50); retard (500); ligne d'octets =eyePupil; for (int t=0; t> 1; ligne =ligne | B10000000 ; setRow (0, 3, ligne); setRow(1, 3, ligne); setRow (0, 4, ligne); setRow(1, 4, ligne); retard (50); si (t ==0) retard((5-i)*10) ; // augmente le délai au 1er défilement (effet d'accélération) } // tourne de R au centre pour (int i=0; i<5; i++) { row =row>> 1; si (i>=2) ligne =ligne | B10000000 ; setRow (0, 3, ligne); setRow(1, 3, ligne); setRow (0, 4, ligne); setRow(1, 4, ligne); retard (50); si (t ==(fois-1)) retard ((i+1)*10) ; // augmente le délai au dernier défilement (effet de ralentissement) } }}/* Cette méthode traverse les yeux*/void crossEyes(){ moveEyes(0, 0, 50); retard (500); octet pupilleR =eyePupil; octet pupilL =eyePupil; // déplace les élèves ensemble pour (int i=0; i<2; i++) { pupilR =pupilR>> 1; élèveR =élèveR | B10000000 ; élèveL =élèveL <<1 ; élèveL =élèveL | B1 ; setRow(0, 3, pupilR); setRow(1, 3, pupilL); setRow (0, 4, pupilR); setRow(1, 4, pupilL); retard (100); } retard (2000); // replace les élèves au centre pour (int i=0; i<2; i++) { pupilR =pupilR <<1; élèveR =élèveR | B1 ; élèveL =élèveL>> 1 ; élèveL =élèveL | B10000000 ; setRow(0, 3, pupilR); setRow(1, 3, pupilL); setRow (0, 4, pupilR); setRow(1, 4, pupilL); retard (100); }}/* Cette méthode affiche le globe oculaire avec la pupille décalée par les valeurs X, Y à partir de la position centrale. La plage X et Y valide est [MIN,MAX] Les deux modules LED afficheront des yeux identiques */void displayEyes(int offsetX, int offsetY) { // assurez-vous que les décalages sont dans des plages valides offsetX =getValidValue(offsetX); offsetY =getValidValue(offsetY); // calcule les index pour les lignes pupillaires (exécute le décalage Y) int row1 =3 - offsetY; int row2 =4 - offsetY; // définit l'octet de la ligne de la pupille pupilRow =eyePupil; // effectuer un décalage X // décalage de bit et remplir le nouveau bit avec 1 if (offsetX> 0) { for (int i=1; i<=offsetX; i++) { pupilRow =pupilRow>> 1; pupilRow =pupilRow | B10000000 ; } } else if (offsetX <0) { for (int i=-1; i>=offsetX; i--) { pupilRow =pupilRow <<1; pupilRow =pupilRow | B1 ; } } // la ligne pupille ne peut pas contenir de 1 où eyeBall a un octet 0 pupilRow1 =pupilRow &eyeBall[row1]; octet pupilRow2 =pupilRow &eyeBall[row2]; // affichage sur la matrice LCD, mise à jour vers eyeCurrent for(int r=0; r<8; r++) { if (r ==row1) { setRow(0, r, pupilRow1); setRow(1, r, pupilRow1) ; eyeCurrent[r] =pupilRow1; } else if (r ==row2) { setRow(0, r, pupilRow2) ; setRow(1, r, pupilRow2) ; eyeCurrent[r] =pupilRow2; } else { setRow(0, r, eyeBall[r]); setRow(1, r, eyeBall[r]); eyeCurrent[r] =eyeBall[r]; } } // met à jour X et Y courants currentX =offsetX; currentY =offsetY;}/* Cette méthode corrige la valeur de coordonnée fournie*/int getValidValue(int value){ if (value> MAX) return MAX; sinon si (valeur =1; i--) { lc.setIntensity(0,i); lc.setIntensity(1,i); retard (25); } délai(150); }}/* Cette méthode déplace les yeux vers le centre, vers l'extérieur puis vers le centre*/void methEyes(){ moveEyes(0, 0, 50); retard (500); octet pupilleR =eyePupil; octet pupilL =eyePupil; // déplace les élèves pour (int i=0; i<2; i++) { pupilR =pupilR <<1; élèveR =élèveR | B1 ; élèveL =élèveL>> 1 ; élèveL =élèveL | B10000000 ; setRow(0, 3, pupilR); setRow(1, 3, pupilL); setRow (0, 4, pupilR); setRow(1, 4, pupilL); retard (100); } retard (2000); // replace les élèves au centre pour (int i=0; i<2; i++) { pupilR =pupilR>> 1; élèveR =élèveR | B10000000 ; élèveL =élèveL <<1 ; élèveL =élèveL | B1 ; setRow(0, 3, pupilR); setRow(1, 3, pupilL); setRow (0, 4, pupilR); setRow(1, 4, pupilL); retard (100); }}/* Cette méthode déplace les deux yeux de la position actuelle à la nouvelle position*/void moveEyes(int newX, int newY, int stepDelay){ // définit la position actuelle comme position de départ int startX =currentX; int startY =currentY; // corrige les nouvelles valeurs X Y invalides newX =getValidValue(newX); newY =getValidValue(newY); // eval step int stepX =abs(currentX - newX); int étapesY =abs(currentY - newY); // besoin de changer au moins une position if ((stepsX ==0) &&(stepsY ==0)) return; // eval direction du mouvement, nombre d'étapes, changement par étape X Y, effectuer le déplacement int dirX =(newX>=currentX) ? 1 :-1 ; int dirY =(newY>=currentY) ? 1 :-1 ; int étapes =(étapesX> étapesY) ? pasX :pasY; int intX, intY; float changeX =(float)stepsX / (float)steps ; float changeY =(float)stepsY / (float)steps ; for (int i=1; i<=steps; i++) { intX =startX + round(changeX * i * dirX); intY =startY + round(changeY * i * dirY); displayEyes(intX, intY); retard(stepDelay); }}/* Cette méthode abaisse et élève uniquement la pupille droite*/void lazyEye(){ moveEyes(0, 1, 50); retard (500); // pupille inférieure gauche lentement pour (int i=0; i<3; i++) { setRow(1, i+2, eyeBall[i+2]); setRow(1, i+3, eyeBall[i+3] &eyePupil); setRow(1, i+4, eyeBall[i+4] &eyePupil); retard (150); } délai(1000); // élève rapidement la pupille gauche pour (int i=0; i<3; i++) { setRow(1, 4-i, eyeBall[4-i] &eyePupil); setRow(1, 5-i, eyeBall[5-i] &eyePupil); setRow(1, 6-i, eyeBall[6-i]); retard (25); } }/* Cette méthode fait tourner les pupilles dans le sens des aiguilles d'une montre*/void roundSpin(int times){ if (times ==0) return; moveEyes(2, 0, 50); retard (500); for (int i=0; i 
Asi Neck avec bibelot Arduino
c'est ce que j'utilise pour m'assurer que le cou Asi se déplace d'avant en arrière
 // Paramètres du servo. La broche DOIT être 1 ou 4 sur un bijou. La position du servo// est spécifiée en ticks bruts de minuterie/compteur (1 tick =0,128 millisecondes).// La durée d'impulsion du servo est généralement de 1 à 2 ms, mais peut varier légèrement entre// les servos, vous devrez donc peut-être ajuster ces limites pour correspond à votre réalité.#define SERVO_PIN 4 // Les broches 1 ou 4 sont prises en charge sur Trinket#define SERVO_MIN 4 // ~1 ms pulse#define SERVO_MAX 26 // ~2 ms pulse Adafruit_TiCoServo servo ; void setup(void) {#if (F_CPU ==16000000L) // 16 MHz Trinket nécessite le réglage de la pré-échelle pour une synchronisation correcte. // Cela DOIT être fait AVANT servo.attach()! clock_prescale_set(clock_div_1);#endif servo.attach(SERVO_PIN); pinMode(LED_PIN, SORTIE); digitalWrite(LED_PIN, HIGH);} uint32_t lastLookTime =0; // Heure du dernier tour de tête void loop(void) { unsigned long t =millis(); // Heure actuelle // Si plus d'une demi-seconde s'est écoulée depuis le dernier tour de tête... if((t - lastLookTime)> 500) { if(random(10) ==0) { // Il y a un 1- chance sur 10... // ...de déplacer aléatoirement la tête dans une nouvelle direction :servo.write(random(SERVO_MIN, SERVO_MAX)); lastLookTime =t; // Enregistre le temps de rotation des têtes pour référence future } } // Sans rapport avec le contrôle de rotation des têtes, if(random(10) ==0) { // il y a 1 chance sur 10... // .. .d'un "clignement des yeux":digitalWrite(LED_PIN, LOW); // La LED s'éteint delay(random(50, 250)); // pour un court instant aléatoire digitalWrite(LED_PIN, HIGH); // puis retour ON } delay(100); // Répéter loop() environ 10 fois/seconde}

Pièces et boîtiers personnalisés

la pièce d'extrémité de la jambe réelle a oublié d'ajouter l'engrenage de retournement pour le servo, j'ai généralement imprimé et ajusté la fixation du servo au milieu puis la visser sur le servole corps d'Asithe le bas de la cuisse d'Asithe au joint d'Asilegla vis que j'utilise pour joindre les jambes d'Asi l'écrou qui va avec la vis le servo de vitesse utilisé pour faire tourner la tête d'Asi, il est recommandé d'utiliser une pièce de servo et de la poser au milieu de la pièce médiane d'Asithe support du servo pour la plaque de cou asi GearAsi, c'est là que la sphère acrylique est collée à la cou

Schémas

le circuit que j'ai utilisé pour Asi Neck ce sont ceux que j'ai utilisés pour démarrer Asi. vous pouvez les connecter en guirlande pour les alimenter tous les deux à partir de petits circuits imprimés

Processus de fabrication

  1. Comment créer une plate-forme robotique Arduino+Raspberry Pi
  2. Robot boîtier CD Raspberry Pi
  3. PiCy – Le petit robot alimenté par Raspberry Pi !
  4. Robot d'alarme roulante
  5. Créer un robot Minecraft Creeper
  6. Archimedes :The AI ​​Robot Owl
  7. Open CV Robot
  8. Robot ROS
  9. Robot Pi simple