這個是 Arduino 接上 MPU-6050 並用 UART 將數據傳至 Unity 的 Example
直接看結果圖 & 用程式碼說明吧:
執行結果:
Arduino :
#include <Wire.h>
const int Address = 0x68; // MPU-6050 的 I2C 地址
void setup() {
Serial.begin(115200); // 初始化串口
Wire.begin(); // 初始化Wire庫
WriteMPUReg(0x6B, 0); // 啟動 MPU-6050
}
void loop()
{
byte date[16]; // 14 + 2 = 16 (14: 資料 , 2: AA AA 分隔符)
ReadAccGyr(date); //讀出測量值
for (int i = 0; i < 16; i++) {
Serial.write(date[i]);
}
}
void WriteMPUReg(int nReg, unsigned char nVal) {
Wire.beginTransmission(Address);
Wire.write(nReg);
Wire.write(nVal);
Wire.endTransmission(true);
}
//從 MPU-6050 讀出一個 Byte 的數據
//指定暫存器地址,返回一個 Byte 的值
unsigned char ReadMPUReg(int nReg) {
Wire.beginTransmission(Address);
Wire.write(nReg);
Wire.requestFrom(Address, 1, true);
Wire.endTransmission(true);
return Wire.read();
}
// 讀取順序 ( 14 項資料 ):
// [
// Acc_X_H, Acc_X_L, Acc_Y_H, Acc_Y_L, Acc_Z_H, Acc_Z_L,
// Temp_H, Temp_L
// Gyro_X_H, Gyro_X_L, Gyro_Y_H, Gyro_Y_L, Gyro_Z_H, Gyro_Z_L
// ]
// 從MPU-6050 讀出三個加速度計值、溫度值、三個角速度計值
// 保存在指定數組中
void ReadAccGyr(byte *pVals) {
Wire.beginTransmission(Address);
Wire.write(0x3B);
Wire.requestFrom(Address, 14, true);
Wire.endTransmission(true);
for (int i = 0; i < 14; i++) {
pVals[i] = Wire.read();
}
pVals[14] = 170; // AA
pVals[15] = 170; // AA
}
C # :
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using System;
using UnityEngine;
using UnityEngine.UI;
public class Test_MPU_6050 : MonoBehaviour
{
public Text txt_msg;
void Start()
{
new Thread(Run).Start();
InvokeRepeating("LoopSec", 0, 1);
}
int secCount = 0;
void LoopSec()
{
print("一秒接收:" + secCount + " 次");
secCount = 0;
}
float AccX = 0, AccY = 0, AccZ = 0, Temp = 0, GyroX = 0, GyroY = 0, GyroZ = 0;
void Update()
{
txt_msg.text = "";
txt_msg.text += "AccX : " + AccX.ToString("0.00");
txt_msg.text += " ";
txt_msg.text += "AccY : " + AccY.ToString("0.00");
txt_msg.text += " ";
txt_msg.text += "AccZ : " + AccZ.ToString("0.00");
txt_msg.text += "\n";
txt_msg.text += "Temp : " + Temp.ToString("0.00");
txt_msg.text += " ";
txt_msg.text += "\n";
txt_msg.text += "GyroX : " + GyroX.ToString("0.00");
txt_msg.text += " ";
txt_msg.text += "GyroY : " + GyroY.ToString("0.00");
txt_msg.text += " ";
txt_msg.text += "GyroZ : " + GyroZ.ToString("0.00");
}
SerialPort sp = null;
bool isClose = false;
void Run()
{
Debug.Log("Run");
string data = "No Data";
try
{
sp = new SerialPort("COM4", 115200, Parity.None, 8, StopBits.One); // 通訊埠為COM5、波特率(Baud rate) 115200
sp.Open(); // 打開 COM5 通訊埠
while (isClose == false)
{
if (sp.ReadByte() == 0xAA && sp.ReadByte() == 0xAA)
{
List<int> d = new List<int>();
while (true)
{
int dd = sp.ReadByte();
int dd2 = sp.ReadByte();
if (dd == 0xAA && dd2 == 0xAA)
{
break;
}
d.Add(dd);
d.Add(dd2);
}
if (d.Count != 14)
{
continue;
}
unchecked
{
// 加速度計
short accX = (short)(d[0] << 8 | d[1]);
short accY = (short)(d[2] << 8 | d[3]);
short accZ = (short)(d[4] << 8 | d[5]);
AccX = accX / 32767.0f;
AccY = accY / 32767.0f;
AccZ = accZ / 32767.0f;
// 溫度
short temp = (short)(d[6] << 8 | d[7]);
Temp = 36.53f + temp / 340.0f;
// 陀螺儀
short gyroX = (short)(d[8] << 8 | d[9]);
short gyroY = (short)(d[10] << 8 | d[11]);
short gyroZ = (short)(d[12] << 8 | d[13]);
GyroX = gyroX / 32767.0f;
GyroY = gyroY / 32767.0f;
GyroZ = gyroZ / 32767.0f;
}
secCount++;
}
}
}
catch (Exception ex)
{
Debug.Log(ex);
Debug.Log(data);
isClose = true;
sp.Close(); // 關閉 COM5 通訊埠
}
}
private void OnDestroy()
{
isClose = true;
sp.Close();
print("Close");
}
}