quinta-feira, 6 de janeiro de 2011

Braço Robótico USB


Olá, esse tutorial vai ensinar como controlar servos através da porta serial do arduino, esta é uma forma pouco aprimorada e possui algumas falhas, mas é funcional.





Para interagir com o arduino, criei esta interface utilizando a plataforma Processing o que tornou as coisas bem mais simples. O braço é composto por 3 servos e foi feito utilizando recortes de placas de fenolite, meu forte é elétrica então a parte mecânica ta bem feia, mas já tenho planos para aperfeiçoar. Os leds são apenas para enfeitar. O código utilizado no arduino é o seguinte:

#include
//declaração dos servos
Servo base;
Servo hand;
Servo arm;
//declaração dos leds
byte led1 = 12;
byte led2 = 13;
byte led3 = 8;

int count = 0; //contador que controlará os leds
//variáveis de controle dos servos
int ctrl1 = 90;
int ctrl2 = 90;
int ctrl3 = 90;


void setup(){
//atribui os pinos dos servos
base.attach(11);
hand.attach(10);
arm.attach(9);
//atribui os pinos dos leds
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
pinMode(led3,OUTPUT);

Serial.begin(9600);//inicia porta serial

}

void loop(){

Serial.write(255); //Diz ao software que envie a variável
delay(7);//Aguarda resposta
ctrl1 = Serial.read();//Lê a primeira variável enviada pelo Processing
Serial.write(255);//Diz que envie a proxima variável
delay(7);//Aguarda resposta
ctrl2 = Serial.read();//Lê a proxima variável
Serial.write(255);
delay(7);
ctrl3 = Serial.read();

//Envia os valores adquiridos aos servos
base.write(ctrl1);
arm.write(ctrl2);
hand.write(ctrl3);

//utiliza a variável count para acender e apagar os leds a cada 3s
if (count == 58){
digitalWrite(led3,LOW);
digitalWrite(led1,HIGH);
}
if(count == 116){
digitalWrite(led1,LOW);
digitalWrite(led2,HIGH);
}
if(count == 174){
digitalWrite(led2,LOW);
digitalWrite(led3,HIGH);
count=0;
}

count++;
delay(30);
}


Como podem ver o código é bem simples, e a comunicação é passivel de falhas como a leitura trocada das variáveis de controle, mas em grande parte do tempo o sistema funciona corretamente. A seguir o código utilizado no Processing


import processing.serial.*; //biblioteca para comunicação serial

Serial port; //declara nova comunicação serial
//variáveis de controle que serão passadas aos servos
int ctrl1 =90;
int ctrl2 =90;
int ctrl3 =90;

//declaração de imagem e fontes utilizadas na interface
PImage logo;
PFont font;
PFont font2;


void setup() {
size(600, 350); //tamanho da tela
background(200); //cor de fundo
//lê as imagens e as fontes utilizadas
logo = loadImage("logo.png");
font = loadFont("FootlightMTLight-18.vlw");
font2 = loadFont("FootlightMTLight-16.vlw");

println(Serial.list());//imprime no console as portas disponíveis

port = new Serial(this, Serial.list()[1], 9600);//inicializa conexão serial
//utilizando a porta Serial.list()[1], no meu caso a COM4

}

void draw() //loop do processing
{
background(200);//utilizado para limpar a tela a cada frame

//desenha a interface
fill(255);
rect(120,111,30,180);
rect(194,111,30,180);
rect(46,111,30,180);

image(logo,132,19);

textFont(font);
fill(10);
text("Servo Positions", 400, 98);
textFont(font2);
text("Base Servo:", 360,130);
text("Neck Servo:", 360,150);
text("Hand Servo:", 360,170);
textFont(font2);
fill(10);
text(ctrl1, 500,130);
text(ctrl2, 500,150);
text(ctrl3, 500,170);


//desenha as barras que representam a posição de cada servo

fill(100);
rect(46,291,30,-ctrl1);
rect(120,291,30,-ctrl2);
rect(194,291,30,-ctrl3);

//incrementa ou decrementa os controles utilizando o teclado

if(keyPressed) {
if ((key == 'a' || key == 'A')&&(ctrl1>0)) {
ctrl1--;
}
}
if(keyPressed) {
if ((key == 'q' || key == 'Q')&&(ctrl1<180)) { ctrl1++; } } if(keyPressed) { if ((key == 's' || key == 'S')&&(ctrl2>0)) {
ctrl2--;
}
}
if(keyPressed) {
if ((key == 'w' || key == 'W')&&(ctrl2<180)) { ctrl2++; } } if(keyPressed) { if ((key == 'd' || key == 'D')&&(ctrl3>0)) {
ctrl3--;
}
}
if(keyPressed) {
if ((key == 'e' || key == 'E')&&(ctrl3<180)) { ctrl3++; } } //envia os dados ao arduino waitSerial(); //aguarda o arduino solicitar o envio port.write(ctrl1);//envia a variável de comando //na ordem em que o arduino espera waitSerial(); port.write(ctrl2); waitSerial(); port.write(ctrl3); } void waitSerial(){ while(port.read() != 255){ delay(1); } }


Então é isso, agradeço aqueles que leram, e mais ainda aqueles que comentaram.

Obrigado!

7 comentários:

  1. Muito Bom
    Seu blog esta ajudando muito as pessoas

    ResponderExcluir
  2. Parabens pelo projeto e pelo blog
    Recentemente fiz uma pequena aplicação com motores no entanto não utilizai processing, tive que fazer a programação fora via DELPHI e acionar os motores...

    Gostaria de aprender mais sobre processing quem sabe não pode ficar como sendo um minicurso

    walleeuu By EDYBAHIA

    ResponderExcluir
  3. boa, vou estudar melhor o processing e postarei uma serie de tutoriais sobre ele. é uma plataforma bem mais simples de se trabalhar que o delphi, e até mais estavel eu acho. obrigado pela visita e pela sugestão. volte sempre \o

    ResponderExcluir
  4. egidio
    Ola man tem como voce me explica uma parte do seu codigo do braço mecanico
    é a parte de escrever na janela alguma palavra
    textFont(font);
    fill(10);
    text("Servo Positions", 400, 98);
    textFont(font2);
    text("Base Servo:", 360,130);
    text("Neck Servo:", 360,150);
    text("Hand Servo:", 360,170);
    textFont(font2);
    fill(10);
    text(ctrl1, 500,130);
    text(ctrl2, 500,150);
    text(ctrl3, 500,170);

    meu programa nao roda por causa disso
    dei uma pesquisada alterei algumas coisas e ele rodou mas a fonte de texto ficaou muito feia nem da para entender direito.
    sera que voce pode me explica isso? Como faço para altera fonte e tamanho?
    obrigado.

    ResponderExcluir
  5. Na sessão de Programação já tem posts sobre o Processing o/

    ResponderExcluir
  6. Egidio
    Caso voce tivese interesse em salvar a posicao e a velocidade do ponto como voce faria isso. voce ja vio em algum lugar algo parecido. Estou querendo fazer isso no meu projeto. Que funcao deveria utilizar?
    Obrigado.

    ResponderExcluir
  7. para salvar a posição você pode usar o ultimo valor passado ao servo, ou caso seu servo esteja sendo forçado você teria que usar uma entrada analogica para ler a posição na saida do potenciometro interno ao servo. não entendi que velocidade você quer...

    ResponderExcluir