Comunicação entre Arduino e Unity3D

unity_arduino_acel

Novas formas de interação com o computador e jogos podem ser desenvolvidas a partir da integração entre o Arduino conectado a um acelerômetro e a engine para desenvolvimento de jogos Unity3D.

Conexão do hardware

unity_arduino_acel_conexoes_eletricas

Código fonte para o Arduino

/*
Autor: Marco T. Chella
Em: 28/09/2016
Para saber mais:
*/
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
String vx = String (analogRead(A0));
String vy = String (analogRead(A1));
String vz = String (analogRead(A2));
Serial.println(vx + "," + vy + "," + vz);
delay(10); // delay in between reads for stability
}

Código fonte para o Unity3D

/*
Autor Marco T. Chella
em: 28/09/2016
Para saber mais:
*/
using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System.Threading;
public class com_serial : MonoBehaviour {
public SerialPort sp;
public Thread serialThread;
float x_mapeado;
float angleX_filtrado;
float y_mapeado;
float angley_filtrado;
void Start () {
print("app iniciando….");
x_mapeado = 0;
angleX_filtrado =0;
angley_filtrado = 0;
sp = new SerialPort("COM3", 9600);
sp.Open();
sp.ReadTimeout = 50;
sp.Handshake = Handshake.None;
serialThread = new Thread(recData);
serialThread.Start();
print("app iniciado!");
}
// Update is called once per frame
void Update () {
// atualiza posicao do cubo com valores do acelerometro ja processados
GameObject.Find("Cube").transform.rotation= Quaternion.Euler( new Vector3(x_mapeado, 0, y_mapeado));
}
public void Close()
{
sp.Close();
Debug.Log("Fechar");
}
void OnDestroy()
{
EndThread();
sp.Close();
Debug.Log("Destroi");
}
// thread da comunicacao serial
void recData()
{
string data;
while (1 == 1)
{
if ((sp != null) && (sp.IsOpen))
{
try
{
data = sp.ReadLine();
string[] tokens = data.Split(',');
// parse da string recebida do arduino ex: "125,592,8"
int eixo_x = System.Convert.ToInt16(tokens[0]);
int eixo_y = System.Convert.ToInt16(tokens[1]);
int eixo_z = System.Convert.ToInt16(tokens[2]);
float vx = (float) eixo_x * 5f / 1023f;
float vy = (float)eixo_y * 5f / 1023f;
float vz = (float)eixo_z * 5f / 1023f;
float z = 1.8f * 5.1f / 5f; //1.8 corresponde a 0G do acelerometro
vx -= z;
vy -= z;
vz -= z;
float sensitivity = 200 * 5.1f / 5f; // sensibilidade
sensitivity = sensitivity / 1000;
float gx = vx * sensitivity;
float gy = vy * sensitivity;
float gz = vz * sensitivity;
// calculo do angulo
float m = (float)System.Math.Sqrt (gx * gx + gy * gy + gz * gz);
float angleX = (float)System.Math.Acos(gx / m);
float angleY = (float)System.Math.Acos(gy / m);
float angleZ = (float)System.Math.Acos(gz / m);
// converte angulo para graus
angleX = angleX * 180f / 3.14f;
angleY = angleY * 180f / 3.14f;
angleZ = angleZ * 180f / 3.14f;
// filtro passa-baixa
float alpha = 0.1f;
angleX_filtrado = angleX * alpha + (angleX_filtrado * (1.0f alpha));
angley_filtrado = angleY * alpha + (angley_filtrado * (1.0f alpha));
//normalizar valores
x_mapeado = mapear(angleX_filtrado, 20, 166, 90, 90);
y_mapeado = mapear(angley_filtrado, 15, 160, 90, 90);
//Debug.Log(angleX + "," + x_mapeado);
//Debug.Log(angleX + "," + angleY + "," + angleZ);
Debug.Log(vx + "," + vy + "," + vz); //valor raw dos sensores
// Debug.Log(tokens[0] + "," + tokens[1] + "," + tokens[2]);
}
catch (System.TimeoutException)
{
data = null;
}
//print(data);
}
Thread.Sleep(1);
}
}
// encerrar thread
void EndThread()
{
try
{
if (serialThread.IsAlive)
{
serialThread.Abort();
Debug.Log("tentativa encerrar thread");
}
}
catch
{
Debug.Log("falha encerramento da thread");
}
}
float mapear(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x in_min) * (out_max out_min) / (in_max in_min) + out_min;
}
}

Algumas referências:

  • Datasheet módulo mma7361 (link)
  • Comunicação serial com thread no Unity3d versão 5 (link)
  • Tratamento dados do acelerômetro (link)
  • Implementação de filtro passa baixa aplicado a acelerômetro (link)

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s