lunes, 25 de enero de 2021

Kuribot - Robot bípedo





KuriBot es un robot de tipo bípedo que tu mismo puedes construir. Tiene una altura de 20 cm., utiliza cuatro servos MG995, una placa Arduino, una placa de Bluetooth y un led matrix 8x8. 

En este Blog encontraras el detalle de la construcción, el detalle de todos los elementos, el despiece así como el programa para Arduino que hemos desarrollado para su control y los archivos STL para imprimir en tu impresora 3D todas las piezas de este robot. 

El robot se gobierna con una aplicación Android que puedes descargar en Google Play, cuesta menos de un euro, pero puede ser gobernado por cualquier App pues encontraras en este blog las claves (ordenes alfabéticas) para controlar por Bluetooth en el apartado dedicado a programación, en el propio programa encontraras todas las claves necesarias.

KuriBot se puede controlar de tres formas diferentes:

- Mediante controles de movimientos, es posible crear series para crear programación de movimientos
- Mediante control por voz
- Gestos predefinidos, 

KuriBot es un estupendo medio para introducirse en la programación de movimientos. Se pueden guardar hasta cinco series de movimientos diferentes en la memoria de la App, por ejemplo puedes crear un programa para que realice un baile definido por ti. Desde la aplicación puedes acceder al manual donde se explican todos los detalles.

LAS PIEZAS DEL ROBOT


Para la instalación de los servos se utilizan estas cinco piezas, el montaje es relativamente sencillo. Debes utilizar tornillos de métrica 3.
Necesitaras cuatro servos y un brazo circular para cada servo.






Debes tener la precaución, antes de instalar los cuatro servos, de colocar su posición a 90 grados.







A continuación colocaremos el cuerpo nº 1 



El soporte de los servos dispone de unas ranuras para insertar las tuercas de métrica 3
 

Sobre el cuerpo nº1 instalaremos el soporte de la placa Arduino. Es posible instalar una placa Uno Arduino o, como en este caso, un shield para una placa Nano












Instalaremos una placa Bluetooth y una led matriz 8 x 8






Y finalmente instalaremos el cuerpo nº 2 que a su vez da soporte al led matriz 8x8


He utilizado una pila de Lipo de 7,4 V y 2000 mAh para alimentar directamente la placa, suficiente para dar energía a los cuatro servos. 


ARCHIVOS STL 

El robot tiene un total de nueve piezas

Dos pies




Dos piernas



Soporte de servos



Cuerpo nº1



Soporte de cuerpos



Soporte Bluetooth



Cuerpo nº 2





CONEXIONES ELECTRONICAS

Para la conexión de los servos debes colocar tu robot enfrente de ti como en esta imagen 
de tal forma que el servo nº 1 será el correspondiente a la cadera de la izquierda, el servo nº 2 será el de la cadera derecha, el servo nº 3 será el del pie de la izquierda y el servo ºn 4 será el del pie de la derecha.

Utilizo la librería  <VarSpeedServo.h>
Los pines de conexión de Arduino son:
 
Servo nº 1 pin nº  6
Servo nº 2 pin nº  10
Servo nº 3 pin nº  9
Servo nº 4 pin nº  11


Para la conexión del Bluetooth no utilizo los pines clásicos RX y TX de la placa Arduino ya que impide actualizar la programación si están conectados, por tanto utilizo una la librería  <SoftwareSerial.h> y conecto el pin TX de la placa Bluetooth en el pin nº 7 de Arduino y el pin RX en el pin 8

Para el el led de 8x8 he utilizado la librería <LedControlMS.h>, conectando los pines de la siguiente forma:
El pin  DIN lo conecto en el pin nº  4 de Arduino
El pin  CLK en el pin nº  3 de Arduino
El pin  CS en el pin nº 5 de Arduino
Existen varias librerías para utilizar las matriz de leds 8x8, yo he escogido esta por la sencillez de su manejo y porque puedo crear diferentes dibujos mediante series binarias, es muy sencillo, en el futuro tengo previsto hacer un tutorial sobre esta matriz. A modo de ejemplo, si quiero dibujar un corazon escribire esta serie de ceros y unos

00000000
01100110
11111111
11111111
01111110
00111100
00011000 
00000000 

PROGRAMACION 

Este es el sketch completo de Kuribot, selecciona y copia el texto de color  azul y pegalo un un sketch nuevo de tu Arduino




/*
KURIBOT V3
Robot bípedo
@GERMAN ALONSO - Kuritre Game 2020
SE UTILIZAN 9 VALORES PARA CADA SERVO SEPARADOS EN 
15 GRADOS ENTRE POSICIONES. SE UTILIZAN TODAS LAS LETRAS MINUSCULAS Y MAYUSCULAS DEL ALFABETO
EXCEPTUANDO LA LETRA Ñ, QUEDAN LIBRES LA W (MINUSCULA) W (MAYUSCULA) Z (MAYUSCULA)
SE UTILIZAN LOS NUMEROS 1-2-3-4 PARA VELOCIDADES 

UTILIZAR LA APP : KURIBOT
Se utilizan los códigos de control de esta aplicación 


BLUETOOTH
Conexion de cables
         MODULO   ARDUINO
Verde     VCC     5V
Azul      GND     GND
Morado    TXD     RX
Gris      RXD     TX

SERVOS
Conexiones Servo 180º 55: 
Marron en el pin GND
Rojo en el pin 5v
Amarillo en el pin de control 

     -----------------
     -    0     0    -
     -               -
 1   -----------------  2
        -         -
        -         -        -         -
      ---         ---
       3           4 
Notas:
La libreria VarSpeedServo asigna a cada servo tres valores: 
1: Giro valores entre 0 y 180. 
2: Velocidad, valores entre 1 y 255 velocidad.  
3: Esperar a completar las instrucciones anteriores, valores de verdadero (true) o falso (false)
 
*/



////////////////////////////////////////////////////////////////////////////////////////////////////////MATRIZ LED
#include "LedControlMS.h" 
LedControl lc=LedControl(4,3,5,1); 
// Los numeros se refieren a que pin de ARDUINO tienes en cada uno de los terminales
// Para el DIN, 3 para el CLK, 5 para el CS y el 1 se refiere a la asignacion de la matriz

byte CORAZON[] = {
B00000000,
B01100110,
B11111111,
B11111111,
B01111110,
B00111100,
B00011000, 
B00000000};

byte GO[] = {
B00000000,
B00000000,
B11100111,
B10000101,
B10000101,
B10100101,
B10100101,
B11100111};

byte RIE[] = {
B11000011,
B11000011,
B00011000,
B00011000,
B10000001,
B11000011,
B01111110,
B00111100};

byte STOP[] = {
B11000011,
B11000011,
B00011000,
B00011000,
B00000000,
B00000000,
B01111110,
B00000000};

byte IZQ[] = {
B00011000,
B00001100,
B00000110,
B11111111,
B11111111,
B00000110,
B00001100,
B00011000};

byte DER[] = {
B00011000,
B00110000,
B01100000,
B11111111,
B11111111,
B01100000,
B00110000,
B00011000};

byte ATRAS[] = {
B00011000,
B00111100,
B01111110,
B00011000,
B00001100,
B00000110,
B00000011,
B11111111};

//Cara UNO
byte UNO[] = {
B00001000,
B00011000,
B00111000,
B01011000,
B00011000,
B00011000,
B00011000,
B00011000};

//Cara DOS
byte DOS[] = {
B00011100,
B00100010,
B00100010,
B00000100,
B00001000,
B00010000,
B00100000,
B00111110};

//Cara TRES
byte TRES[] = {
B00011100,
B00100010,
B00100011,
B00001110,
B00001110,
B00100011,
B00100010,
B00011100};

//Cara CUATRO
byte CUATRO[] = {
B00100010,
B00100010,
B00100010,
B00111110,
B00000110,
B00000110,
B00000110,
B00000110};

//Conectado
byte Conectado[] = {
B00000000,
B00000000,
B00111100,
B00100100,
B00111100,
B00000000,
B00000000,
B00000000};
///////////////////////////////////////////////////////////////////////////SERVOS
#include <VarSpeedServo.h> 

//////////Crear objeto servo para controlar un servo
//////////Se pueden crer un máximo de ocho objetos servo
VarSpeedServo myservo1;                          
VarSpeedServo myservo2;
VarSpeedServo myservo3;
VarSpeedServo myservo4;

/////////Se declaran los pin digitales que utilizará cada servo
const  int servoPin1 = 6 ;     //Cadera izquierda                 
const  int servoPin2 = 10 ;    //Cadera derecha
const  int servoPin3 = 9 ;     //Pie izquierdo 
const  int servoPin4 = 11 ;    //Pie derecho

//////////////////////////////////////////////////////////////////////COMUNICACION BLUETOOTH
#include <SoftwareSerial.h>
int bluetoothTx = 7; //Corresponde a la patilla Tx del modulo
int bluetoothRx = 8;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

////////////////////////////////////////////////////////////////////////COMUNICACION SERIAL
//Variable en la que se asignara la señal recibida
int estado;     

/////////////////////////////////////////////////////////////////////Velocidad inicial del movimiento de los servos
int vel=30; 
int pausa=500;



////////////////////////////////////////////////////////////////////////.................INICIO VOID SETUP 
void  setup () {


////////////////////////////////////////////////////////////// Setup matrix led  
lc.shutdown(0,false);
lc.setIntensity(0,2);// La valores estan entre 1 y 15 
lc.clearDisplay(0); //Display apagado


///////////////////////////////////////////////////////////////////////Parametros del puerto serie
Serial.begin(9600);
//Configurar la conexión serie de Bluetooth con Android
bluetooth.begin(9600);
  

/////////////////////////////////////////////////////////////////7////Se aplica cada objeto servo a un pin   
myservo1. attach (servoPin1);   
myservo2. attach (servoPin2);  
myservo3. attach (servoPin3);
myservo4. attach (servoPin4);

////////////////////////////////////////////////////////////////////////..................................INICIO VOID LOOP
void  loop () {

Representar(STOP,0);
  
////////////////////////////////////////////////////////////////////////Recepcion y asignacion de la señal
if(Serial.available()>0) 
  {                      
  estado = Serial.read(); 
  } 
////////////////////////////////////////////////////////////////////////////Recepcion de la orden por Bluetooth
if(bluetooth.available()>0 )
  {                      
  estado = bluetooth.read();
  Representar(Conectado,0); 
  }

////////////////////////////////////////////////////////////////////////////Definicion de tres Velocidades distintas
///////////////////////////////Velocidad muy lenta
if  (estado=='1')
  {
vel = 30;
Representar(UNO,0); 
  }
  
////////////////////////////////////Velocidad lenta
if  (estado=='2')
  {
vel = 50;
Representar(DOS,0); 
  }

///////////////////////////////////////Velocidad media
if  (estado=='3')
  {
vel = 100;
Representar(TRES,0);
  }

////////////////////////////////////////////Velocidad rápida
if  (estado=='4')
  {
vel = 150;
Representar(CUATRO,0); 
  }


/////////////////////////////////////////////////////////////////////////MOVIMIENTOS   

////////////////////////////////////////STOP Alineacion de todos los seervos s 90 grados
if(estado=='c')
    { 
Representar(STOP,0);
myservo1.write ( 90 , 50 , false ); 
delay (pausa);              
myservo2.write ( 90 , 50 , false );  
delay (pausa);             
myservo3.write ( 90 , 150 , false );   
delay (pausa);          
myservo4.write ( 90 , 150 , true ); 
estado=0;    
     }

////////////////////////////////////////CAMINAR AL FRENTE                      
if(estado=='a')
    { 

Representar(RIE,0);
myservo4.write ( 60 , vel , true );
myservo3.write ( 60 , vel , true ); 
myservo1.write ( 60 , vel , true );  
myservo2.write ( 60 , vel , true );
myservo4.write ( 90 , vel , true );
myservo3.write ( 120 , vel , true );
myservo4.write ( 120 , vel , true );
myservo1.write ( 90 , vel , true );
myservo2.write ( 90 , vel , true );
myservo3.write ( 90 , vel , true );
myservo4.write ( 90 , vel , true );
     }
     
//////////////////////////////////////CAMINAR HACIA ATRAS                                
if(estado=='e')
    { 
Representar(ATRAS,0);
myservo4.write ( 60 , vel , true );
myservo3.write ( 60 , vel , true );
myservo1.write ( 120 ,vel , true ); 
myservo2.write ( 120 ,vel , true );  
myservo4.write ( 90 , vel , true );
myservo3.write ( 120 , vel , true );
myservo4.write ( 120 , vel , true );
myservo2.write ( 90 , vel , true);
myservo1.write ( 90 , vel , true );
myservo3.write ( 90 , vel , true ); 
myservo4.write ( 90 , vel , true );
    }

/////////////////////////////////////////GIRO SOBRE LA IZQUIERDA                           
if(estado=='b')
    { 
Representar(IZQ,0);
vel = 50; 
myservo3.write ( 135, vel , true );
myservo4.write ( 120,vel , true );
myservo2.write ( 120, vel , true );
myservo3.write ( 75 , vel , true );
myservo4.write ( 60 , vel , true ); 
myservo2.write ( 90 , vel , true ); 
myservo4.write ( 90 , vel , true );
myservo3.write ( 90 , vel , true );
vel = 30; 
    }

///////////////////////////////////////////GIRO SOBRE LA DERECHA                    
if(estado=='d')
    { 
Representar(DER,0);
vel = 50; 
myservo3.write ( 120 , vel , true );
myservo4.write ( 120 , vel , true );
myservo2.write ( 60 , vel , true );
myservo3.write ( 90 , vel , true );
myservo4.write ( 60 , vel , true );
myservo3.write ( 60 , vel , true );
myservo2.write ( 90 , vel , true );
myservo4.write ( 90 , vel , true );
myservo3.write ( 90 , vel , true );
vel = 30; 
    }

/////////////////////////////////////////////BAILE1                                           
if(estado=='f')
    {           
Representar(CORAZON,0);
myservo4.write ( 115 , vel , true );
myservo3.write ( 55 , vel , true );
myservo4.write ( 90 , vel , true );
myservo3.write ( 90 , vel , true );
myservo3.write ( 55 , vel , true );
myservo4.write ( 115 , vel , true );
myservo3.write ( 90 , vel , true );
myservo4.write ( 90 , vel , true );  
    }
    
///////////////////////////////////////////////BAILE 2                                     
if(estado=='g')
    { 
Representar(CORAZON,0);
myservo1.write ( 65 , vel , false ); 
myservo2.write ( 65 , vel , true ); 
myservo1.write ( 115 , vel , false ); 
myservo2.write ( 115 , vel , true ); 
myservo1.write ( 90 , vel , false ); 
myservo2.write ( 90 , vel , true );  
    }

////////////////////////////////////////////////BAILE 3                           
if(estado=='h')
    { 
Representar(CORAZON,0);
myservo3.write ( 135 , vel , true ); 
myservo4.write ( 120 , vel , true );
myservo4.write ( 90 , vel , true ); 
myservo3.write ( 90 , vel , true );
myservo4.write ( 60 , vel , true ); 
myservo3.write ( 60 , vel , true );
myservo3.write ( 90 , vel , true );
myservo4.write ( 90 , vel , true ); 
    } 

/////////////////////////////////////////////////PUNTERAS                                           
if(estado=='i')
    { 
Representar(CORAZON,0);
myservo4.write ( 45 , vel , false); 
myservo3.write ( 135 , vel , true ); 
myservo4.write ( 90 , vel , false); 
myservo3.write ( 90 , vel , true );
    } 

///////////////////////////////////////////////////zigzag                      
if(estado=='j')
    { 
Representar(CORAZON,0);
myservo2.write ( 120, vel , false );
myservo1.write ( 60 , vel , true );
myservo2.write ( 90 , vel , false);
myservo1.write ( 90 , vel , true );  
    } 

////////////////////////////////////////////////SALUDA PIE IZQUIERDO                     
if(estado=='k')
    { 
Representar(CORAZON,0);
vel = 50; 
myservo3.write ( 135 , vel , true );
myservo4.write ( 135 , vel , true );
myservo3.write ( 60 , vel , true );
myservo3.write ( 120 , vel , true );
myservo3.write ( 60 , vel , true );
myservo3.write ( 90 , vel , true );
myservo4.write ( 90 , vel , true ); 
    } 

////////////////////////////////////////////////SALUDA PIE DERECHO                      
if(estado=='l')
    { 
Representar(CORAZON,0);
vel = 50; 
myservo4.write ( 60 , vel , true ); 
myservo3.write ( 60 , vel , true );
myservo4.write ( 120 , vel , true ); 
myservo4.write ( 60 , vel , true );
myservo4.write ( 120 , vel , true ); 
myservo4.write ( 90 , vel , true );
myservo3.write ( 90 , vel , true );
    }

////////////////////////////////////////////INCLINATE IZQUIERDA                      
if(estado=='m')
    { 
Representar(CORAZON,0);
myservo4.write ( 45 , vel , true );
myservo3.write ( 75 , vel , true );
myservo3.write ( 90 , vel , true );
myservo4.write ( 90 , vel , true ); 
    }

/////////////////////////////////////////////INCLINATE DERECHA                      
if(estado=='w')
    { 
Representar(CORAZON,0);
myservo3.write ( 135 , vel , false );
myservo4.write ( 120 , vel , true );
myservo4.write ( 90 , vel , true );
myservo3.write ( 90 , vel , true ); 
    }

///////////////////////////////////////////////MOVIMIENTOS PARA SERVO Nº 1

if(estado=='n')
    { 
myservo1.write (30,vel,false); 
    }

if(estado=='o')
    { 
myservo1.write (45,vel,false); 
    }

if(estado=='p')
    { 
myservo1.write (60,vel,false); 
    }

if(estado=='q')
    { 
myservo1.write (75,vel,false); 
    }

if(estado=='r')
    { 
myservo1.write (90,vel,false); 
    }

if(estado=='s')
    { 
myservo1.write (105,vel,false); 
    }

if(estado=='t')
    { 
myservo1.write (120,vel,false); 
    }

if(estado=='u')
    { 
myservo1.write (135,vel,false); 
    }   

if(estado=='v')
    { 
myservo1.write (150,vel,false); 
    }    

/////////////////////////////////////////////////MOVIMIENTOS PARA SERVO Nº 2
if(estado=='x')
    { 
myservo2.write (30,vel,false); 
    }

if(estado=='y')
    { 
myservo2.write (45,vel,false); 
    }

if(estado=='z')
    { 
myservo2.write (60,vel,false); 
    }

if(estado=='A')
    { 
myservo2.write (75,vel,false); 
    }

if(estado=='B')
    { 
myservo2.write (90,vel,false); 
    }

if(estado=='C')
    { 
myservo2.write (105,vel,false); 
    }

if(estado=='D')
    { 
myservo2.write (120,vel,false); 
    }

if(estado=='E')
    { 
myservo2.write (135,vel,false); 
    }   

if(estado=='F')
    { 
myservo2.write (150,vel,false); 
    }

//////////////////////////////////////////////MOVIMIENTOS PARA SERVO Nº 3
if(estado=='G')
    { 
myservo3.write (30,vel,false); 
    }

if(estado=='H')
    { 
myservo3.write (45,vel,false); 
    }

if(estado=='I')
    { 
myservo3.write (60,vel,false); 
    }

if(estado=='J')
    { 
myservo3.write (75,vel,false); 
    }

if(estado=='K')
    { 
myservo3.write (90,vel,false); 
    }

if(estado=='L')
    { 
myservo3.write (105,vel,false); 
    }

if(estado=='M')
    { 
myservo3.write (120,vel,false); 
    }

if(estado=='N')
    { 
myservo3.write (135,vel,false); 
    }   

if(estado=='O')
    { 
myservo3.write (150,vel,false); 
    }

/////////////////////////////////////////////MOVIMIENTOS PARA SERVO Nº 4
if(estado=='P')
    { 
myservo4.write (30,vel,false); 
    }

if(estado=='Q')
    { 
myservo4.write (45,vel,false); 
    }

if(estado=='R')
    { 
myservo4.write (60,vel,false); 
    }

if(estado=='S')
    { 
myservo4.write (75,vel,false); 
    }

if(estado=='T')
    { 
myservo4.write (90,vel,false); 
    }

if(estado=='U')
    { 
myservo4.write (105,vel,false); 
    }

if(estado=='V')
    { 
myservo4.write (120,vel,false); 
    }

if(estado=='X')
    { 
myservo4.write (135,vel,false); 
    }   

if(estado=='Y')
    { 
myservo4.write (150,vel,false); 
    }


///////////////////////////////////////////////////////////////////////////7//////////////////...............FIN VOID LOOP
}
////////////////////////////////////////////////////////////////////////////////////FUNCIONES VOID
////////Definicion de la funcion para representar las figuras 
////////Funcion para la representacion de bytes de datos para una matriz de 8x8

void Representar(byte *Datos,int retardo)  
{
  for (int i = 0; i < 8; i++)  
  {
     lc.setColumn(0,i,Datos[7-i]);
  }
  delay(retardo);
}
    
Te puedo asegurar que disfrutaras con la construcción, es relativamente sencillo,
 

COMPRAS Y ENCARGOS 

Los archivo STL están disponible mediante el pago de 10 euros, se puede realizar el pago a través de PayPal o Bizum, contacta conmigo en 29german@gmail.com

Si deseas obtener las piezas ya impresas te las puedo enviar mediante el pago de 30 euros incluidos gastos de envió a la península, si tienes dudas o alguna pregunta en 29german@gmail.com

Si compras los archivos STL o me encargas la impresión de las piezas te regalaré la App KuriBot

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.