(Se deseja ir direto para implementação pule para o passo 1.)
A antiga(mas não ultrapassada) forma de controlar jogos através de um direcional e botões, limita a construção, ou mesmo as interações possíveis com os jogos. Visando essa sentença, cada vez mais os jogos e o entretenimento moderno está em busca por um diferencial, seja por uma característica única no software ou por uma forma diferente de construir essa interação.
A proposta a seguir visa uma diferente abordagem na construção de um controle com giroscópio e acelerômetro, mais comum em celulares ou portáteis por já conter esse tipo de ferramenta.
e BreadBoard.
1 – Materiais Utilizados
4 fios.
1 Arduino Uno.
1 Giroscopio/Acelerometro
![]() |
| Modelo utilizado: GY-521 (MPU6050) |
2 – Montagem dos materiais.
Ligamos o Giroscopio no arduino através das portas SCL e SDA. O VCC na porta de alimentação de 5V ou 3.3V e o GND no ground.
3 – Código utilizado no arduino.
Utilizando a FreeIMU library :
1: #include <ADXL345.h>
2: #include <bma180.h>
3: #include <HMC58X3.h>
4: #include <ITG3200.h>
5: #include <MS561101BA.h>
6: #include <I2Cdev.h>
7: #include <MPU60X0.h>
8: #include <EEPROM.h>
9: //#define DEBUG
10: #include "DebugUtils.h"
11: #include "FreeIMU.h"
12: #include <Wire.h>
13: #include <SPI.h>
14: float val[11]; //Vetor que irão conter as variaveis
15: FreeIMU my3IMU = FreeIMU();
16: int y = 0;
17: int z = 0;
18: int media[3];
19: void sicronizar()
20: {
21: my3IMU.getValues(val);
22: for(int i = 0; i <50; i++)
23: {
24: media[0] += map(val[0], -17090, 17090, -45, 45);
25: media[1] += map(val[1], -17090, 17090, -45, 45);
26: media[2] += map(val[2], -17090, 17090, -45, 45);
27: }
28: media[0] /= 50;
29: media[1] /= 50;
30: media[2] /= 50;
31: }
32: void setup() {
33: Serial.begin(115200);
34: Wire.begin();
35: delay(500);
36: my3IMU.init(true); // Variavel que ativa o modo rápido
37: sicronizar();
38: delay(500);
39: }
40: void loop(){
41: Serial.flush(); //Limpa o buffer.
42: my3IMU.getValues(val); //Passa o vetor como parametro
43: val[1] = map(val[1], -17090, 17090, -45, 45); /* Mapeando as variaveis */
44: val[2] = map(val[2], -17090, 17090, -45, 45); /* para ir de -45 a +45 */
45: z = val[1] - media[1];
46: y = val[2] - media[2];
47: Serial.print(y);
48: Serial.print(',');
49: Serial.println(z);
50: delay(100);
51: }
A função do algoritmo é: ler o acelerômetro, obter os valores necessários e imprimi-los na saída serial.
Pontos Relevantes:
A função “my3IMU.getValues(val);” atriubui a um vetor as as variaveis associadas ao acelerometro, giroscopio, sensor de movimento e temperatura. No caso so trabalharemos com as posições 1 e 2 (Eixo de rotação Z e Y respectivamente, pode variar com o acelerometro).
A função sicronizar() faz 50 loops pegando as variaveis de Y e Z e faz uma media nelas, para calcular a posição média inicial do acelerometro.
“Serial.print(y)”, “Serial.print(',')” e “Serial.println(z)” e imprimi em uma linha de saida serial o conteudo das variaveis y e z separados por virgula e pula a linha.
4 – Código em C# utilizado no jogo.
O jogo foi feito utilizando Unity pela facilidade de construção, e entendimento mais direcionado a comunicação e a obtenção de dados do acelerômetro. O código a seguir é utilizado no tabuleiro do jogo.Pontos Relevantes: Linha 22 à 35: Recebe os dados da porta serial, trata e usa eles para rotacionar o objeto Linha 52: transform.Rotate Rotaciona o objeto com as coordenadas atualizadas. Linha 57 à 72: Estabiliza o tabuleiro quando os angulos forem 0.1: using UnityEngine; 2: using System.Collections; 3: using System.IO.Ports; 4: public class SerialTeste : MonoBehaviour { 5: public float speed; 6: private float amountToMove; 7: SerialPort sp = new SerialPort("COM5", 115200); 8: int d = 0; 9: int dOld = 0; 10: int dY = 0; 11: int dYOld = 0; 12: int lastX = 0; 13: int lastY = 0; 14: // Use this for initialization 15: void Start () { 16: sp.Open(); 17: sp.ReadTimeout = 2; 18: } 19: // Update is called once per frame 20: void Update () { 21: amountToMove = speed * Time.deltaTime; 22: if(sp.IsOpen) { 23: try { 24: sp.DiscardOutBuffer(); 25: string value = sp.ReadLine(); 26: string[] vec2 = value.Split(','); 27: if(vec2[0] != "" && vec2[1] != ""){ 28: lastX = int.Parse(vec2[0]); 29: lastY = int.Parse(vec2[1]); 30: MoveObject(int.Parse(vec2[0]),int.Parse(vec2[1])); 31: //print ("X:"+int.Parse(vec2[0])+"Y:"+int.Parse(vec2[1])); 32: } 33: sp.BaseStream.Flush(); 34: } catch (System.Exception e) { 35: MoveObject(lastX,lastY); 36: } 37: } 38: } 39: void MoveObject(int DirectionX, int DirectionY) { 40: this.d = DirectionX; 41: this.dY = DirectionY; 42: print(this.d); 43: int rotateZ = -(this.dY - dYOld); 44: int rotateX = this.d - dOld ; 45: if((System.Math.Abs(rotateX) > 2 && System.Math.Abs(rotateX) < 45) || (System.Math.Abs(rotateZ) > 2 && System.Math.Abs(rotateZ) < 45)) 46: { 47: var newRotation = Quaternion.LookRotation(Camera.main.transform.position - transform.position).eulerAngles; 48: /*newRotation.y = 0; 49: newRotation.x = rotateX; 50: newRotation.z = rotateZ; 51: transform.rotation = Quaternion.Euler(newRotation);*/ 52: transform.Rotate( //Rotacionar a camera baseada na nova posição comentar se for usar quarternions. 53: rotateX , 54: 0, 55: rotateZ 56: ); 57: dOld = d; 58: dYOld = dY; 59: } 60: Vector3 ang = transform.localEulerAngles; 61: if (this.d == 0) 62: { 63: transform.Rotate(-ang.x,0,0); 64: } 65: if (this.dY == 0 ) 66: { 67: transform.Rotate(0,0,-ang.z); 68: } 69: if (ang.y != 0 ) 70: { 71: transform.Rotate(0,-ang.y,0); 72: } 73: } 74: }






Olá Marcelo, beleza?
ResponderExcluirParabens pelo post, gostaria de pedir seu contato para tirar umas duvidas referente ao projeto, se puder, me adciona no face https://www.facebook.com/julio.chiles ou manda um email: julio_g.angel@hotmail.com.
Ficarei muito agradecido.
E novamente, parabens pelo post