Skip to content

Instantly share code, notes, and snippets.

@marcotchella
Created September 29, 2016 10:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcotchella/728e44f3c015b046bc603252eab654ea to your computer and use it in GitHub Desktop.
Save marcotchella/728e44f3c015b046bc603252eab654ea to your computer and use it in GitHub Desktop.
Comunicação e interação entre Arduino e Unity3D versão 5.x
/*
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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment