Projetando com Arduino e Processing: Explorer 1.0 (PARTE II)
Autor: Doug | Publicado: 2012-04-11T19:41:00-03:00





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) 
&nbsp;Iniciando na programação gráfica com o processing.
&nbsp;http://processing.org/learning/basics/

&nbsp;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.
&nbsp;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 &gt;Libraries&gt; GSVideo.

&nbsp;Pronto, o código para o Arduino é o seguinte:



&nbsp;Código para o Arduino 

//código&nbsp;para&nbsp;controlar&nbsp;o&nbsp;arduino&nbsp;a&nbsp;partir&nbsp;do&nbsp;processing
//
#include&nbsp;&lt;Servo.h&gt;// inserir a biblioteca de controle dos servos

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

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


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

}

void loop() {

&nbsp;&nbsp;static int v = 0;

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

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

GSCapture&nbsp;cam;//criada variável câmera
Serial&nbsp;port;&nbsp;&nbsp;// 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&nbsp;uma&nbsp;variavel&nbsp;tipo&nbsp;cor&nbsp;para&nbsp;o&nbsp;botão


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

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


//&nbsp;Área&nbsp;para&nbsp;controle&nbsp;dos&nbsp;direcionais&nbsp;do&nbsp;robô


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

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

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

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

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

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