Skip to content
Juan Gonzalez-Gomez edited this page Oct 15, 2023 · 13 revisions

LOG

Domingo, 15-Oct-2023

Hace tiempo me compré el robot MeARM de Keystudios. Lo compré por amazon en este enlace

Lo monté y lo estuve probando, pero apenas he tenido dedicarle más tiempo. Ahora lo quiero retormar y lo quiero dejar listo para usarlo con FPGAs. Pero lo primero es lograr que funcione bien con el mando que trae

Por alguna razón, está descalibrado y no funciona bien. Voy a hacer pruebas para entenderlo mejor y dejarlo listo

La documentación está disponible en la wiki de Keystudios

Leyendo la documentación, he visto que hay que alimentar el robot entre 7 y 15v. Lo he alimentado con la fuente y ha mejorado el movimiento, aunque todavía hay dos ejes que van raros (la pinza y el balancín)

Lo primero será cargar el blinky en la placa compatible arduino que trae. He instalado Arduino 2.2.1. He indicado que tengoun Arduino UNO y he cargado el programa del blink. TODO OK!

Servo de la pinza

Conecto el servo de la pinza a la entrada A0 de la shield. Cargo este programa:

#include <Servo.h>
Servo myservo;  // create servo object to control a servo

void setup()
{
  Serial.begin(9600); 
  delay(1000);
}

void loop() 
{
  myservo.attach(A0);  // modify each pin to adjust 
  myservo.write(0);  // angle value  
  delay(1000);
}

La pinza se cierra (sin forzar). He probado con otros valores para determianr el rango de uso de los ángulos:

Angulo Estado pinza
0 Cerrada
90 Abierta (180 grados)

La pinza se puede abrir más de 90, pero su rango de uso básicamente es 0 - 90

Servo de la Base

Haciendo pruebas con la base, los ángulos a usar van entre 0 - 140

Anuglo Estado base
0 En esquina superior derecha
140 En esquina superior izquierda

Servo Derecho (Balancin)

El servo del balancin que lo hace moverse arriba-abajo tiene un rango de 0 - 120 (0 es arriba y 120 abajo)

Angulo Balancin
0 Arriba
120 Abajo

Servo Izquierdo (Hombro)

El servo del hombro hace que el brazo se estira - encoja: 0 (Estirado) - 120 (Encogido)

Angulo Hombro
0 Estirado
120 Encogido

OK... por separado todos los servos están funcionado bien. Cómo los estoy provando uno a uno, con la alimentación del portátil es suficiente (no estoy usando la fuente externa)

Movimiento de la pinza

Este programa realiza un movimiento de apertura y cierre de la pinza, pero NO a la máxima velocidad. Funciona muy bien

#include <Servo.h>
Servo pinza;  // create servo object to control a servo

void setup()
{
  Serial.begin(9600); 

  //-- Configurar servo de la pinza (Cerrado por defecto)
  pinza.attach(9);  
  pinza.write(0);   

  delay(1000);

}

void loop() 
{
   
 //-- Abrir pinza
 for(int pos = 0; pos < 90; pos++)
 {
   pinza.write(pos);
   delay(10);
 }

 //-- Cerrar pinza
 for(int pos = 90; pos > 0; pos--)
 {
   pinza.write(pos);
   delay(10);
 }

  delay(1000);
}

Movimiento de la base

Este programa hace lo mismo, pero con la base. Si se prueba desde el USB del ordenador, girar hacia la izquierda le cuesta. Pero con la fuente de alimentación sí que lo hace bien...

#include <Servo.h>
Servo base;

void setup()
{
  Serial.begin(9600); 

  //-- Configurar el servo de la base
  base.attach(A1);
  base.write(0);

  delay(1000);

}

void loop()
{


  //-- Girar hacia la Izquierda
  for(int pos = 0; pos < 140; pos++) {
    base.write(pos);
    delay(10);
  }

  //-- Girar hacia la derecha
  for (int pos = 140; pos > 0; pos--) {
    base.write(pos);
    delay(10);
  }

  delay(1000);

}

Movimiento del codo

El codo se mueve arriba y abajo. Con la alimentación portátil funciona bien

#include <Servo.h>
Servo codo;

void setup()
{
  Serial.begin(9600); 

  //-- Configurar el servo de la base
  codo.attach(A0);
  codo.write(0);

  delay(1000);

}

void loop()
{


  //-- Subir codo
  for(int pos = 0; pos < 100; pos++) {
    codo.write(pos);
    delay(10);
  }

  //-- bajar codo
  for (int pos = 100; pos > 0; pos--) {
    codo.write(pos);
    delay(10);
  }

  delay(1000);

}

Movimiento del Hombro

Este código mueve el hombro arriba-abajo, en secuencia. Funciona con la alimentación del PC

#include <Servo.h>
Servo hombro;

void setup()
{
  Serial.begin(9600); 

  //-- Configurar el servo de la base
  hombro.attach(6);
  hombro.write(20);

  delay(1000);

}

void loop()
{


  //-- Subir codo
  for(int pos = 20; pos < 140; pos++) {
    hombro.write(pos);
    delay(10);
  }

  //-- bajar codo
  for (int pos = 140; pos > 20; pos--) {
    hombro.write(pos);
    delay(10);
  }

  delay(1000);

}

Primera secuencia de prueba

Ya tengo el robot funcionando con una primera secuencia de prueba. El robot comienza en la posición reposo, en el centro. En este secuencia sólo se mueve un servo cada vez. Primero se mueve hacia la derecha (apuntando a su esquina superior derecha). Abre la pinza. Estira el brazo (para lo cual baja). Cierra la pinza para coger el objeto depositado. Se va hacia atrás (con el objeto cogido). Gira a la izquierda. Baja y se estira para poner el objeto en el suelo otra vez. Abre la pinza. Se echa hacia atrás. Cierra la pinza. Y repite el bucle...

#include <Servo.h>
Servo base;
Servo codo;
Servo hombro;
Servo pinza;

int pos_base = 80;
int pos_codo = 60;
int pos_hombro = 120;
int pos_pinza = 0;

void setup()
{
  Serial.begin(9600); 

  //-- Configurar el servo de la base
  base.attach(A1);
  base.write(pos_base);

  //-- Configurar el servo del codo
  codo.attach(A0);
  codo.write(pos_codo);

  //-- Configurar el servo del hombro
  hombro.attach(6);
  hombro.write(pos_hombro);


  //-- Configurar servo de la pinza 
  pinza.attach(9);  
  pinza.write(pos_pinza);   

  delay(1000);

}

void loop()
{


  //-- Girar hacia la derecha
  for (; pos_base > 0; pos_base--) {
    base.write(pos_base);
    delay(10);
  }
  delay(1000);

  //-- Abrir pinza
  for(; pos_pinza < 90; pos_pinza++)
  {
    pinza.write(pos_pinza);
    delay(10);
  }
  delay(1000);

   //-- bajar codo
  for (; pos_codo > 50; pos_codo--) {
    codo.write(pos_codo);
    delay(10);
  }

  //-- bajar hombro (estirar)
  for (; pos_hombro > 50; pos_hombro--) {
    hombro.write(pos_hombro);
    delay(10);
  }
  delay(1500);

  //-- Cerrar pinza
  for(; pos_pinza > 0; pos_pinza--)
  {
    pinza.write(pos_pinza);
    delay(10);
  }
  delay(1000);

  //-- Subir hombro (encojer)
  for (; pos_hombro < 120; pos_hombro++) {
    hombro.write(pos_hombro);
    delay(10);
  }

  delay(1000);

  //-- Girar a la izquierda
  for (; pos_base < 120; pos_base++) {
    base.write(pos_base);
    delay(10);
  }
  delay(1000);

  // Bajar hombro
  for(;pos_hombro > 50; pos_hombro--)
  {
    hombro.write(pos_hombro);
    delay(10);
  }
  delay(1000);

  //-- Abrir pinza
  for(; pos_pinza < 90; pos_pinza++)
  {
    pinza.write(pos_pinza);
    delay(10);
  }
  delay(1000);

  //-- Subir hombro 
  for(;pos_hombro < 120; pos_hombro++)
  {
    hombro.write(pos_hombro);
    delay(10);
  }
  delay(1000);

  //-- Cerrar la pinza
  //-- Cerrar pinza
  for(; pos_pinza > 0; pos_pinza--)
  {
    pinza.write(pos_pinza);
    delay(10);
  }
  delay(1000);

}

Segunda prueba de secuencia

Voy a modifcar los valores de pausa para que vaya un poquito más rápido. Voy a usar los que incluyen en el ejemplo original, ahora que ya me funciona bien

#include <Servo.h>

#define DELAY_BASE 5
#define DELAY_CODO 5
#define DELAY_HOMBRO 5
#define DELAY_PINZA 0

Servo base;
Servo codo;
Servo hombro;
Servo pinza;

int pos_base = 80;
int pos_codo = 60;
int pos_hombro = 120;
int pos_pinza = 0;

void setup()
{
  Serial.begin(9600); 

  //-- Configurar el servo de la base
  base.attach(A1);
  base.write(pos_base);

  //-- Configurar el servo del codo
  codo.attach(A0);
  codo.write(pos_codo);

  //-- Configurar el servo del hombro
  hombro.attach(6);
  hombro.write(pos_hombro);


  //-- Configurar servo de la pinza 
  pinza.attach(9);  
  pinza.write(pos_pinza);   

  delay(1000);

}

void loop()
{


  //-- Girar hacia la derecha
  for (; pos_base > 0; pos_base--) {
    base.write(pos_base);
    delay(DELAY_BASE);
  }
  delay(1000);

  //-- Abrir pinza
  for(; pos_pinza < 90; pos_pinza++)
  {
    pinza.write(pos_pinza);
    delay(DELAY_PINZA);
  }
  delay(1000);

   //-- bajar codo
  for (; pos_codo > 50; pos_codo--) {
    codo.write(pos_codo);
    delay(DELAY_CODO);
  }

  //-- bajar hombro (estirar)
  for (; pos_hombro > 50; pos_hombro--) {
    hombro.write(pos_hombro);
    delay(DELAY_HOMBRO);
  }
  delay(1500);

  //-- Cerrar pinza
  for(; pos_pinza > 0; pos_pinza--)
  {
    pinza.write(pos_pinza);
    delay(DELAY_PINZA);
  }
  delay(1000);

  //-- Subir hombro (encojer)
  for (; pos_hombro < 120; pos_hombro++) {
    hombro.write(pos_hombro);
    delay(DELAY_HOMBRO);
  }

  delay(1000);

  //-- Girar a la izquierda
  for (; pos_base < 120; pos_base++) {
    base.write(pos_base);
    delay(DELAY_BASE);
  }
  delay(1000);

  // Bajar hombro
  for(;pos_hombro > 50; pos_hombro--)
  {
    hombro.write(pos_hombro);
    delay(DELAY_HOMBRO);
  }
  delay(1000);

  //-- Abrir pinza
  for(; pos_pinza < 90; pos_pinza++)
  {
    pinza.write(pos_pinza);
    delay(DELAY_PINZA);
  }
  delay(1000);

  //-- Subir hombro 
  for(;pos_hombro < 120; pos_hombro++)
  {
    hombro.write(pos_hombro);
    delay(DELAY_HOMBRO);
  }
  delay(1000);

  //-- Cerrar la pinza
  //-- Cerrar pinza
  for(; pos_pinza > 0; pos_pinza--)
  {
    pinza.write(pos_pinza);
    delay(DELAY_PINZA);
  }
  delay(1000);

}

Funciona igual, pero un pelin más rápido. Se nota sobre todo al abrir y cerrar la pinza

Lectura del joystick

Con este programa se leen los valores del joystick. Se muestran en el puerto serie el joystick izquierdo y luego el derecho, en la misma línea. El eje Z es el pulsador de cada joystick

const int right_X = A2; // define the right X pin to A2 
const int right_Y = A5; // define the right Y pin to A5 
const int right_key = 7; //define the right key pin to 7(that is the value Z)

const int left_X = A3; //define the left X pin to A3
const int left_Y = A4;  // define the left Y pin to A4
const int left_key = 8; //define the left key pin to 8(that is the value Z) 

void setup() 
{
  pinMode(right_key, INPUT);   // set the right/left key to INPUT 
  pinMode(left_key, INPUT);
  Serial.begin(9600); //  set the baud rate to 9600
}

void loop() 
{
  int x1,y1,z1;  // define the variable, used to save the joystick value it reads
  int x2,y2,z2;
  
  x1 = analogRead(right_X); // read the value of right X 
  y1 = analogRead(right_Y);  // read the value of right Y 
  z1 = digitalRead(right_key);  //// read the value of right Z 
  
  x2 = analogRead(left_X);  // read the value of left X
  y2 = analogRead(left_Y);  // read the value of left Y 
  z2 = digitalRead(left_key);  // read the value of left Z 
  
  //-- Mostrar Joystick izquierdo
  Serial.print("X: "); 
  Serial.print(x2 ,DEC);  
  Serial.print("  Y: ");
  Serial.print(y2 ,DEC);
  Serial.print("  Z: ");
  Serial.print(z2 ,DEC);

  //-- MOstrar Joystick derecho
  Serial.print("  ---  X: "); // on the serial monitor, print out right_X = 
  Serial.print(x1 ,DEC);  // print out the value of right X and line wrap
  Serial.print("  Y: ");
  Serial.print(y1 ,DEC);
  Serial.print("  Z: ");
  Serial.println(z1 ,DEC);

  delay(300);
}

Los valores leidos son:

Izquierda Centro Derecha Arriba Abajo
1008 504 0 0 1008

Muy parecidos para ambos joysticks...

Movimiento del robot con el joystick

Este programa permite mover los 4 DOF del robot con el joystick... El programa está lleno de números mágicos y es cutre, pero de momento me sirve para hacer prruebas

  • Controles:
    • Joystick derecho:
      • Derecha/izquierda: Mover base derecha/izqda
      • Up/Down: Mover el codo arriba/abajo
    • Joystick izquierdo:
      • Left/right: Abrir/cerrar la pinza
      • Up/Down: Mover hombre arriba/abajo
#include <Servo.h>

const int right_X = A2; // define the right X pin to A2 
const int right_Y = A5; // define the right Y pin to A5 
const int right_key = 7; //define the right key pin to 7(that is the value Z)

const int left_X = A3; //define the left X pin to A3
const int left_Y = A4;  // define the left Y pin to A4
const int left_key = 8; //define the left key pin to 8(that is the value Z) 

Servo base;
Servo codo;
Servo hombro;
Servo pinza;

int pos_base = 80;
int pos_codo = 60;
int pos_hombro = 90;
int pos_pinza = 90;

void setup() 
{
  pinMode(right_key, INPUT);   // set the right/left key to INPUT 
  pinMode(left_key, INPUT);
  Serial.begin(9600); //  set the baud rate to 
  
  //-- Configurar el servo de la base
  base.attach(A1);
  base.write(pos_base);

  //-- Configurar el servo del codo
  codo.attach(A0);
  codo.write(pos_codo);

  //-- Configurar el servo del hombro
  hombro.attach(6);
  hombro.write(pos_hombro);

  //-- Configurar servo de la pinza 
  pinza.attach(9);  
  pinza.write(pos_pinza);  
}

void loop() 
{
  int x1,y1,z1;  // define the variable, used to save the joystick value it reads
  int x2,y2,z2;
  
  x1 = analogRead(right_X); // read the value of right X 
  y1 = analogRead(right_Y);  // read the value of right Y 
  z1 = digitalRead(right_key);  //// read the value of right Z 
  
  x2 = analogRead(left_X);  // read the value of left X
  y2 = analogRead(left_Y);  // read the value of left Y 
  z2 = digitalRead(left_key);  // read the value of left Z 
  

  //------ Comprobar la pinza
  //-- Cerrar pinza? Joystick izquierdo a la derecha
  if (x2 < 50) { 

    //-- Pinza todavia no cerrada del todo
    if (pos_pinza > 0) { 
      pos_pinza = pos_pinza - 1;
      pinza.write(pos_pinza);
      delay(5);
    }
    
  }

  //-- Abrir pinza!
  if (x2 > 1000) {

    //-- Pinza todavia no abierta del todo
    if (pos_pinza < 90) {
      pos_pinza = pos_pinza + 1;
      pinza.write(pos_pinza);
      delay(5);
    }
  }

  //--- Comprobar la base
  //-- Mover base a la derecha? Joystick derecho a la derecha
  if (x1 < 50) {

    //-- Si robot todavia no esta en la derecha del todo
    if (pos_base > 0) {
      pos_base = pos_base - 1;
      base.write(pos_base);
      delay(5);
    }
  }

  //-- Mover base a la izquierda? Joystick derecho a la izquierda 
  if (x1 > 1000) {

    //-- Pinza todavia no abierta del todo
    if (pos_base < 140) {
      pos_base = pos_base + 1;
      base.write(pos_base);
      delay(5);
    }
  }

  //-- Comprobar el codo
  //-- Mover codo hacia arriba? Jostick derecho hacia arriba
  if (y1 < 50) {

    //-- Codo todavía no en su limite superior
    if (pos_codo > 0 ) {
      pos_codo = pos_codo - 1;
      codo.write(pos_codo);
      delay(5);
    }

  }

  //-- Mover codo hacia bajo? Joystick derecho hacia abajo
  if (y1 > 1000) {

    //-- Codo no en su limite superior
    if (pos_codo < 120) {
      pos_codo = pos_codo + 1;
      codo.write(pos_codo);
      delay(5);
    }
  }

  //-- Comprobar el Hombro
  //-- Alargar el brazo hacia adelante? Joystick izquierdo hacia arriba
  if (y2 < 50) {

    if (pos_hombro > 40) {
      pos_hombro = pos_hombro - 1;
      hombro.write(pos_hombro);
      delay(5);
    }
  }

  //-- Encoger el brazo (hacia atras)? Joystick izquierdo hacia abajo
  if (y2 > 1000) {

    //-- Hombre no en su limite superior
    if (pos_hombro < 120) {
      pos_hombro = pos_hombro + 1;
      hombro.write(pos_hombro);
      delay(5);
    }


  }

}