Está en la página 1de 6

+

Construyendo a Chispas
Menú
Saltar al contenido.

Controlar un brazo robótico de 4 motores con Arduino


Vamos a ver como controlar desde el ordenador un brazo robotico con cuatro motores. Aunque
realmente del movimiento se ocupan tres, el cuarto es solo para abrir y cerrar «la
pinza».Vamos a nombrar los servos de la siguiente manera:

base: se encuentra en la base del robot y controla el giro del brazo


hombro: controla «el hombro» del brazo
codo: controla «el codo» del brazo
mano: controla la apertura y cierre de la pinza
En las siguientes fotos puede verse el brazo que voy a usar. El servo «base» se encuentra en
la parte inferior del brazo. El servo «hombro» en la parte superior de la fotografía (en la foto
vista desde arriba), el servo «codo» en la inferior y el servo «mano» en la mano (este era
sencillo).

Para controlar el movimiento de estos servos usaremos dos variables, una guardará el valor en
grados actual, la otra el valor en grados al que debe de moverse. En cada iteración de la
función loop() se llamara a la función ActualizarServos() que se ocupa de actualizar el valor del
servo. Si ambas variables coinciden no se hace nada, si son distintas cada iteración se sumará
o restará un grado para acercarse al valor deseado. Esto se hace así para evitar movimientos
demasiado rápidos que puedan dañar el robot o golpear alguna cosa del entorno. La velocidad
se puede controlar con el delay al final de la función loop()

Cada servo tendrá unos grados mínimos y máximos delos que no podrá pasar, delimitados por
la estructura del brazo (por ejemplo, que choque con la propia estructura del brazo o que la
articulación no «da más de si»). Se usaran dos variables para estar seguro que no pasamos
esos limites. Por ejemplo para la base se usaran: basePosMax y basePosMin.

Si se intenta establecer un valor mayor o menor del fijado por esas dos variables se igualará al
valor de estas. Asi evitamos situaciones que puedan dañar el brazo.

Para controlar el brazo usaremos comandos de texto enviados a través del puerto serie

Lo comandos son:

Sn:grados: n indica el servo y grados la posicion en grados a la que debe ir


Q: mueve cada servo a la «posición de apagado» / «posición de inicio»
W: escribe en consola la posición en grados de cada servo
El comando Q es necesario para poder «parar» el brazo. No se guarda el estado de los servos,
por lo que para evitar que el brazo realice movimientos bruscos al iniciarse hay que llevarlo a la
posición de «apagado» o de «arranque» (obviamente son la misma).

El comando S tiene las siguientes correspondencias con los servos:

S1 base
S2 codo
S3 hombro
S4 mano
Por ejemplo, para cerrar la mano se podria usar el comando S4:35

El código para el controlarlo es el siguiente:

#include <Servo.h>

// Se definen los pines a los que están conectados los servos


const int basePin = 5;
const int hombroPin = 11;
const int codoPin = 3;
const int manoPin = 10;

// Se crean los objetos Servo correspondientes a cada servo


Servo baseServo;
Servo hombroServo;
Servo codoServo;
Servo manoServo;

// Variables para almacenar la posición actual y destino


int basePos = 90;
int hombroPos = 90;
int codoPos = 120;
int manoPos = 10;

int basePosDest = basePos;


int hombroPosDest = hombroPos;
int codoPosDest = codoPos;
int manoPosDest = manoPos;

int basePosMax = 180;


int hombroPosMax = 150;
int codoPosMax = 170;
int manoPosMax = 35;

int basePosMin = 0;
int hombroPosMin = 80;
int codoPosMin = 90;
int manoPosMin = 10;

void setup() {
// Se inicializan los servos en la posición central
baseServo.write(basePos);
hombroServo.write(hombroPos);
codoServo.write(codoPos);
manoServo.write(manoPos);

// Se inician los objetos Servo


baseServo.attach(basePin);
hombroServo.attach(hombroPin);
codoServo.attach(codoPin);
manoServo.attach(manoPin);

// Se inicia la comunicación por el puerto serie


Serial.begin(9600);
}

void loop() {
// Se actualizan los servos
ActualizarServos();

// Se espera para que los servos alcancen su nueva posición


delay(20);
}

// Función que se llama al final decada iteracion de loop


void serialEvent() {
// Se lee la línea recibida del puerto serie
String data = Serial.readStringUntil('\n');
char command = data.charAt(0);
if(command == 'Q'){
basePosDest = 90;
hombroPosDest = 90;
codoPosDest = 120;
manoPosDest = 10;
}
if(command == 'W'){
Serial.print("S1 Base: ");
Serial.print(basePosDest);
Serial.print(" [");
Serial.print(basePosMin);
Serial.print(" - ");
Serial.print(basePosMax);
Serial.println("]");

Serial.print("S2 Codo: ");


Serial.print(codoPosDest);
Serial.print(" [");
Serial.print(codoPosMin);
Serial.print(" - ");
Serial.print(codoPosMax);
Serial.println("]");

Serial.print("S3 Hombro: ");


Serial.print(hombroPosDest);
Serial.print(" [");
Serial.print(hombroPosMin);
Serial.print(" - ");
Serial.print(hombroPosMax);
Serial.println("]");

Serial.print("S4 Mano: ");


Serial.print(manoPosDest);
Serial.print(" [");
Serial.print(manoPosMin);
Serial.print(" - ");
Serial.print(manoPosMax);
Serial.println("]");
}
if(command == 'S'){
// Se separa la información de servo y ángulo
// Se obtiene el índice del servo a partir del segundo caracter
int servoIndex = data.charAt(1) - '0';
// Se obtiene el ángulo a partir del cuarto caracter hasta el final
int angle = data.substring(3).toInt();

// Se actualiza la posición deseada del servo correspondiente


switch (servoIndex) {
case 1:
basePosDest = angle;
if(basePosDest > basePosMax){
basePosDest = basePosMax;
}
if(basePosDest < basePosMin){
basePosDest = basePosMin;
}
break;
case 2:
codoPosDest = angle;
if(codoPosDest > codoPosMax){
codoPosDest = codoPosMax;
}
if(codoPosDest < codoPosMin){
codoPosDest = codoPosMin;
}
break;
case 3:
hombroPosDest = angle;
if(hombroPosDest > hombroPosMax){
hombroPosDest = hombroPosMax;
}
if(hombroPosDest < hombroPosMin){
hombroPosDest = hombroPosMin;
}
break;
case 4:
manoPosDest = angle;
if(manoPosDest > manoPosMax){
manoPosDest = manoPosMax;
}
if(manoPosDest < manoPosMin){
manoPosDest = manoPosMin;
}
break;
default:
break;
}
}
}

// Función que actualiza la posición de los servos


void ActualizarServos() {
if (basePos < basePosDest) {
basePos++;
} else if (basePos > basePosDest) {
basePos--;
}
baseServo.write(basePos);

if (hombroPos < hombroPosDest) {


hombroPos++;
} else if (hombroPos > hombroPosDest) {
hombroPos--;
}
hombroServo.write(hombroPos);

if (codoPos < codoPosDest) {


codoPos++;
} else if (codoPos > codoPosDest) {
codoPos--;
}
codoServo.write(codoPos);

if (manoPos < manoPosDest) {


manoPos++;
} else if (manoPos > manoPosDest) {
manoPos--;
}
manoServo.write(manoPos);

También podría gustarte