quarta-feira, 11 de abril de 2012

Projetando com Arduino e Processing: Explorer 1.0 (PARTE II)


Pessoal, dando continuidade ao artigo anterior onde eu mostrei a construção do hardware do meu projeto Explorer 1.0, venho agora mostrar o código que utilizei no Processing para gerar a interface gráfica, e no Arduino para controle das instruções. Se você ainda não conhece o Processing, aconselho dar uma olhada nos seguintes links antes de continuar.
Projetando com Arduino e Processing: Explorer 1.0 (PARTE I)
 Iniciando na programação gráfica com o processing.
 http://processing.org/learning/basics/

 Criar uma comunicação entre o Arduino e o processing não é tão complicado.

Contudo para utilizar a webcam em meu projeto precisei baixar uma biblioteca de códigos própria para trabalhar com webcams e imagem. O nome da biblioteca é GSVideo e pode ser encontrada aqui.
 Após fazer o download da bilblioteca, você deve descompactá-la e copiar a pasta GSVideo para dentro da pasta "libraries", dentro da pasta Processing. O caminho até a pasta deve ficar exatamente assim Processing >Libraries> GSVideo.

 Pronto, o código para o Arduino é o seguinte:



 Código para o Arduino

//código para controlar o arduino a partir do processing
//
#include <Servo.h>// inserir a biblioteca de controle dos servos

//criando variaveis do tipo servo
Servo servo1; Servo servo2;

void setup() {
 /* abaixo, condicional for para definir as portas 
  digitais como saida*/
  for (int thisPin = 2; thisPin < 6; thisPin++) {
        pinMode(thisPin, OUTPUT);
      }
  servo1.attach(6);//servo 1 na digital 6
  servo2.attach(7);//servo 2 na digital 7
  // as portas digitais de 2 a 5 reservadas para a ponte H
  
  //posição inicial paras os servos e espera de 7 segundos
  servo1.write(100);
      servo2.write(170);
      delay(7000);


 /*iniciar a porta serial. deve estar na mesma velocidade no 
 processing*/
  Serial.begin(19200);
  Serial.println("Pronto");

}

void loop() {

  static int v = 0;

 if ( Serial.available()) {
   char ch = Serial.read();//variavel do tipo caracter criado

  switch(ch) {
  case '0'...'9':
    v = v * 10 + ch - '0';
    break;
    /* o código no processing esta programado para enviar o caractere
    "c" para variar o eixo "x" no caso o servo1, e o caractere "b" para
    variar o eixo do "y" no servo 2. sempre que o arduino receber algum 
    desses caracteres ele entenderá qual servo deve movimentar */
  case 'c':
  servo1.write(180-v);/*escrever no servo 1 o valor com 
  relação ao mouse*/
  Serial.print("c = ");
  Serial.println(v);       
     v = 0;
     break;
   case 'b':
   servo2.write(180-v);/*escrever no servo 2 o valor com 
     relação ao mouse*/
   Serial.print("b = ");
   Serial.println(v);
      v = 0;
    break;
    
    //controle dos motores do carro
    
    case 'w':
     digitalWrite(2, HIGH);//motor direito para frente
     digitalWrite(4, HIGH);//motor esquerdo para frente
     digitalWrite(3, LOW);//robô anda para frente
     digitalWrite(5, LOW);
    break;
    
    case 's':
    digitalWrite(2, LOW);//motor direito para trás
    digitalWrite(4, LOW);//motor esquerdo para trás
    digitalWrite(3, HIGH);//robô anda para trás
    digitalWrite(5, HIGH);
    break;
    
    case 'a':
    digitalWrite(2, HIGH);//motor direito para frente
    digitalWrite(4, LOW);//motor esquerdo para trás
    digitalWrite(3, LOW);//robô roda para esquerda
    digitalWrite(5, HIGH);
    break;
    
    case 'd':
    digitalWrite(2, LOW);//motor direito para trás
    digitalWrite(4, HIGH);//motor esquerdo para frente
    digitalWrite(3, HIGH);//robô roda para esquerda
    digitalWrite(5, LOW);
    break;
    
    case 'h':
    digitalWrite(2, LOW);//motor direito para trás
    digitalWrite(4, LOW);//motor esquerdo para frente
    digitalWrite(3, LOW);//robô roda para esquerda
    digitalWrite(5, LOW);
    break;
    
  Serial.flush();// apaga entrada de dados ao final do loop
  }
 }
}  
 
 
  
Após fazer o upload do código acima para o Arduino, você deve colocar o código abaixo no Processing
e então dar play no processing para rodar a interface gráfica. 
 
 Código para o Processing 
  
 
import codeanticode.gsvideo.*;//importat biblioteca de códigos para camera
import processing.serial.*;// importa biblioteca serial       

GSCapture cam;//criada variável câmera
Serial port;  // Definir variável do tipo serial
int xpos=90;  //valores iniciais dos servos
int ypos=90;
PFont fontA; // cria uma variável do tipo fonte
color corBotao1,corBotao2,corBotao3,corBotao4,corBotao5,padrao;  
//cria uma variavel tipo cor para o botão


void setup() {
  size(1260,720); //define o tamanho da tela em pixels
  smooth();
  frameRate(100);
  println(Serial.list()); // List COM-ports

  //selecionar a primeira porta serial
  port = new Serial(this, Serial.list()[0], 19200);
  //selecionar a velocidade de comunicação serial
  
  String[] cameras = GSCapture.list();//lista camêras disponíveis
  
  if (cameras.length == 0)
  {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) {
      println(cameras[i]);
    }
    cam = new GSCapture(this, 640, 480, cameras[0]);
    // atribui a variavel cam a camera listada
    cam.start(); //inicia câmera
  }
    
    
  padrao = color(0,255,0);
  corBotao1 = color(padrao);// atualiza a cor inicial do botão
  corBotao2 = color(padrao);
  corBotao3 = color(padrao);
  corBotao4 = color(padrao);
  corBotao5 = color(padrao);
  background(255,255,255);//define a cor de fundo da tela
   fontA = loadFont("TraditionalArabic-48.vlw");
   // Carrega a fonte do títulovoid draw() {
  update(mouseX, mouseY);// atualiza a posição do mouse
  fill (0); //cor do texto do título
  textFont(fontA,30)
  ;// Escrever texto com o tipo de fonte e tamanho definido
  text("Projeto Dougtek-I",width*2/5,30);
  // Posição e descrição do título


// Área para controle dos direcionais do robô


  if (key == 'w'){ 
  fill(0,0,255);//pinta da cor escolhida
  port.write("w");
  }else{
   fill(corBotao1);
   // preenche os botões com a cor escolhida caso circleover1 for false
 }
 ellipse(200,90,40,40);// Circulo imagem para botão direcional superior
  
  if (key == 's'){ 
  fill(0,0,255);//pinta da cor escolhida
  port.write("s");
  }else{
   fill(corBotao2);
 }
 ellipse(200,150,40,40);// Circulo imagem para botão direcional inferior

  
  if (key == 'a'){ 
  fill(0,0,255);//pinta da cor escolhida
  port.write("a");
  }else{
   fill(corBotao3);
 }
 ellipse(150,120,40,40);// Circulo imagem para botão direcional esquerdo

  
  if (key == 'd'){ 
  fill(0,0,255);//pinta da cor escolhida
  port.write("d");
  }else{
   fill(corBotao4);
 }
 ellipse(250,120,40,40);// Circulo imagem para botão direcional direito

  
  if (key == 'h'){ 
  fill(0,0,255);
  port.write("h");
  }else{
   fill(corBotao5);
 }
 ellipse(250,320,40,40);
 // Circulo imagem para botão direcional direito

  
 fill(0);
 textFont(fontA,20);
 text("W",190,100);
 //Letra correspondente a cada direção dentro de cada circulo
 text("S",195,160);
 text("A",145,130);
 text("D",245,130);
 text("H",242,330);
 
 // Área para posição gráfica da cãmera
 
 if (cam.available() == true) {
    cam.read();
    image(cam, 550, 50);
    /* a posição (cam,0,0) é a posição onde ficará a câmera no
    interface gráfica*/
  }
  
  
  // Rodapé
 
 fill(255,0,0);
 textFont(fontA,20);
 text(" Desenvolvido por: Douglas Rafael. Todos os direitos Reservados.",600,590);
 
}
   // Controle lógico dos botões dos direcionais
   
void update(int x, int y) 
{
   /*divide o tamanho da tela para o valor do pos entrar
  na escala de 0 a 180 do servo*/
  xpos= x/7;
  ypos=y/4;

  //saida dos valores dos servos de 0 a 180
  port.write(xpos + "c");
  port.write(ypos + "b");
} 
 
 
Qualquer dúvida, crítica ou sugestão podem postar nos comentários. Até a próxima.

5 comentários:

  1. olá adorei o blog, tenho 13 anos e me interessei vi o video seu no youtube quanto vc gastou para construir akele robô? estou querendo fazer testes pois pretende estudar e fazer alguns projetos para impressionar meus amigos e na minha aula de ciencias, como poderia construir esse robô do 0 ate o final poderia me dizer tbm as peças q foram usadas vo começar a correr atras logo depois da sua resposta. Obrigado continue assim me espelho mt em vc vlw

    ResponderExcluir
    Respostas
    1. Caro Iago, eu comprei todas as peças no www.ebay.com , comprar aqui no Brasil sai bem mais caro. Se você dominar um pouco de inglês recomendo que compre também no ebay. Para construir esse robô gastei por volta de 150 reais, mas se você comprar as peças aqui no brasil sai bem mais caro. Caso você queira comprar aqui no Brasil, te recomendo o site http://multilogica-shop.com/ possui muitas das peças que comprei e também ensina o básico sobre o arduino, e o bom que é em português. Espero ter ajudado.

      Excluir
  2. Pra Quem Curte Novidades e Notícias de Tecnologia, Social Midia, Apps, Mobile, Hackers,Big Data, Start-Ups, Web 3.0. Acesse www.techinsider.com.br

    ResponderExcluir
  3. Boas olha podes ir ao teu canal youtube eu mandei te uma MP
    meu nick Thejls94
    porque gostava que me o arranjasses o circuito please

    ResponderExcluir
  4. Boa tarde, Doug.
    Utilizei de base algumas partes do código do seu projeto para fazer um trabalho da faculdade. Adicionei algumas coisas à interface como farol, buzina e rastreamento facial. Se estiver interessado, posso te passar as modificações que fiz, como agradecimento por ter disponibilizado o seu projeto que me foi muito útil. Obrigado!

    ResponderExcluir