LoginSignup
6
5

More than 5 years have passed since last update.

Arduino+LIS3DH(3軸加速度センサ)+Unityのテスト

Posted at

やった結果

ArduinoとLIS3DHの接続

Arduino LIS3DH
3.3V pin1
GND pin2
pin13 pin3
pin11 pin4
pin12 pin5
pin10 pin6

Arduinoで使ったコード

LIS3DH.ino
#include <SPI.h>

const byte R_BIT  = 0x80; // 0b10000000
const byte R_MASK = 0xBF; // 0b10111111  
const byte W_MASK = 0x3F; // 0b00111111
const byte CS = 10; // pin10
const int CTRL_REG1 = 0x20;
const int OUT_X_L = 0x28;
const int OUT_X_H = 0x29;
const int OUT_Y_L = 0x2A;
const int OUT_Y_H = 0x2B;
const int OUT_Z_L = 0x2C;
const int OUT_Z_H = 0x2D;
int x_axis = 1;
int y_axis = 2;
int z_axis = 3;

unsigned int readRegister(byte reg) {
  unsigned int result;
  reg |= R_BIT;
  reg &= R_MASK;
  digitalWrite(CS, LOW);
  SPI.transfer(reg);
  result = SPI.transfer(0x00);
  digitalWrite(CS, HIGH);
  return result;
}

void writeRegister(byte reg, byte data) {
  reg &= W_MASK;
  digitalWrite(CS, LOW);
  SPI.transfer(reg);
  SPI.transfer(data);
  digitalWrite(CS, HIGH);
}

void setup() {
  unsigned int res = 0;

  pinMode(CS, OUTPUT);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE3);
  SPI.setClockDivider(SPI_CLOCK_DIV2);

  writeRegister(CTRL_REG1, 0x27);
  res = readRegister(0x0F);

  Serial.begin(115200);
  delay(1);
}

int getValue(int axis) {
  int Val = 0;
  int h, l;
  if (axis == x_axis) {
    l = readRegister(OUT_X_L);
    h = readRegister(OUT_X_H);
  } else if (axis == y_axis) {
    l = readRegister(OUT_Y_L);
    h = readRegister(OUT_Y_H);
  } else if (axis == z_axis) {
    l = readRegister(OUT_Z_L);
    h = readRegister(OUT_Z_H);
  }
  Val = h << 8 | l;
  return Val;
}

void loop() {
  int x, y, z;

  writeRegister(CTRL_REG1, 0x27);

  x = getValue(x_axis);
  y = getValue(y_axis);
  z = getValue(z_axis);

  const int angleX = atan2(x, z) / PI * 180;
  const int angleY = atan2(y, z) / PI * 180; 

  Serial.print(angleX);
  Serial.print("\t");
  Serial.println(angleY);
  Serial.flush();

  delay(100);
}

Unityで使うC#コード

LIS3DH.cs
using System;
using System.IO.Ports;
using System.Threading;
using UnityEngine;
using System.Collections.Generic;

public class LIS3DH : MonoBehaviour {
    public const string SERIAL_PORT = "COM8";
    public const int SERIAL_BAUD_RATE = 115200;
    private const int SERIAL_TIMEOUT = 100;

    private Thread _readThread;
    private static SerialPort _serialPort;
    private static bool _continue;

    private static Quaternion _handQuaternion = new Quaternion();

    private List<Vector3> angleCache = new List<Vector3>();
    public int angleCacheNum = 10;
    public Vector3 angle {
        private set {
            angleCache.Add(value);
            if (angleCache.Count > angleCacheNum) {
                angleCache.RemoveAt(0);
            }
        }
        get {
            if (angleCache.Count > 0) {
                var sum = Vector3.zero;
                angleCache.ForEach(angle => { sum += angle; });
                return sum / angleCache.Count;
            } else {
                return Vector3.zero;
            }
        }
    }

    void Start() {
        _readThread = new Thread(Read);
        _serialPort = new SerialPort(SERIAL_PORT, SERIAL_BAUD_RATE);
        _serialPort.ReadTimeout = SERIAL_TIMEOUT;
        _serialPort.Open();
        _continue = true;
        _readThread.Start();
    }

    void Update() {
        //Debug.Log (angle);
        transform.rotation = Quaternion.Euler(angle);
    }

    void OnApplicationQuit() {
        _continue = false;
        _readThread.Join();
        _serialPort.Close();
    }

    private void Read() {
        string[] values;
        while (_continue) {
            if (_serialPort.IsOpen) {
                try {
                    values = _serialPort.ReadLine().Split('\t');
                    var angleX = float.Parse(values[0]) * -1;
                    var angleY = float.Parse(values[1]) * -1;
                    angle = new Vector3(angleX, 0, angleY);
                    //_handQuaternion.eulerAngles.Set(angleX, 0, angleY);
                    //Debug.Log (angleX + "," + angleY);
                } catch (TimeoutException) {
                }
            }
            Thread.Sleep(1);
        }
    }
}

参考

http://makers-with-myson.blog.so-net.ne.jp/2014-03-08
http://tips.hecomi.com/entry/2014/07/28/023525

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5