Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Robot Compañero Asi (Anansi)

Componentes y suministros

Arduino Nano R3
× 1
Micro-servo motor SG90
× 1
Módulo de pantalla de matriz de puntos LED rojo MAX7219
× 1
portapilas 4xAA
una batería de iones de litio 3.7 200mah también funciona
× 1
tornillos
× 1
Carcasas de plástico transparente de acrílico para moldes de bombas de baño
× 1
Adafruit Trinket - Mini microcontrolador - 5V Logic
× 1

Herramientas y máquinas necesarias

Impresora 3D (genérica)
Pistola de pegamento caliente (genérica)

Acerca de este proyecto

Historia

Este proyecto originalmente iba a ser un Xpider, de Thingiverse. Luego digo Archimedes de Alex Glow. Me voló la cabeza. Quería tanto uno. Entonces, me puse a trabajar en mi propio compañero robótico. Pensé que no soy del tipo búho y quería que mi familiar fuera especial. Entonces recordé la historia africana de Anansi la araña, embaucadora y dios de las historias. Decidí diseñar el bot con la idea de una historia, y así nació Asi (en realidad es Asi_v4, v1-3 eran prototipos).

Ensamblaje

El diseño original era un Xpider, pero lo llevé a un nivel superior, edité muchas cosas a través de muchas de ellas y las retoqué. Éstas son la mayoría de las piezas que tiene que imprimir.

El montaje se explica por sí mismo, pero aquí hay algunas fotos de todos modos.

Para la electrónica, generalmente puede colocarlos en la parte superior o inferior del cabezal (su llamada), pero el servo debe estar conectado como tal. Asegúrese de que el equipo esté colocado, por favor.

Asi está controlado por dos microcontroladores, un Trinket y un Arduino Nano. El Trinket controla el movimiento del ojo, gracias al servo gira hacia adelante y hacia atrás a intervalos aleatorios. El Arduino Nano controla el ojo. También es aleatorio cuando mira a su alrededor y, por lo general, la gente asume que los está mirando.

Tenga en cuenta que los tengo en dos placas de pruebas pequeñas que están conectadas en cadena con 4 pilas AA. (También puede usar una batería de iones de litio 3.7 200mAh. Con la batería de litio, he tenido momentos por alguna razón en los que no funciona, así que usaría dos baterías de litio separadas y las conectaría al mismo interruptor de encendido y apagado para que todo comience a la vez.)

La cabeza es solo una esfera navideña que obtuve durante las vacaciones. Di un paso atrás y lo rocié ligeramente con pintura negra en aerosol. Luego toma un poco de pegamento termofusible y pégalo a la pieza del cuello de Asi y ¡BOOM, ahí está la cabeza!

Por último, cómo lo llevo. Simplemente tomé un cable de armadura y lo ensarté a través de los orificios en la parte inferior de Asi, y los envolví en mi mochila de mi mochila.

Código

  • Asi Eye
  • Cuello Asi con abalorio
Asi Eye Arduino
el código para Asi eye
 #include  // Siempre tenemos que incluir la librería LedControl # include "LedControl.h" / * Crear objeto LetControl, definir conexiones pin Tenemos 2 MAX72XX para ojos. * / # 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); // rotaciónbool rotateMatrix0 =falso; // rotar la matriz 0 180 grados rotateMatrix1 =false; // rotar 1 matriz 180 grados // definir globo ocular sin byte de pupila eyeBall [8] ={B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B01111110, B00111100}; byte eyePupil =B11100111; // almacena el estado actual de LEDsbyte eyeCurrent [8]; int currentX; int currentY; int cntLoop =0; int cntEffect =0; // posiciones mínimas y máximas # definir MIN -2 # definir MAX 2 // retrasos # definir DELAY_BLINK 40 // realizar un efecto cada # de iteraciones de bucle, 0 para deshabilitar # definir EFFECT_ITERATION 4 / * Arduino setup * / void setup () {// MAX72XX está en modo de ahorro de energía al inicio, tenemos que hacer una llamada de activación lc.shutdown (0, false); lc.shutdown (1, falso); // establece el brillo a bajo lc.setIntensity (0,1); lc.setIntensity (1,1); // limpia ambos módulos lc.clearDisplay (0); lc.clearDisplay (1); // Prueba de LED // Byte de línea vertical b =B10000000; para (int c =0; c <=7; c ++) {para (int r =0; r <=7; r ++) {setRow (0, r, b); setRow (1, r, b); } b =b>> 1; retraso (50); } // módulo completo b =B11111111; para (int r =0; r <=7; r ++) {setRow (0, r, b); setRow (1, r, b); } retraso (500); // limpia ambos módulos lc.clearDisplay (0); lc.clearDisplay (1); retraso (500); // semilla aleatoria randomSeed (analogRead (0)); // ojos centrales, parpadeo loco displayEyes (0, 0); retraso (2000); blinkEyes (verdadero, falso); blinkEyes (falso, verdadero); delay (1000);} / * Arduino loop * / void loop () {// mover a una posición aleatoria, esperar un tiempo aleatorio moveEyes (random (MIN, MAX + 1), random (MIN, MAX + 1), 50); retraso (aleatorio (5, 7) * 500); // ¿Parpadea el tiempo? si (aleatorio (0, 5) ==0) {retraso (500); blinkEyes (); retraso (500); } // tiempo de efecto? if (EFFECT_ITERATION> 0) {cntLoop ++; if (cntLoop ==EFFECT_ITERATION) {cntLoop =0; if (cntEffect> 6) cntEffect =0; switch (cntEffect) {caso 0:// ojos cruzados crossEyes (); retraso (1000); descanso; caso 1:// giro redondo roundSpin (2); retraso (1000); descanso; caso 2:// giro loco crazySpin (2); retraso (1000); descanso; caso 3:// meth eyes methEyes (); retraso (1000); descanso; caso 4:// ojo vago lazyEye (); retraso (1000); descanso; caso 5:// parpadeo loco blinkEyes (verdadero, falso); blinkEyes (falso, verdadero); retraso (1000); descanso; caso 6:// glow glowEyes (3); retraso (1000); descanso; predeterminado:descanso; } cntEffect ++; }}} / * Este método parpadea ambos ojos * / void blinkEyes () {blinkEyes (true, true);} / * Este método parpadea según los parámetros proporcionados * / void blinkEyes (boolean blinkLeft, boolean blinkRight) {// blink ? if (! blinkLeft &&! blinkRight) return; // cierra los párpados para (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); } retraso (DELAY_BLINK); } // párpados abiertos para (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]); } retraso (DELAY_BLINK); }} / * Este método mueve los ojos a la posición central, luego se mueve horizontalmente con envoltura alrededor de los bordes. * / Void crazySpin (int times) {if (times ==0) return; moveEyes (0, 0, 50); retraso (500); fila de bytes =eyePupil; for (int t =0; t > 1; fila =fila | B10000000; setRow (0, 3, fila); setRow (1, 3, fila); setRow (0, 4, fila); setRow (1, 4, fila); retraso (50); si (t ==0) retraso ((5-i) * 10); // aumenta la demora en el primer desplazamiento (efecto de aceleración)} // gira de R al centro para (int i =0; i <5; i ++) {fila =fila>> 1; si (i> =2) fila =fila | B10000000; setRow (0, 3, fila); setRow (1, 3, fila); setRow (0, 4, fila); setRow (1, 4, fila); retraso (50); si (t ==(veces-1)) retraso ((i + 1) * 10); // aumenta el retraso en el último desplazamiento (efecto de ralentización)}}} / * Este método cruza los ojos * / void crossEyes () {moveEyes (0, 0, 50); retraso (500); byte pupilR =eyePupil; byte pupilL =eyePupil; // mueve las pupilas juntas para (int i =0; i <2; i ++) {pupilR =pupilR>> 1; pupilR =pupilR | B10000000; pupilL =pupilL <<1; pupilL =pupilL | B1; setRow (0, 3, pupilR); setRow (1, 3, pupilL); setRow (0, 4, pupilR); setRow (1, 4, pupilL); retraso (100); } retraso (2000); // mueve las pupilas al centro para (int i =0; i <2; i ++) {pupilR =pupilR <<1; pupilR =pupilR | B1; pupilL =pupilL>> 1; pupilL =pupilL | B10000000; setRow (0, 3, pupilR); setRow (1, 3, pupilL); setRow (0, 4, pupilR); setRow (1, 4, pupilL); retraso (100); }} / * Este método muestra el globo ocular con la pupila desplazada por los valores X, Y desde la posición central. El rango válido de X e Y es [MIN, MAX] Ambos módulos LED mostrarán ojos idénticos * / void displayEyes (int offsetX, int offsetY) {// asegúrese de que las compensaciones estén en rangos válidos offsetX =getValidValue (offsetX); offsetY =getValidValue (offsetY); // calcula los índices para las filas de la pupila (realiza el desplazamiento Y) int row1 =3 - offsetY; int fila2 =4 - offsetY; // definir byte de fila de pupila pupilRow =eyePupil; // realiza el desplazamiento X // cambio de bit y completa el nuevo bit con 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; }} // fila de pupila no puede tener 1s donde eyeBall tiene 0s byte pupilRow1 =pupilRow &eyeBall [fila1]; byte pupilRow2 =pupilRow &eyeBall [fila2]; // mostrar en la matriz LCD, actualizar a eyeCurrent para (int r =0; r <8; r ++) {if (r ==fila1) {setRow (0, r, pupilRow1); setRow (1, r, pupilRow1); eyeCurrent [r] =pupilRow1; } más si (r ==fila2) {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]; }} // actualizar X e Y actuales currentX =offsetX; currentY =offsetY;} / * Este método corrige el valor de coordenadas proporcionado * / int getValidValue (int value) {if (value> MAX) return MAX; de lo contrario, si (valor  =1; i--) {lc.setIntensity (0, i); lc.setIntensity (1, i); retraso (25); } retraso (150); }} / * Este método mueve los ojos al centro, hacia afuera y luego de regreso al centro * / void methEyes () {moveEyes (0, 0, 50); retraso (500); byte pupilR =eyePupil; byte pupilL =eyePupil; // mover las pupilas hacia afuera para (int i =0; i <2; i ++) {pupilR =pupilR <<1; pupilR =pupilR | B1; pupilL =pupilL>> 1; pupilL =pupilL | B10000000; setRow (0, 3, pupilR); setRow (1, 3, pupilL); setRow (0, 4, pupilR); setRow (1, 4, pupilL); retraso (100); } retraso (2000); // mueve las pupilas al centro para (int i =0; i <2; i ++) {pupilR =pupilR>> 1; pupilR =pupilR | B10000000; pupilL =pupilL <<1; pupilL =pupilL | B1; setRow (0, 3, pupilR); setRow (1, 3, pupilL); setRow (0, 4, pupilR); setRow (1, 4, pupilL); retraso (100); }} / * Este método mueve ambos ojos desde la posición actual a la nueva posición * / void moveEyes (int newX, int newY, int stepDelay) {// establece la posición actual como posición inicial int startX =currentX; int startY =currentY; // corregir nuevos valores X Y no válidos newX =getValidValue (newX); newY =getValidValue (newY); // eval pasos int stepsX =abs (currentX - newX); int pasosY =abs (actualY - nuevoY); // Necesito cambiar al menos una posición if ((stepsX ==0) &&(stepsY ==0)) return; // evalúa la dirección del movimiento, # de pasos, cambia por paso X Y, realiza el movimiento int dirX =(newX> =currentX)? 1:-1; int dirY =(newY> =currentY)? 1:-1; int pasos =(pasosX> pasosY)? stepsX:stepsY; int intX, intY; flotar changeX =(flotar) pasosX / (flotar) pasos; flotar cambioY =(flotar) pasosY / (flotar) pasos; for (int i =1; i <=pasos; i ++) {intX =startX + round (changeX * i * dirX); intY =startY + round (changeY * i * dirY); displayEyes (intX, intY); delay (stepDelay); }} / * Este método baja y sube la pupila derecha solamente * / void lazyEye () {moveEyes (0, 1, 50); retraso (500); // pupila inferior izquierda lentamente para (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); retraso (150); } retraso (1000); // levanta la pupila izquierda rápidamente para (int i =0; i <3; i ++) {setRow (1, 4-i, eyeBall [4-i] &eyePupil); setRow (1, 5-i, eyeBall [5-i] y eyePupil); setRow (1, 6-i, eyeBall [6-i]); retraso (25); }} / * Este método hace girar las pupilas en el sentido de las agujas del reloj * / void roundSpin (int times) {if (times ==0) return; moveEyes (2, 0, 50); retraso (500); for (int i =0; i  
Asi Neck con abalorio Arduino
esto es lo que uso para asegurarme de que el cuello de Asi se mueva hacia adelante y hacia atrás
 // Parámetros de servo. El pin DEBE ser 1 o 4 en una baratija. La posición del servo // se especifica en tics de contador / temporizador sin procesar (1 tick =0,128 milisegundos) .// El tiempo de pulso del servo suele ser de 1-2 ms, pero puede variar ligeramente entre // servos, por lo que es posible que deba modificar estos límites para coincidir con su realidad. # definir SERVO_PIN 4 // Los pines 1 o 4 son compatibles con Trinket # definir SERVO_MIN 4 // ~ pulso de 1 ms # definir SERVO_MAX 26 // ~ pulso de 2 ms Adafruit_TiCoServo servo; void setup (void) {#if (F_CPU ==16000000L) // El trinket de 16 MHz requiere la configuración de preescala para la sincronización correcta. // ¡Esto DEBE hacerse ANTES de servo.attach ()! clock_prescale_set (clock_div_1); # endif servo.attach (SERVO_PIN); pinMode (LED_PIN, SALIDA); digitalWrite (LED_PIN, HIGH);} uint32_t lastLookTime =0; // Hora del último bucle void de vuelta de cabeza (void) {unsigned long t =millis (); // Hora actual // Si ha pasado más de 1/2 segundo desde el último giro de cabeza ... if ((t - lastLookTime)> 500) {if (random (10) ==0) {// Hay un 1- probabilidad en-10 ... // ... de mover aleatoriamente la cabeza en una nueva dirección:servo.write (random (SERVO_MIN, SERVO_MAX)); lastLookTime =t; // Guarde el tiempo de giro de cabeza para referencia futura}} // No relacionado con la verificación de giro de cabeza, if (random (10) ==0) {// hay una probabilidad de 1 en 10 ... // .. . de un "parpadeo":digitalWrite (LED_PIN, LOW); // El LED se apaga delay (random (50, 250)); // por un breve momento aleatorio digitalWrite (LED_PIN, HIGH); // luego vuelve a ENCENDER} delay (100); // Repite el bucle () unas 10 veces / segundo} 

Piezas y carcasas personalizadas

la pieza del extremo de la pierna real se olvidó de agregar el engranaje giratorio para el servo, generalmente imprimí y coloqué el accesorio del servo en el medio y luego lo atornillé en el cuerpo del servo de Asit La parte inferior de Asithe peice del muslo a la junta de Asileg El tornillo que utilizo para unir las piernas de Asi a la Tuerca que va con el tornillo, el servo de engranajes que se usa para hacer girar la cabeza de Asi, recomendaría usar una pieza de servo y colocarla en el medio, la pieza del medio de As, el soporte del servo para la placa del cuello del GearAsi, aquí es donde la esfera acrílica se pega a la cuello

Esquemas

el circuito que usé para Asi Neck estos son los que usé para que Asi comenzara. puede conectarlos en cadena para alimentarlos a ambos desde pequeñas placas de circuito

Proceso de manufactura

  1. Cómo hacer una plataforma de robot Arduino + Raspberry Pi
  2. Robot de caja de CD Raspberry Pi
  3. PiCy - ¡El diminuto robot con tecnología Raspberry Pi!
  4. Robot de alarma rodante
  5. Crea un robot Creeper de Minecraft
  6. Arquímedes:El búho robot con IA
  7. Abrir CV Robot
  8. Robot ROS
  9. Robot Pi simple
  10. ¿Qué es un robot de bebidas?
  11. Robots y fabricación de baterías:una conexión positiva