Revista 100% Verde

Sencillo exobrazo

Por Soloelectronicos @soloelectronico

Puede parecer una vanalidad , pero la idea detrás de este prototipo es muy interesante pues puede suponer una ayuda importante a la movilidad pues esto puede ser especialmente importante para los ancianos y otras personas que necesitan este tipo de ayuda en la vida cotidiana.

El sistema que sugieren destaca por su simplicidad : una estructura para sujetar el brazo, un motor y una placa Arduino con su correspondiente escudo , cuyos detalles por cierto han publicado en hackaday.com ,

Nos explican que el exo-brazo buscaban que fuese relativamente barato, sencillo y potente que permitiera un uso fácil del mismo , por lo cual su construir su prototipo no deberia costar mas de 100$ ., lo cual es un precio bastante razonable sobre todo si nos vamos a soluciones qeu esta desarrollando la induistria

El desarrollo de este proyecto comienzó centrándose: más en el control del brazo y luego en el propio diseño, por lo tanto, tal vez el objetivo número 1 es que sus creadores esperarn hacer que el control de ExoArm sea tan barato y tan intuitivo como sea posible.

En el siguinte video podemos verlo en acción:

Como podemos apreciar, hay una estructura articulada de aluminio y p recisamente en la articulación esta el motor ( en el codo) , aunque sugieren que en otros diseños futuros también preveen implementar un actuador en el hombro.

Este exo-brazo tiene tambien apoyo traser o, de modo que todo el peso se distribuya uniformemente a su cuerpo siendo la capacidad de elevación alrededor de 10 kg máximo o 22 libras.

Electrónica

Sencillo exobrazo

Ademas de la placa Arduino, un componente básico es el driver del motor VNH2SP30 ,el cual es esencialmente una versión en rampa del escudo de motor Ardumoto. Esta placa se presenta como un escudo que se conecta encima de Arduino y es de bajo coste ( unos 6,5€ en Amazon).

Para este Shield se usa un par de drivers de motor de puente completo VNH2SP30. También incluye los circuitos de soporte para que esta placa sea capaz de controlar un par de motores de alta corriente. continua aunque para esta apliacion solo se usa uno .

El VIN y el motor son lanzados para terminales de tornillo de 5mm , lo que facilita la conexión de cables de mayor calibre.

Nota: Al utilizar este escudo en aplicaciones de alta demanda extrema puede ser necesario mejorar el rendimiento térmico con un disipador de calor o ventilador y soldar los cables directamente a la placa en lugar de usar un terminal de tornillo (tenga en cuenta la alta corriente de este) Sin embargo, cuando se utiliza el tablero en corrientes de hasta 6A los chips apenas llegarán a ser perceptiblemente calientes.

Resumidamente esta son algunas de las características:

  • Voltaje: max. 16V
  • Regimen de corriente: 30A maximo
  • Corriente permanente: 14 A
  • Resistencia MOSFET (solo ida): 19 m & OHgr;
  • Frecuencia PWM: 20 kHz Max.
  • Tamano placa: 6 * 5,2 * 2cm / 2,4 * 2 * 0,8pulg
  • Peso : 23 g / 0,8 oz

Respecto a Arduin o , los pines que se requieren , en la aplicación son los pines siguientes:

  • Pines 3 y 4 como salidas binarias para configuar el motor via el driver del motor
  • Pin 5 como salida analoigica para escribir el dato en el el driver del motor
  • Pin 2 como entrada analogica para el encoder solidario al eje del motor para sqaber la posicion de la articulacion
  • Pines 8 como entrada binaria para ordenar subir la articulacion via el motor
  • Pines 9 como entrada binaria para ordenar bajar la articulacion via el motor

Antes de ver el codigo es interesante apreciar como el control del motor se hace fijando los pins 3 y 4 a un valor y luego sacando un valor analogico en el pin 5

Por ejemplo parar mover arriba el motor usa esta funcion

void moveup(float writemotor){ /
writemotor = map(writemotor, 0, -80, 255, 0);
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
analogWrite(5, writemotor);

Y de forma similar para mover hacia abajo

void movedown(float writemotor){

Simplemente parar parar el motor sacamos un valor cero en el pin 5 usando esta funcion:

void stopmove(){ //parar el motor
digitalWrite(3, LOW);
digitalWrite(4, LOW);
analogWrite(5, 0);
}

Una función muy importante es conocer la posición de la articulación gracias a que hay conectado un potenciómetro al aje

Mirando el valor de la salida del potenciómetro podemos conocer el angulo gracias a la siguiente función

float computePID(int setpoint){
angle = analogRead(2);
angle = map(angle, 0, 344, 0, 90);

double time_elapsed = micros();
dtrate = (time_elapsed - last) / 1000.f;
last = time_elapsed;

float error = setpoint - angle;
errorSum += error * dtrate;
errorSum = constrain(errorSum, -255, 255);

return (Kp * error) + (Ki * errorSum);

Por ultimo en la función loop miramos los valores binarios de los pines 8 y 9 y en función de su estado llamaremos a alguna de las rutinas anteriores:

int readingUp = digitalRead(8);
int readingDown = digitalRead(9);

if(readingUp == 1 & readingDown == 0){
if(program_runtime - previousMillis > interval) {
previousMillis = program_runtime;
Step -= 5;
}

Código arduino

El procesamiento de control como decíamos se hace con un Arduino, por lo que el código es bastante fácil de entender y modificar cuanto se quiera para mejorarlo o adaptarlo a cada necesidad:

#include "MegunoLink.h" // Funciones útiles para comunicarse con MegunoLink Pro.

#include "filter.h"
#include "Servo.h"

TimePlot plot;

int potVal;
int angle;
float dtrate;
double last;

ExponentialFilter FilteredMuscleValue(5, 20); // peso de la derecha, valor de inicio i zquierdo

void moveup(float writemotor){ //mover arriba el motor
writemotor = map(writemotor, 0, -80, 255, 0);
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
analogWrite(5, writemotor);

}

void stopmove(){ //parar el motor
digitalWrite(3, LOW);
digitalWrite(4, LOW);
analogWrite(5, 0);
}

void movedown(float writemotor){ //mover hacia abajo

writemotor = map(writemotor, 0,-255, 0, 255);
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
analogWrite(5, writemotor);
}

float errorSum;
float Kp = 2;
float Ki = 0;

float computePID(int setpoint){ //función de calculo de la posición del encoder
angle = analogRead(2);
angle = map(angle, 0, 344, 0, 90); // dejanski kot
Serial.print(angle);

double time_elapsed = micros();
dtrate = (time_elapsed - last) / 1000.f;
last = time_elapsed;

float error = setpoint - angle;
errorSum += error * dtrate;
errorSum = constrain(errorSum, -255, 255);
//Serial.println(error);
return (Kp * error) + (Ki * errorSum);

// Serial.println(time_elapsed, 5);
}

int Step = 0;

void setup() //inicializacion del brazo
{
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
Serial.begin(9600);
Step = 0;
}

int k = 1;
int previousMillis = 0;
int interval = 50;

void loop() //bucle principal de ejecución
{
int program_runtime = millis();

int readingUp = digitalRead(8);
int readingDown = digitalRead(9);

if(readingUp == 1 & readingDown == 0){
if(program_runtime - previousMillis > interval) {
previousMillis = program_runtime;
Step -= 5;
}

}
if(readingDown == 1 & readingUp == 0) {
if(program_runtime - previousMillis > interval) {
previousMillis = program_runtime;
Step += 5;
}

}
Step = constrain(Step, -150, 150);
if(readingDown == 0 & readingUp == 0) Step = 0;

//plot.SendData("pid", writemotor);
Serial.println(Step);
if(Step > 0) moveup(Step);
if(readingUp == 0 & readingDown == 0) stopmove();
if(Step < 0) movedown(Step);

}

Componentes necesarios

1 × calibrador de tensión con el amplificador de celda de carga
1 × Aluminio 4 x 30 x al menos 2000 mm
1 × A rduino Uno / Nano
1 × controlador de motor VNH2SP30
1 × Motor del limpiador del parabrisas del coche
1 × cables largos
1 × Potenciómetro
1 × Li-Po batería 3S 5500mAh
1 × Tornillos y tuercas. M4 y M6
1 × Cinta adhesiva
1 × Zipties
1 × Correas
1 × Placas de madera
1 × Tubo termorretráctil

En el siguiente video el autor mas detalles de contruccion de este esobrazo:

Mas información en https://hackaday.io/project/20663-assistive-exoskeleton-arm-exoarm#menu-description


Volver a la Portada de Logo Paperblog