Brazo robótico. Electrónica.

Este es el segundo post sobre el montaje de un brazo robótico de seis ejes. Vamos a ver con detalle cómo montar la parte electrónica. En el primer post vimos el ensamblaje de la parte mecánica.

Necesitamos un dispositivo que sea capaz de manejar seis servos de manera independiente. Queremos que cada servo pueda mover su eje el ángulo adecuado para posicionar la garra del brazo en el punto deseado. También sería interesante poder variar la velocidad de movimiento de cada motor para un posicionamiento fino.

Para mover cada servo, podemos usar un par de pulsadores que hagan que avance adelante o atrás. También podríamos usar un potenciómetro que indicara el ángulo que debe desplazarse, etc. Sin embargo, la opción elegida para el control de los servos es el joystick.

Cada joystick está formado por dos potenciómetros lo que nos permite controlar dos servos, por tanto necesitaremos tres joysticks.

Características generales

  • Alimentación: 8 – 40V
  • Consumo máximo: 1A
  • Controladores basados en joystick

Este es el dispositivo que vamos a montar:

Esquema

Nuestro circuito está basado en tres unidades idénticas formadas por un Joystick y dos servos. Como decíamos más arriba, el joystick está formado por dos potenciómetros perpendiculares. Vamos ha hacer que cuando movamos el joystick en el eje horizontal (izquierda – derecha) el sistema actúe sobre un servo y cuando lo movamos en el eje vertical (arriba – abajo) el sistema actúe sobre el otro servo.

Esquema de conexiones Joystick – Sensor Shield – Servos

Los dos terminales del Joystick asociados a los potenciómetros (Rx y Ry) los conectaremos a dos pines analógicos de la Sensor Shield (A0 y A1 en la imagen). Por otro lado, los dos pines de señal de los servos los conectamos a dos pines digitales (Pin 2 y Pin 3 en la imagen). Además, conectaremos los pines de alimentación del joystick y de los servos tal como se ve en la imagen.

Los servos incluyen un cable con un conector de tres pines que encaja perfectamente en los pines de la Sensor Shield. Tener cuidado de conectar el cable amarillo o naranja (el cable de señal del servo) en la parte de abajo del conector.

Alimentación de los servos

No podemos alimentar los seis servos directamente desde la placa de Arduino ya que podríamos dañarla, necesitamos una fuente de alimentación externa exclusivamente para ellos. Usaremos el alimentador de 12V. Dado que la tensión de alimentación de los servos es de 6V, necesitamos reducir la salida del alimentador. Para esto usaremos el regulador de tensión.

Detalle de la conexión del alimentador con el regulador de tensión

Usaremos el adaptador de Power Jack para conectar el alimentador al regulador en los pines IN+ e IN-. Tener cuidado de respetar la polaridad del conector y del regulador.

Conectando un voltímetro a la salida del regulador (pines OUT) actuaremos sobre el potenciómetro de ajuste hasta obtener los 6V necesarios para alimentar los servos.

La salida del regulador (terminales OUT) la conectaremos a los terminales de alimentación de la Sensor Shield (marcada como 6V en el esquema anterior).

Es importante quitar el jumper que hay junto a los terminales de alimentación de la Sensor Shield. Si este jumper está puesto, la Sensor Shield entrega a los servos la alimentación obtenida del pin de 5V de la placa de Arduino. Si el jumper está quitado, la Sensor Shield alimenta los servos desde el terminal de alimentación externa.

Siguiendo el esquema anterior para un joystick y dos servos, repetimos el montaje para los otros dos joysticks y los cuatro servos restantes. Así, los tres joysticks estarán conectados a los pines digitales A0, A1 para el primer joystick, A2 y A3 para el segundo y A4 y A5 para el tercero. No olvidar conectar los pines de alimentación de los tres joysticks.

Los servos, ordenados de abajo a arriba en el brazo, los conectaremos a los pines 2, 3, 4, 5, 6, 7 de la Sensor Shield.

La distribución de los elementos en la protoboard podría ser la siguiente

Distribución en protoboard

y el montaje quedaría como en la imagen.

Software

Tenemos nuestro circuito montado. Ahora veamos el software que debe controlarlo.

#include <Servo.h>
#include <math.h>

Servo S1, S2, S3, S4, S5, S6;

// Pines analógicos de los potenciómetros de los joys.
// El 0 y el 1 los intercambio porque quiero el 
// primer servo en el segundo potenciómetro del
// primer joystick.
int PotPins[6] = { 1, 0, 2, 3, 4, 5 };

// Pines digitales de control de los servos.
int ServoPins[6] = { 2, 3, 4, 5, 6, 7 };

// Lectura de los potenciómetros
int PotVals[6] = { 0, 0, 0, 0, 0, 0 };

// Servos
Servo Servos[6] = {S1, S2, S3, S4, S5, S6};

// Posiciones de los servos.
int ServoPositions[6] = { 90, 120, 150, 90, 110, 30 };

// Dirección horaria o antihoraria de los servos
int ServoDirections[6] = { -1, 1, -1, -1, 1, 1 };

// Velocidad de cada servo.
int Speeds[6] = { 0, 0, 0, 0, 0, 0 };

int PotGapUp = 550;
int PotGapDown = 450;

void setup()
{
	//Serial.begin(115200);

	for (int i = 0; i < 6; i++)
	{
		Servos[i].attach(ServoPins[i]);
		//ServoPositions[i] = Servos[i].read();
		Servos[i].write(ServoPositions[i]);
		delay(10);
	}
}

void loop()
{
	ReadJoys();
	Move();
}

void ReadJoys()
{
	for (int i = 0; i < 6; i++) PotVals[i] = analogRead(PotPins[i]);
	FilterJoys();
	for(int i = 0; i < 6; i++) Speeds[i] = GetSpeed(PotVals[i]);
}

void Move()
{
	for (int i = 0; i < 6; i++)
	{
		if (PotVals[i] < PotGapDown)
		{
			if (ServoDirections[i] == 1) MoveBackward(i);
			else MoveForward(i);
		}
		else if (PotVals[i] > PotGapUp)
		{
			if (ServoDirections[i] == 1) MoveForward(i);
			else MoveBackward(i);
		}
	}
}

void MoveForward(int index)
{
	ServoPositions[index] += 1;
	if (ServoPositions[index] > 180) ServoPositions[index] = 180;
	Servos[index].write(ServoPositions[index]);
	delay(GetDelay(Speeds[index]));
}

void MoveBackward(int index)
{
	ServoPositions[index] -= 1;
	if (ServoPositions[index] < 0) ServoPositions[index] = 0;
	Servos[index].write(ServoPositions[index]);
	delay(GetDelay(Speeds[index]));
}

void FilterJoys()
{
	// Evita los movimientos cruzados de los joys.
	// Sólo acepta el valor x o el valor y, el que sea mayor.

	int idlePos = (PotGapUp + PotGapDown) / 2;

	// Joy1
	int delta0 = abs(PotVals[0] - idlePos);
	int delta1 = abs(PotVals[1] - idlePos);
	if (delta0 > delta1) PotVals[1] = idlePos;
	else PotVals[0] = idlePos;

	// Joy2
	int delta2 = abs(PotVals[2] - idlePos);
	int delta3 = abs(PotVals[3] - idlePos);
	if (delta2 > delta3) PotVals[3] = idlePos;
	else PotVals[2] = idlePos;

	// Joy3
	int delta4 = abs(PotVals[4] - idlePos);
	int delta5 = abs(PotVals[5] - idlePos);
	if (delta4 > delta5) PotVals[5] = idlePos;
	else PotVals[4] = idlePos;
}

int GetSpeed(int level)
{
	if (level <= 25) return 6;
	else if (level > 25 && level <= 150) return 4;
	else if (level > 150 && level <= 350) return 2;
	else if (level > 350 && level <= 450) return 1;
	else if (level > 450 && level <= 550) return 0;
	else if (level > 550 && level <= 700) return 1;
	else if (level > 700 && level <= 850) return 2;
	else if (level > 850 && level <= 1000) return 4;
	else return 6;
}

int GetDelay(int speed)
{
	int del = 300 / speed;
	return del;
}

La primera parte del código define algunos arrays para controlar los joysticks y los servos. El significado de estos arrays es el siguiente:

  • PinPots define los pines analógicos a los que hemos conectado los potenciómetros de los joysticks. Está definido con los valores 1, 0, 2, 3, 4, 5. Los dos primeros pines están intercambiados porque interesa que el primer potenciómetro del primer joystick (eje vertical) controle el segundo servo. Esto es interesante por que al hacerlo así, si movemos el joystick hacia arriba o hacia abajo, actúa el segundo servo moviendo el brazo hacia arriba o hacia abajo. El eje x del primer joystick lo asociamos al primer servo que hace que el brazo gire a izquierda o derecha.
  • ServoPins define los pines digitales a los que conectamos los servos.
  • PotVals guardará las lecturas de todos los potenciómetros de los joysticks.
  • ServoPositions Este array guarda las posiciones (ángulo en grados) actuales de todos los servos. Aquí podemos indicar la posición inicial que queremos que tenga cada servo.
  • ServoDirections define si cada servo debe girar en sentido horario o antihorario. Lo indicamos con un 1 o un -1.
  • Speeds Aquí se guarda la velocidad de desplazamiento de cada servo. Contra más desplacemos el joystick de su posición de reposo, mayor será su velocidad.

Cuando desplazamos un joystick de su posición de reposo, el motor asociado avanza o retrocede un grado, hace un delay, avanza otro grado y se repite la operación hasta que el joystick vuelve a quedar en reposo. Variando este delay podemos controlar la velocidad de los motores. Si modificamos el número 300 que aparece en la línea 133 del código, podemos variar la velocidad global, a mayor delay, menor velocidad. Cambiando el 300 por 150, por ejemplo, duplicaremos la velocidad global de todos los servos.

También te podría gustar...

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *