142.03.joystick

= = =** Joystick Arduino **=

Sumário:

=Grupo= =Dispositivo= =Projeto= =Resumo= =Softwares e materiais utilizados= =Metodologia= =Desenvolvimento e Resultados= =Conclusão=


 * GRUPO:**

Amanda Nunciaroni 0040441123011 André Ventura de Mello 0040961313004 Felipe Aleoni Tamasi 0040961313010 Gabriel Henrique Dalposso 0040961313015 Guilherme Domingues Lima 0040961313019


 * DISPOSITIVO:**






 * PROJETO:**


 * Layout dos Materiais**



=
O controle possui quatro botões de ação (representados em círculos vermelhos), um direcional analógico (representado em círculo preto e quadrado azul) e dois botões de sistema (representados em círculos pretos e quadrados cinzas). ===== A disposição dos botões foi escolhida de acordo com o padrão de controles já utilizados por desenvolvedores conhecidos. A placa de madeira conterá todos os botões na parte da frente enquanto a placa do Arduino (representado pelo bloco azul) e o armazenamento das pilhas (representado pelo bloco preto) ficarão dispostos no lado oposto, como mostra a imagem a seguir:




 * RESUMO:**

O projeto consiste em um controle de videogame sem fio, construído em Arduino, composto de um Joystick, seis botões, e um transceptor. O controle se comunicará através de outro Arduino, conectado num computador. O primeiro passo é criar um controle sem fio capaz de controlar o mouse do computador usando um joystick e um botão. O segundo passo é transformar os controles do mouse em algo mais complexo e próximo de um controlador de videogame que possa substituir os comandos dados em um teclado de computador durante o jogo.


 * SOFTWARES E MATERIAIS UTILIZADOS:**


 * Softwares:**
 * [|Processing 2.2.1]
 * [|Arduino 1.0.6]
 * [|Standard Firmata 334]

Segue lista com os materiais necessários e a quantidade para a conclusão do projeto. Os itens abaixo são para fazer, tanto o controlador do mouse, quanto o do videogame:
 * Materiais:**
 * 2 Placas Arduino Nano ATMega328
 * 2 Transceptor de Rádio
 * 1 Joystick
 * 6 Botões
 * 1 Adaptador de pilhas paralelas para entrada de energia do Arduino
 * 1 Adaptador USB para mini-USB
 * 2 Pilhas AA
 * Cabos conectores
 * 1 Placa de madeira de, aproximadamente, 15 cm x 7,5 cm


 * METODOLOGIA:**


 * Divisão do Projeto**

O projeto será dividido em cinco partes, uma para cada integrante do grupo. As partes serão:
 * A comunicação entre transceptores (André de Mello),
 * O Joystick (Guilherme Domingues),
 * O Processing (Gabriel Dalposso) e
 * Os botões (Amanda Nunciaroni e Felipe Tamasi)


 * DESENVOLVIMENTO E RESULTADOS:**


 * 25/09/2014**

A intenção era fazer o controlador de mouse. Iniciamos utilizando uma placa Arduino Nano ATMega328, um //joystick// e um cabo USB além do software Processing 2.2.1 e Arduino 1.0.6.
 * Objetivo:**

Inicialmente, pesquisamos bibliotecas no Processing que utilizassem o mouse como output, ou seja, que simulassem os movimentos do mouse. Não foi possível encontrá-las, porém, no Arduino, encontramos a biblioteca //Mouse and Keyboard Control//. Com essa biblioteca podemos utilizar o Arduino para o proposito que queríamos com o Processing. Dentro da página havia exemplos que implementavam essa biblioteca, dentre eles, o //JoystickMouseControl//. Utilizamos esse exemplo para criar o código abaixo:
 * Resultado:**

code format="java" /* JoystickMouseControl

Controls the mouse from a joystick on an Arduino Leonardo or Micro. Uses a pushbutton to turn on and off mouse control, and a second pushbutton to click the left mouse button

Hardware: * 2-axis joystick connected to pins A0 and A1 * pushbuttons connected to pin D2 and D3

The mouse movement is always relative. This sketch reads two analog inputs that range from 0 to 1023 (or less on either end) and translates them into ranges of -6 to 6. The sketch assumes that the joystick resting values are around the middle of the range, but that they vary within a threshold.

WARNING: When you use the Mouse.move command, the Arduino takes over your mouse! Make sure you have control before you use the command. This sketch includes a pushbutton to toggle the mouse control state, so you can turn on and off mouse control.

created 15 Sept 2011 updated 28 Mar 2012 by Tom Igoe

this code is in the public domain

*/

// set pin numbers for switch, joystick axes, and LED: const int switchPin = 2;     // switch to turn on and off mouse control const int mouseButton = 3;   // input pin for the mouse pushButton const int xAxis = A0;        // joystick X axis const int yAxis = A1;        // joystick Y axis const int ledPin = 5;        // Mouse control LED

// parameters for reading the joystick: int range = 12;              // output range of X or Y movement int responseDelay = 5;       // response delay of the mouse, in ms int threshold = range/4;      // resting threshold int center = range/2;        // resting position value

boolean mouseIsActive = false;   // whether or not to control the mouse int lastSwitchState = LOW;       // previous switch state

void setup { pinMode(switchPin, INPUT);      // the switch pin pinMode(ledPin, OUTPUT);        // the LED pin // take control of the mouse: Mouse.begin; }

void loop { // read the switch: int switchState = digitalRead(switchPin); // if it's changed and it's high, toggle the mouse state: if (switchState != lastSwitchState) { if (switchState == HIGH) { mouseIsActive = !mouseIsActive; // turn on LED to indicate mouse state: digitalWrite(ledPin, mouseIsActive); } }  // save switch state for next comparison: lastSwitchState = switchState;

// read and scale the two axes: int xReading = readAxis(A0); int yReading = readAxis(A1);

// if the mouse control state is active, move the mouse: if (mouseIsActive) { Mouse.move(xReading, yReading, 0); }

// read the mouse button and click or not click: // if the mouse button is pressed: if (digitalRead(mouseButton) == HIGH) { // if the mouse is not pressed, press it: if (!Mouse.isPressed(MOUSE_LEFT)) { Mouse.press(MOUSE_LEFT); } }  // else the mouse button is not pressed: else { // if the mouse is pressed, release it: if (Mouse.isPressed(MOUSE_LEFT)) { Mouse.release(MOUSE_LEFT); } }

delay(responseDelay); }

/* reads an axis (0 or 1 for x or y) and scales the analog input range to a range from 0 to */

int readAxis(int thisAxis) { // read the analog input: int reading = analogRead(thisAxis);

// map the reading from the analog input range to the output range: reading = map(reading, 0, 1023, 0, range);

// if the output reading is outside from the // rest position threshold, use it: int distance = reading - center;

if (abs(distance) < threshold) { distance = 0; }

// return the distance for this axis: return distance; } code

Foi necessário requisitar ao professor uma nova placa, pois a biblioteca só poderia ser usada com os Arduinos Leonardo, Micro ou Due. O professor sugeriu a ideia de simular um mouse dentro da tela do Processing com um ponto ou uma forma geométrica plana. A ideia sugerida foi realizada dessa maneira:

code format="java" import processing.serial.*; import cc.arduino.*; //importa todas as partes das bibliotecas necessarias para funcionar o codigo

Arduino arduino; color off=color(4,79,111); int circX = 0; //Posicao do circulo no eixo X int circY = 0; //Posicao do circulo no eixo Y

void setup{ size(1280,720); background(off); println(Arduino.list); //Imprime as portas disponiveis a selecionada no programa do arduino deve estar listada

arduino = new Arduino(this, "COM4", 57600); //instancia o objeto criado anteriormente e define a porta em [4]

for(int i=0; i<=13;i++){ arduino.pinMode(i, Arduino.INPUT); //seta todos as portas do objeto arduino como input. Se quiser mudar, precisa criar uma exce??o }

}

void draw{ int arduinoX = arduino.analogRead(2); int arduinoY = arduino.analogRead(1); //Associa os valores da entrada analogica a variavel

circX = circX+((arduinoX-510)/50); circY = circY-((arduinoY-519)/50); //Define o novo valor da posicao do circulo a cada vez que draw roda. //O valor vai ser o anterior, mais o valor das entradas analogicas if(circX>width){ circX=width; } else if(circX<0){ circX=0; } else if(circY>height){ circY=height; } else if(circY<0){ circY=0; }   //Impede que o circulo saia do canvas background(off); text("EntradaX: " + arduinoX, width/2, height/2); text("EntradaY: " + arduinoY, 10, 10); ellipse(circX, circY, 10, 10); //desenha o circulo } code


 * 23/10/2014**

Emular o ponteiro do mouse com a classe ROBOT do java, utilizando o Arduíno e com programa //Firmata// e o //Processing// com a implementação da classe.
 * Objetivo:**

O código, escrito por Guilherme, inicialmente, emulava a movimentação do mouse. O código foi testado e os botões direito e esquerdo foram implementados. Apesar da dificuldade inicial, o código foi compilado com sucesso:
 * Resultados:**

code format="java" /* Utilizei o código anterior que movia o circulo pela tela e passei os valores recebidos e calculados para a classe Robot do JAVA para realizar o movimento do mouse

import processing.serial.*; import cc.arduino.*; import java.awt.*; //esse e o de baixo é necessário para utilizar a classe robot import java.awt.event.*;

color off=color(4,79,111);

Robot myRobot;

Arduino arduino; int posX, posY; //armazenará a posição que será passada ao mouse

void setup{ size(150,150); frame.setState(Frame.ICONIFIED);//inicializa minimizado

//necessário para inicializar o objeto Robot try { myRobot = new Robot; myRobot.setAutoDelay(0); } catch (Exception e) { e.printStackTrace; }

println(Arduino.list); arduino = new Arduino(this, "COM3", 57600); for(int i=0; i<=13;i++){ arduino.pinMode(i, Arduino.INPUT); //seta todos as portas do objeto arduino como input. Se quiser mudar, precisa criar uma exceção }

//inicia o cursor no centro da tela posX=displayWidth/2; posY=displayHeight/2; }

void draw{ background(off); //posiciona a janela no centro da tela frame.setLocation(displayWidth/2-width/2,displayHeight/2-height/2);

int i = 1; int arduinoX=arduino.analogRead(2); int arduinoY=arduino.analogRead(1); int arduinobtn1=arduino.digitalRead(3); int arduinobtn2=arduino.digitalRead(4);

//while para devolver o controle do mouse assim que fechar o programa while(i!=0){ posX+=(arduinoX-510)/50; posY+=(arduinoY-510)/50;

if(posX>displayWidth){ posX=displayWidth; }else if(posX<0){ posX=0; }   if(posY>displayHeight){ posY=displayHeight; }else if(posY<0){ posY=0; }

//passa a posição para o objeto mover o cursor myRobot.mouseMove(posX, posY); if(arduinobtn1==1){ myRobot.mousePress(InputEvent.BUTTON1_MASK); delay(100); myRobot.mouseRelease(InputEvent.BUTTON1_MASK); }   if(arduinobtn2==1){ myRobot.mousePress(InputEvent.BUTTON2_MASK); delay(100); myRobot.mouseRelease(InputEvent.BUTTON2_MASK); }   i=0;

//exibe na tela a posição atual do cursor text("Position: " + posX + ", " + posY, 10, height/2); text("1: " + arduinobtn1 + " - 2: " + arduinobtn2, 10, 10); } } code


 * 06/11/2014**

Iniciar a emulação do controle.
 * Objetivo:**

Ainda utilizando a classe ROBOT do JAVA, programamos no //Processing// um código para emular o //joystick.// Mantivemos o F//irmata// no Arduíno e desenvolvemos o seguinte código no Processing para usar os valores recebidos do joystick e dos seis botões:
 * Resultados:**

code format="java" /* Utilizei o código anterior que movia o circulo pela tela e passei os valores recebidos e calculados para a classe Robot do JAVA para realizar o movimento do mouse

import processing.serial.*; import cc.arduino.*; import java.awt.*; //esse e o de baixo é necessário para utilizar a classe robot import java.awt.event.*; import java.awt.event.KeyEvent;

color off=color(4,79,111);

Robot myRobot;

Arduino arduino; int posX, posY; //armazenará a posição do joyStick

void setup{ size(150, 300); frame.setState(Frame.ICONIFIED); //inicializa minimizado

//necessário para inicializar o objeto Robot try { myRobot = new Robot; myRobot.setAutoDelay(0); } catch (Exception e) { e.printStackTrace; }

println(Arduino.list); arduino = new Arduino(this, "COM4", 57600); for(int i=0; i<=13;i++){ arduino.pinMode(i, Arduino.INPUT); //seta todos as portas do objeto arduino como input. Se quiser mudar, precisa criar uma exceção }

//inicia o cursor no centro da tela // posX=displayWidth/2; // posY=displayHeight/2; }

void draw{ background(off); //posiciona a janela no centro da tela frame.setLocation(displayWidth/2-width/2,displayHeight/2-height/2);

int i = 1; int arduinoY=arduino.analogRead(1); int arduinoX=arduino.analogRead(2);

int arduinobtnZ=arduino.digitalRead(0); int arduinobtnX=arduino.digitalRead(1); int arduinobtnA=arduino.digitalRead(2); int arduinobtnS=arduino.digitalRead(3); int arduinobtnQ=arduino.digitalRead(4); int arduinobtnW=arduino.digitalRead(5);

//while para devolver o controle do mouse assim que fechar o programa while(i!=0){ posX=arduinoX; posY=arduinoY;

//passa a posição para o objeto mover o cursor

if(arduinobtnZ==1){ myRobot.keyPress(KeyEvent.VK_Z); delay(100); myRobot.keyRelease(KeyEvent.VK_Z); }   if(arduinobtnX==1){ myRobot.keyPress(KeyEvent.VK_X); delay(100); myRobot.keyRelease(KeyEvent.VK_X); }   if(arduinobtnA==1){ myRobot.keyPress(KeyEvent.VK_A); delay(100); myRobot.keyRelease(KeyEvent.VK_A); }   if(arduinobtnS==1){ myRobot.keyPress(KeyEvent.VK_S); delay(100); myRobot.keyRelease(KeyEvent.VK_S); }   if(arduinobtnQ==1){ myRobot.keyPress(KeyEvent.VK_Q); delay(100); myRobot.keyRelease(KeyEvent.VK_Q); }   if(arduinobtnW==1){ myRobot.keyPress(KeyEvent.VK_W); delay(100); myRobot.keyRelease(KeyEvent.VK_W); }   if(posX>920){ myRobot.keyPress(KeyEvent.VK_RIGHT); delay(100); myRobot.keyRelease(KeyEvent.VK_RIGHT); }   if(posX<100){ myRobot.keyPress(KeyEvent.VK_LEFT); delay(100); myRobot.keyRelease(KeyEvent.VK_LEFT); }   if(posY>920){ myRobot.keyPress(KeyEvent.VK_UP); delay(100); myRobot.keyRelease(KeyEvent.VK_UP); }   if(posY<100){ myRobot.keyPress(KeyEvent.VK_DOWN); delay(100); myRobot.keyRelease(KeyEvent.VK_DOWN); }

i=0;

//exibe na tela a posição atual do cursor text("Position: " + posX + ", " + posY, 10, height/2); text("B: " + arduinobtnZ + ", " + arduinobtnX + ", " + arduinobtnQ + ", " +arduinobtnW+",   "+arduinobtnA+", "+arduinobtnS, 10, (height/2)+30); } }

code


 * 13/11/2014**

Desenvolver, usando dispositivos de rádio, a comunicação entre dois Arduinos para criar um controle sem fio.
 * Objetivo:**

Para usar os dispositivos de rádio, foi necessário utilizar a biblioteca //VirtualWire//. Esta biblioteca utiliza o mesmo //timer// do Arduino que a biblioteca //Servo//. Dessa forma, para usar o Arduino receptor, foi preciso modificar o //Firmata,// removendo a utilização da biblioteca //Servo//, já que não foi utilizada no projeto. O recebimento dos sinais de radio do controle foi implementado. No Arduino transmissor, que é o dispositivo montado para ser o controle sem fio, foi desenvolvido o código para obter os valores dos botões e do //joystick// e transmitir pelo rádio para o receptor. Durante as fases de teste, vários problemas ocorreram com as ferramentas que não permitiram chegar a um resultado satisfatório.
 * Resultados:**


 * 26/11/2014**

Finalizar a comunicação sem fio entre os dispositivos de rádio.
 * Objetivo:**

Mesmo depois de testar os códigos a seguir, que prometiam uma fácil comunicação com um alcance de, aproximadamente, 150 metros, não houve conexão entre o transmissor e o receptor.
 * Resultados:**

code format="c" void setup{ vw_setup(2000); // bps } void loop{ send("hello world"); //your message delay(1000); } void send (char *message){ vw_send((uint8_t *)message, strlen(message)); vw_wait_tx; } code
 * 1) include 

Foi feito o upload do código acima no Arduino conectado ao transmissor e o receptor foi conectado à placa dessa maneira:



O terceiro e último passo foi fazer o upload do código a seguir no Arduino conectado ao receptor:

code format="c" byte message[VW_MAX_MESSAGE_LEN]; byte messageLength = VW_MAX_MESSAGE_LEN; void setup{ Serial.begin(9600); Serial.println("Device is ready"); vw_setup(2000); //bps vw_rx_start; } void loop{ if (vw_get_message(message, &messageLength)){ Serial.print("Received: "); for (int i = 0; i < messageLength; i++){ Serial.write(message[i]); }     Serial.println; } } code
 * 1) include 

Com o código acima, o Arduíno conectado ao transmissor deveria enviar uma mensagem ao receptor com um delay de um segundo entre as transmissões. Recebendo o valor, o Arduíno com o receptor conectado ao computador, o imprimiria no //Monitor Serial// (disponível com o programa do Arduíno). Isso faria com que a mensagem fosse exibida a cada um segundo no Console aberto no computador. Porém, ao transferir os códigos para os respectivos Arduínos e ao abrir o console, nada foi exibido.

O grupo decidiu eliminar o recurso sem fio do controle e focar nos métodos de entrada do controle. O projeto foi finalizado sem a comunicação sem fio entre os dispositivos.


 * CONCLUSÃO:**

O grupo criou um controle utilizando a plataforma Arduino que contém um //joystick// e quatro botões. Dos quatro botões principais, funcionaram dois com um pequeno atraso entre a realização do comando e a impressão da variável na janela do //Processing//. Já os dois botões secundários foram totalmente capazes de reconhecer os comandos quando pressionados, portanto foi utilizado somente os quatro principais. Quanto ao direcional analógico, funcionou perfeitamente.