Braço/Garra

Uma boa aquisição para testes e desenvolvimentos de conhecimentos e práticas na área robótica: garra mecânica com seis graus de liberdade.
.
 Vem sem manual de montagem será um enigma montá-lo, dado a quantidade de peças que fazem parte deste conjunto mecânico.
Este conjunto custa lá fora US$ 63,84.
 Observe que falta uma aste metálica na pinça inferior da garra logo, ela não se movimenta.
 Uma falha do sistema de qualidade muito gritante.

Foi confirmar com um colega que comprou uma desta garras e vi que eu estava errado no conceito logo, o mecanismo esta correto. Por não ter manual e não achá-lo em lugar nenhum da página do vendedor conclui a falta da peça que não é verdade.

Chegaram os seis motores e iniciou a novela para montar o braço mecânico. Novela pois o fabricante não enviou o manual de montagem.
Tem que ficar buscando na internet montagens para ir pegando ideias de como montar.



Para a ativação das funções computorizada são necessárias algumas eletrônicas.

 Uma placa com conexão com a placa Arduino Duemilinove.


Conector dos servomotores.

Conector dos dados das placas de extensão. 


Conector da fonte externa da placa de extensão.


Documentação sempre demora muito tempo mas é extremamente recomendável que se faça uma no final o tempo não será perdido.

Foi necessário desenvolver uma nova placa auxiliar para o controle da braço/garra. Porque a outra foi projetada para o Arduino Duemilinove que queimou.


Executar estas tarefas no final de semana tem isto de ruim se não tiver o material necessário trava tudo. Para não ficar parado o jeito é desmontar um projeto antigo que se serviu no passado.


Teremos a disposição seis conectores para os servo-motores e um conector para os potenciometros que irão interfacear o sistema com o homem. Com alimentação separada da potência de controle.

A placa auxiliar com a identificação dos conectores.



Placa com conjunto de soquetes para os servo-motores de alimentação de 5VCC. Disposição dos conectores desta placa auxiliar.

O conector 7 aloja as conexões dos potenciometros que irão controlar os movimentos das partes do braço/garra. Logo, serão seis potenciometros ligados nas entradas analógicas de A0 a A5.





Para controlar os servo-motores através dos potenciometros é necessário desenvolver alguns padrões e conversões nos valores lidos e estimados.


Os potenciômetros de controle dos servomotores serão alojados em uma base de plástico.


O botão preto ordena o sistema memorizar as posições dos servomotores e o botão verde ordena executar as posições memorizadas.







Não dá para começar a digitar o programa sem termo antes um plano básico, para tanto desenvolvi um fluxo grama para este fim, mostrado na figura.


O código para o MAP é listado abaixo:


#include <Servo.h>

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;

int valorAnalogicoMatriz[6] = {0,0,0,0,0,0};//valores analogicos lidos.
int pinoAnalogicoMatriz[6] = {A0,A1,A2,A3,A6,A7};//pinos analogicos. Obs: pino A4 e A5 sao tambem TWI.

int valorPoteLido = 0;
const int valorCompensacao = 5;//valor de ajuste que eh a metade do fundo da escala do CAD dividido pelos graus de cada lado (1024/2/90=5,689).
int valorResultado = 0;

int potenciometrosMatriz[6] = {0,0,0,0,0,0};//valores atuais lidos dos pontenciometros.
int valorPoteAntigoMatriz[6] = {0,0,0,0,0,0};//valor antigo enviado ao PWM.
int memorizacao[6] = {0,0,0,0,0,0};//guarda as posiçoes dos potenciometros.

const int pinoBotaoMemoriza = 2;//atmega pino 32
const int pinoBotaoDesmemoriza = 8;//atmega pino 12
const int pinoLed = 13;//atmega pino 17 / sck

void setup()
{// codigo de configuraçao.
//PWMs
  servo1.attach(3);//atmega pino 1
  servo2.attach(5);//atmega pino 9
  servo3.attach(6);//atmega pino 10
  servo4.attach(9);//atmega pino 13
  servo5.attach(10);//atmega pino 14
  servo6.attach(11);//atmega pino 15 / mosi
//pinos de E/S
  pinMode(pinoBotaoDesmemoriza, INPUT);
  pinMode(pinoBotaoMemoriza, INPUT);
 
  Serial.begin(9600);
  pinMode(pinoLed, OUTPUT);
}

void lepotenciometros()
{
  for (int i=0; i<6; i++)
  {
    valorAnalogicoMatriz[i] = analogRead(pinoAnalogicoMatriz[i]);
    valorPoteLido = valorAnalogicoMatriz[i];
    valorResultado = map(valorPoteLido, 0, 1023, 0, 179);//CAD intervalos de 1024 e graus intervalos de 0 a 180.
    if (potenciometrosMatriz[i] != valorResultado)     //para nao ficar salvando atoa.
    {
      potenciometrosMatriz[i] = valorResultado;      //salva na matriz.
    }
    //Serial.print("Pote");
    //Serial.print(i);
    //Serial.print(": ");
    //Serial.println(potenciometrosMatriz[i]);
    delay(15);
  }
}

void defineposicao()
{
  if (valorPoteAntigoMatriz[0] != potenciometrosMatriz[0])//se diferente muda seno nao faz nada.
    {
      servo1.write(potenciometrosMatriz[0]);              //atualiza o PWM.
      valorPoteAntigoMatriz[0] = potenciometrosMatriz[0]; //registra a posiçao do servomotor 1.
      Serial.print("Servo1: ");
      Serial.println(potenciometrosMatriz[0]);
    }
   
  if (valorPoteAntigoMatriz[1] != potenciometrosMatriz[1])//se diferente muda seno nao faz nada.
    {
      servo2.write(potenciometrosMatriz[1]);              //atualiza o PWM.
      valorPoteAntigoMatriz[1] = potenciometrosMatriz[1]; //registra a posiçao do servomotor 2.
      Serial.print("Servo2: ");
      Serial.println(potenciometrosMatriz[1]);
    }
   
  if (valorPoteAntigoMatriz[2] != potenciometrosMatriz[2])//se diferente muda seno nao faz nada.
    {
      servo3.write(potenciometrosMatriz[2]);              //atualiza o PWM.
      valorPoteAntigoMatriz[2] = potenciometrosMatriz[2]; //registra a posiçao do servomotor 3.
      Serial.print("Servo3: ");
      Serial.println(potenciometrosMatriz[2]);
    }

  if (valorPoteAntigoMatriz[3] != potenciometrosMatriz[3])//se diferente muda seno nao faz nada.
    {
      servo4.write(potenciometrosMatriz[3]);              //atualiza o PWM.
      valorPoteAntigoMatriz[3] = potenciometrosMatriz[3]; //registra a posiçao do servomotor 4.
      Serial.print("Servo3: ");
      Serial.println(potenciometrosMatriz[4]);
    }

  if (valorPoteAntigoMatriz[4] != potenciometrosMatriz[4])//se diferente muda seno nao faz nada.
    {
      servo5.write(potenciometrosMatriz[4]);              //atualiza o PWM.
      valorPoteAntigoMatriz[4] = potenciometrosMatriz[4]; //registra a posiçao do servomotor 5.
      Serial.print("Servo5: ");
      Serial.println(potenciometrosMatriz[4]);
    }

  if (valorPoteAntigoMatriz[5] != potenciometrosMatriz[5])//se diferente muda seno nao faz nada.
    {
      servo6.write(potenciometrosMatriz[5]);              //atualiza o PWM.
      valorPoteAntigoMatriz[5] = potenciometrosMatriz[5]; //registra a posiçao do servomotor 6.
      Serial.print("Servo6: ");
      Serial.println(potenciometrosMatriz[5]);
    }
   
  delay(10);//espera somente uma vez depois de todos os servos posicionados.
}

void memoriza()
{
    for (int i=0; i<6; i++)//6 servomotores 6 variaveis.
    {
      int tempor = potenciometrosMatriz[i];//armazena as posiçoes dos potenciometros.
      memorizacao[i] = tempor;             //salva a posiçao do servomotor na matriz.
    }
}

void desmemoriza()
{
  for (int i=0; i<6; i++)//6 servomotores 6 variaveis.
    {
      int tempor = memorizacao[i];      //le a posiçao do potenciometro memorizada.
      potenciometrosMatriz[i] = tempor; //carrega as posiçoes do servomotor na matriz.
    }
  defineposicao(); //executa as movimentaçoes dos servomotores.
}

void tratabotoes()
{
  int botaoMemo = digitalRead(pinoBotaoMemoriza);  //nova situaçao.
  if (botaoMemo == LOW)
  {
    memoriza();
  }
 
  int botaoDesMemo = digitalRead(pinoBotaoDesmemoriza);  //nova situaçao.
  if (botaoDesMemo == LOW)
  {
    desmemoriza();
  }
  delay(20);
}

void loop()
{// codigo que executa repetidamente.
  digitalWrite(pinoLed, HIGH);
  lepotenciometros();   //le os valores e armazena na matriz.
  defineposicao();      //atualiza as posiçoes dos servos.
  digitalWrite(pinoLed, LOW);
  delay(500);
}



Este código não foi testado na prática foi apenas compilado e esta livre de erros na codificação na IDE Arduino.



O braço/garra apresenta movimentos aleatórios em função da leitura dos potenciômetros via CAD  que o denominei de mal de Parkinson. Para não incorporar alguma eletrônica para solucionar o problema estou tentando resolvê-lo por meio de código. A ideia é realizar várias leituras e com a média ponderada destes realizar o posicionamento dos servomotores.


int valorPoten[10] = {0,0,0,0,0,0,0,0,0,0};//10 valores atuais lidos o mesmo potenciômetro.


void lepote10vezes(int pote)
//Le 10 vezes o potenciometro especificado no parametro e salva-os na matriz padrão.
{
  for (int contador=0; contador<10; contador++)//carrega a matriz com 10 leituras dos potenciometros.
  {
    valorPoteLido = analogRead(pinoAnalogicoMatriz[pote]);//le o pote x.
    valorResultado = map(valorPoteLido, 0, 1023, 0, 179);//CAD intervalos de 1024 e graus intervalos de 0 a 180.
    valorPoten[contador] = valorResultado;
    delay(20);//espera CAD estabilizar.
  }
}

int calculamediavalorpote()
// Calculo a media dos 10 valores da matriz padrão.
{
  valorResultado = 0;
  for (int i=0; i<9; i++)
  {
    valorResultado += valorPoten[i];//soma par de valores.
  }
  return (valorResultado / 10);//media entre 10 valores.
}

void valorespotenciometros()
{
  for (int pote=0; pote<6; pote++)
  {
    lepote10vezes(pote);//carrega a matriz com 10 valores do pote x.
    potenciometrosMatriz[pote] = calculamediavalorpote();//salva a media ponderada dos valores do pote x.
  }
}



A versão atual fica sendo:

#include <Servo.h>

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;

int pinoAnalogicoMatriz[6] = {A0,A1,A2,A3,A6,A7};//pinos analogicos. Obs: pino A4 e A5 sao tambem TWI.

int valorPoteLido = 0;
int valorResultado = 0;

int potenciometrosMatriz[6] = {0,0,0,0,0,0};//valores atuais lidos dos pontenciometros.
int valorPoteAntigoMatriz[6] = {0,0,0,0,0,0};//valor antigo enviado ao PWM.
int valorPotenMatriz[10] = {0,0,0,0,0,0,0,0,0,0};//10 valores atuais lidos do mesmo potenciômetro.

const int pinoLed = 13;//atmega pino 17 / sck

void setup()
{// codigo de configuraçao.
//PWMs
  servo1.attach(3);//atmega pino 1
  servo2.attach(5);//atmega pino 9
  servo3.attach(6);//atmega pino 10
  servo4.attach(9);//atmega pino 13
  servo5.attach(10);//atmega pino 14
  servo6.attach(11);//atmega pino 15 / mosi
//comunicaçao.
    Serial.begin(9600);
//pinos de E/S
  pinMode(pinoLed, OUTPUT);
}

void lepote10vezes(int pote)
//Le 10 vezes o potenciometro especificado no parametro e salva-os na matriz padrão.
{
  for (int contador=0; contador<10; contador++)//carrega a matriz com 10 leituras dos potenciometros.
  {
    valorPoteLido = analogRead(pinoAnalogicoMatriz[pote]);//le o pote x.
    valorResultado = map(valorPoteLido, 0, 1023, 0, 179);//CAD intervalos de 1024 e graus intervalos de 0 a 180.
    valorPotenMatriz[contador] = valorResultado;
    delay(20);//espera CAD estabilizar.
  }
}

int calculamediavalorpote()
// Calculo a media dos 10 valores da matriz padrão.
{
  valorResultado = 0;
  for (int i=0; i<9; i++)
  {
    valorResultado += valorPotenMatriz[i];//soma par de valores.
  }
  return (valorResultado / 10);//media entre 10 valores.
}

void lepotenciometros()
//chama as demais operaçoes para realizar a tarefa de ler os potenciometros e retirar a mal de Parkison.
{
  for (int pote=0; pote<6; pote++)
  {
    lepote10vezes(pote);//carrega a matriz com 10 valores do potenciometro x.
    potenciometrosMatriz[pote] = calculamediavalorpote();//salva a media ponderada dos valores do pote x.
  }
}

void defineposicao(int posicao)
{
  if (valorPoteAntigoMatriz[posicao] != potenciometrosMatriz[posicao])//se diferente muda seno nao faz nada.
  {
    valorPoteAntigoMatriz[posicao] = potenciometrosMatriz[posicao]; //registra a posiçao do servomotor x.
    switch (posicao)
    {
      case 0:
        servo1.write(potenciometrosMatriz[0]);              //atualiza o PWM 1.
      break;
      case 1:
        servo2.write(potenciometrosMatriz[1]);              //atualiza o PWM 2.
      break;
      case 2:
        servo3.write(potenciometrosMatriz[2]);              //atualiza o PWM 3.
      break;
      case 3:
        servo4.write(potenciometrosMatriz[3]);              //atualiza o PWM 4.
      break;
      case 4:
        servo5.write(potenciometrosMatriz[4]);              //atualiza o PWM 5.
      break;
      case 5:
        servo6.write(potenciometrosMatriz[5]);              //atualiza o PWM 6.
      break;
      default:
        Serial.println("Erro no posicionameto!"); 
    }
  }
}

void mostrapotematriz()
{
  for (int i=0; i<0; i++)
  {
    Serial.print("Servo ");
    Serial.print(i);
    Serial.print(": ");
    Serial.println(potenciometrosMatriz[i]);
  }
  Serial.print("--------------");
}

void loop()
{// codigo que executa repetidamente.
  digitalWrite(pinoLed, HIGH);
  lepotenciometros();   //le os valores e armazena na matriz.
  for (int a=0; a<6; a++)
  {
    defineposicao(a);   //atualiza as posiçoes dos servos.
  }
  digitalWrite(pinoLed, LOW);
  mostrapotematriz();
  delay(50);
}



.

Um comentário:

  1. Este conjunto já vem com os motores? Qual foi o site? Será que encontro no Brasil?

    ResponderExcluir