arduino unity3d怎么接unity

给我们留言
地址:福建省晋江市青阳街道洪山路国际工业设计园纳金网
电话: 400-067-3919
(周一到周五, 周六周日休息)
设计师入口
查看: 582|回复: 1
最后登录注册时间阅读权限90积分29083
资深设计师, 积分 29083, 距离下一级还需 20917 积分
纳金币13893 精华106
首先需要一个客户端就是Arduino的程序void setup()
{
&&Serial.begin(9600);
}
void loop() {
&&int incomingByte = 0;
&&if (Serial.available() & 0) {
& & incomingByte = Serial.read();
& & Serial.print(&I received: &);
& & Serial.println(incomingByte, DEC);
&&}
}复制代码用arduino编译器新建一个程序,直接复制进去就可以了,简单解释一下:setup是启动函数,相当于unity的start函数,而loop函数相当于Update函数。
下面是unity的代码:using UnityE
using System.C
using System.IO.P
using System.T
using S
using UnityEngine.UI;
public class SerialPortTest : MonoBehaviour
{
& & public InputF
& & public void buttonOnClick()
& & {
& && &&&sp.Write(input.text);
& & }
& & //Setup parameters to connect to Arduino
& & public static SerialPort sp = new SerialPort(&COM3&, 9600, Parity.None, 8, StopBits.One);
& & p
& & // Use this for initialization
& & void Start()
& & {
& && &&&OpenConnection();
& && &&&Loom.RunAsync(Read); //Loom.cs可在网上搜搜
& & }
& & void Update()
& & {
& & }
& & //Function connecting to Arduino
& & public void OpenConnection()
& & {
& && &&&if (sp != null)
& && &&&{
& && && && &if (sp.IsOpen)
& && && && &{
& && && && && & sp.Close();
& && && && && & message = &Closing port, because it was already open!&;
& && && && &}
& && && && &else
& && && && &{
& && && && && & sp.ReadTimeout = 500;&&// sets the timeout value before reporting error
& && && && && & sp.Open();&&// opens the connection
& && && && && & message = &Port Opened!&;
& && && && &}
& && &&&}
& && &&&else
& && &&&{
& && && && &if (sp.IsOpen)
& && && && &{
& && && && && & print(&Port is already open&);
& && && && &}
& && && && &else
& && && && &{
& && && && && & print(&Port == null&);
& && && && &}
& && &&&}
& & }
& & public static void Read()
& & {
& && &&&while (true)
& && &&&{
& && && && &try
& && && && &{
& && && && && & string message = sp.ReadLine();
& && && && && & Loom.EnqueueToMainThread(() =& { Debug.Log(message); });
& && && && &}
& && && && &catch (TimeoutException) { }
& && &&&}
& & }
& & void OnApplicationQuit()
& & {
& && &&&sp.Close();
& & }
}复制代码*注意:BuildSetting里面,API Compatibility Level要修改为.NET2.0,不然无法使用System.IO.P
最后登录注册时间阅读权限20积分455
设计实习生, 积分 455, 距离下一级还需 45 积分
纳金币108 精华0
你也玩Arduino?
站长推荐 /1
纳金名模第145期空调风扇3d模型:数量48个,大小为74.6MB。完全免费下载哦!这样的福利我和我的小伙伴们都惊呆了!!下载地址:
Powered by - X2.5
Narkii Inc.一个用 Arduino 实现的完整项目 - 技术翻译 - 开源中国社区
一个用 Arduino 实现的完整项目
【已翻译100%】
英文原文:
推荐于 3年前 (共 14 段, 翻译完成于 02-20)
参与翻译&(3人)&: ,
我有一个上小学的女儿. 作为一位父亲,当然该负起责任. 我喜欢自己作为父亲的角色,对此我毫无疑问. 但因此所带给我的困扰则是无止境的数学学习事务. 有时候这真的让我很头疼. 2+2, 5+6, 4+3,一遍又一遍. 那才刚开始呢, 现在又多了减法: 5-4, 10-4 .. 而每个人都知道这是没有结束可言的. 我抱怨的够多了,因而决定利用此项技术. 你知道的,技术为人而生, 而现在是为我而存在. 到这里来,我亲爱的 Arduino, 我需要你.
在最开始的时候,我希望这个项目能很容易实现. 我预计所有需要做的事情就是写一些函数来展示一些数字,并且为了根据趣味性,也许要来点蜂鸣声和一些LED灯光. 然后,情况在我开始精心考虑它的时候发生了改变,&出现了一些硬件管理问题, 然后是内容管理问题. 我们这个小小的&Arduino 应用程序变成了一个认真把握的东西,这导致我写下了这篇文章. 让我们先从需求开始吧.
&翻译得不错哦!
系统可以显示一个菜单,提供一些基本的操作:加、减、乘、除&。
用户(我的女儿)可以用键盘从菜单上选择一种算数运算来学习。
会有一些难度级别:在选择运算后,难度级别会显示出来。
根据选择的难度级别,会随机显示出一些问题,用户可以用键盘回答这些问题。
用户可以在确认前修改自己的答案。
在确认答案后,根据正确与否会显示出一条信息。
如果三次答错,将会显示出正确答案。
用户可以浏览菜单(点开菜单并选择菜单项)。
系统应具有音频和视频警告API,错误信息可以通过该API发送。
每种算术运算有一个限时小测环节。
限时小测随机从简到难给出问题。 &
测试后会显示出统计数据(回答了多少题目,答对了多少题目)。
在用户接近时系统可以引起她的注意。
可以有一些数学以外的娱乐环节,比如让她唱首歌、亲自己的爸爸等等。如果不这么做,用户将无法继续使用系统。
警告API可以用来在娱乐环节做一些有趣的事情。
&翻译得不错哦!
我们在这个项目中需要什么:&
LED 和 400欧姆电阻
看看下面的硬件设计:
注意一些和上面不匹配的部分:
LCD应该是字符LCD。
Arduino UNO应该用Mega替代。
(我用Arduino UNO开启了这个项目,但是因为内存的需要后来改用Arduino Mega继续这个项目。开始的时候,Arduino UNO工作的很好。但是,当代码量增加,我无法将RAM使用量控制在Arduino UNO的容量之内,然后就想你所想的,我最终启用了Arduino Mega,它有8K的SRAM。)
&翻译得不错哦!
图1:设计的概览
系统被分为2个主要部分。就像你在图1中看到的,第一个模块负责硬件的管理。
输入系统:我们有两个不同的键盘,他们被统一在一起,对外提供统一的接口。统一的键盘信息将在(矩阵键盘或模拟键盘上的)任何按键被按下时告知注册的客户端。
输出系统:具有附加功能的字符液晶面板。
发信系统:统一发信子系统。它由一个LED和一个数字蜂鸣器组成,它将不同的信号转化为目标客户端的编码。它将不同的信号转换为客户端代码,客户端代码可以根据需求运行各种代码。
运动检测:用PIR传感器实现运动检测。当有人被检测到,它触发一个信号来引起注意。
表现层负责与用户的交互。它包含图形界面的处理(菜单和页面)并包含管理子系统。
UI管理:在这个子系统中,我们定义了图像对象。一个菜单列表被显示出来供用户选择。一个菜单项可以显示出子菜单或者一个页面。用户可以通过输入显示在其上的索引来选择菜单项。通过按'Escape'键来返回上级菜单。如果一个菜单项是一个页面,选择后将会将这个页面显示出来。页面可以显示出其上面的信息,并等待用户输入来改变它的内容,此时按下'Escape'键就会显示出用户菜单。如果用户输入错误,可以通过按'Backspace'键删除答案。根据答案的正确与否,相应的信号将会被触发。
内容管理:这个子系统提供显示在屏幕上的内容,包括各种算术运算的各种难度级别的生成算法。客户端代码(页面)会向这个子系统请求内容。
简单的类框图如下。这些图像展示了基本的框架,帮助你更容易的理解实际的类实现。
&翻译得不错哦!
硬件管理 &
MFK_InputDevice将Keypad2和AdKeyboard统一为同一个接口。它处理它们的事件,并向其客户端提供一组新的编码,如下所示。
图2:输入子系统
按键映射:
Value (hex)&
MFK_OutputDevice继承自SerialLCD类。它结合SerialLCD类的功能,并对其进行了增强。
图3:输出子系统
一个信号模式从信号源产生。一个模式连同它的索引被储存在信号控制器中。想要启动一个信号模式非常简单,只要用它的索引从信号控制器调用它。
图4:发信系统
&翻译得不错哦!
在硬件管理层顶层的是MFK_Hardware类。它只会所有其他硬件设备,对客户端隐藏多余的复杂性。举例来说,PIRMotionandSignalController没有被暴露给客户端。但是输入和输出设备必须要向外界开放,因为UI系统需要对这些功能的直接访问。信号模式也是在这个类里构建的,可以通过索引来访问他们。
图5:硬件管理
&翻译得不错哦!
这一层负责与用户进行交互,它提供了视觉元素和内容。
ContentFactory根据toContentTypeEnum和ContentLevelEnum创建ContentProviders。客户端得到ContentFactory的实例,之后他可以请求一个content provider。
图6:内容管理
VisualItem是所有的视觉元素(菜单和页面)的基类。它还将硬件管理和呈现结合起来。'show' 和'msgbox'方法通过调用和回调VisualItem提供的方法使用输出设备(MFK_OutputDevice)和输入设备(MFK_InputDevice) 。'msgbox'方法也有能力启动一个信号模式,只要调用硬件(MFK_Hardware)的'signal'方法就可以了。
菜单就像他的名字一样,提供了一系列的菜单项可以选择。用户可以通过一个菜单项前面的索引选择它,然后菜单&'show' VisualItem。
Pageis是显示内容的视觉工具。除了娱乐内容,它会等待用户的输入。用户'Enter'她的答案,显示信息告知她对错。显示信息之后,就需要从内容管理获取新的内容。
&翻译得不错哦!
Chapter是ContentProvider和Page之间的中间类。当一个页面被第一次显示时,与其相关的chapter和ContentProvider就会被创建。用户的答案直接由chapter处理,并由chapter判断其对错。Chapter也对页面内的学习会话进行统计。FunChapter是一种不向用户要求答案的chapter,QuizChapter是限时的chapter。在一个quiz chapter中,问题只有在时间截止之前才能回答。
图7:UI管理
&翻译得不错哦!
我希望你已经清楚了系统的通用结构。现在,是时候深入到代码中去,那里是真正的乐趣开始的地方。
我想以MathForKid.ino开始。它是上传到Arduino主板上的主要代码。
//&File:&MathForKid.ino
//&hardware&management
MFK_Hardware*&
//&presentation
Menu*&mainM
void&setup()&{
&&&&//&for&debugging&purposes
&&&&Serial.begin(9600);
&&&&//&get&the&instance&and&initialize&it
&&&&hw&=&MFK_Hardware::getInstance();
&&&&hw-&begin();
&&&&//&create&user&interface
&&&&CreateUI();
&&&&//&show&the&main&menu
&&&&mainMenu-&show();
void&loop()&{
&&&&//&update&hardware
&&&&hw-&update();
&&&&//&update&active&visual&item
&&&&VisualItem&*v&=&VisualItem::getActiveItem();
&&&&if(v!=NULL)
&&&&&&&&v-&update();
就这么多。在Arduino上运行你的应用吧。好吧,也许解释一下会更好。
正如我在“软件设计”那部分开头所说的,我们有两个部分:一个用来硬件管理,另一个用来展示。它们在代码顶部定义为全局变量,我们在&'setup'函数中将它们初始化。'loop'函数调用代码来更新它们。
&翻译得不错哦!
事实上,CreateUI方法也是在这个文件中实现的。当用户开始交互时,它创建用户接口。mainMenu、所有的子菜单和一切页面都是这个方法产生的,chapter的属性也是其赋予的。
void&CreateUI()&{
&&&&mainMenu&=&new&Menu("main");
&&&&//&addition
&&&&Menu*&m&=&new&Menu("+");
&&&&mainMenu-&addMenuItem(m);
&&&&//&level-1&page
&&&&Page*&p&=&new&Page("L1");
&&&&p-&setChapterProperties(Chapter::NormalChapter,&\
&&&&&&&&&&&&ContentFactory::Addition,&ContentFactory::Level1Content);
&&&&m-&addMenuItem(p);
&&&&//&level-2&page
&&&&p&=&new&Page("L2");
&&&&p-&setChapterProperties(Chapter::NormalChapter,&\
&&&&&&&&&&&&ContentFactory::Addition,&ContentFactory::Level2Content);
&&&&m-&addMenuItem(p);
我们接着来看这个应用的设计模式。
就像你所想的,MFK_Hardware是Facade模式的一个例子。它将底层的硬件管理问题隐藏起来,并对客户端提供了干净的接口。它同时也是 Singleton模式的代表,因为整个系统运行时其只产生一个实例。为了实现这个功能,MFK_Hardware的构造器、复制和赋值操作都被声明为私有方法。
//&File:&MFK_Hardware.h
//&private&constructor&to&achieve&singleton&pattern
&&&&MFK_Hardware();
&&&&MFK_Hardware(MFK_Hardware&const&);&//&copy&disabled
&&&&void&operator=(MFK_Hardware&const&);&//&assigment&disabled
你只能通过getInstance静态方法访问它们,这个方法是公共的:
//&File:&MFK_Hardware.h
//&static&method&to&get&the&instance&
&&&&static&MFK_Hardware*&getInstance()&{
&&&&&&&&static&MFK_Hardware&
&&&&&&&&return&&
&翻译得不错哦!
我们的翻译工作遵照 ,如果我们的工作有侵犯到您的权益,请及时联系我们2333人阅读
Unity3D使用串口与单片机等进行数据传输
一个简单的例子:(接收一个字节)
using UnityE
using System.C
using System.T
using System.Collections.G
using System.IO.P
using System.Text.RegularE
using System.T
public class tmp : MonoBehaviour
private SerialP
private Thread recvT
// Use this for initialization
void Start()
sp = new SerialPort(&COM1&, 9600, Parity.None, 8, StopBits.One);
//串口初始化
if (!sp.IsOpen)
sp.Open();
recvThread = new Thread(ReceiveOneByte); //该线程接收一个字节
recvThread.Start();
void Update()
private void ReceiveOneByte()
Byte[] buf = new Byte[1];
string sbReadline2str = string.E
if (sp.IsOpen)
sp.Read(buf, 0, 1);
catch (Exception ex)
Debug.Log(ex);
/* private void SendSerialPortData(string data) //发送一个字节
if(sp.IsOpen)
sp.WriteLine(data);
void OnApplicationQuit()
sp.Close();
Arduino+MPU6050提供姿态数据由Unity3D实时显示
Arduino端:
与MPU6050的物理连接:A4---SDA A5---SCLVCC---3V3GND---GNDGND---ADD
Arduino IDE(我这用的是1.0.5)
库文件:/jrowberg/i2cdevlib &下载后本次需要的是MPU6050和I2Cdev两个文件夹,将它们拷贝进IDE的安装目录下的libraries\文件夹下
代码可由MPU6050库自带的Example中的“MPU6050_DMP6”改写(该Example还可用于测试连接或元件是否正常工作)
改写内容有:
1.选择输出欧拉角功能
2.去除其它不必要输出和输入
3.修改输出格式如下:每一组欧拉角前加“!”,欧拉角内以“#”分隔
注:由该Example可获得MPU6050经DMP处理后的数据,包括四元数,欧拉角,加速度,具体获得那种数据,靠预处理来选择
最终代码:
// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0)
// 6/21/2012 by Jeff Rowberg &&
// Updates should (hopefully) always be available at /jrowberg/i2cdevlib
// Changelog:
- added seamless Fastwire support
- added note about gyro calibration
- added note about Arduino 1.0.1 + Leonardo compatibility error
- improved FIFO overflow handling and simplified read process
- completely rearranged DMP initialization code and simplification
- pull gyro and accel data from FIFO packet instead of reading directly
- fix broken FIFO read sequence and change interrupt detection to RISING
- add gravity-compensated initial reference frame acceleration output
- add 3D math helper file to DMP6 example sketch
- add Euler output and Yaw/Pitch/Roll output formats
- remove accel offset clearing for better results (thanks Sungon Lee)
- fixed gyro sensitivity to be 2000 deg/sec instead of 250
- basic DMP initialization working
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2012 Jeff Rowberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the &Software&), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &AS IS&, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include &I2Cdev.h&
#include &MPU6050_6Axis_MotionApps20.h&
//#include &MPU6050.h& // not necessary if using MotionApps include file
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include &Wire.h&
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
// AD0 high = 0x69
//MPU6050 mpu(0x69); // &-- use for AD0 high
/* =========================================================================
NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch
depends on the MPU-6050's INT pin being connected to the Arduino's
external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is
digital I/O pin 2.
* ========================================================================= */
/* =========================================================================
NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error
when using Serial.write(buf, len). The Teapot output uses this method.
The solution requires a modification to the Arduino USBAPI.h file, which
is fortunately simple, but annoying. This will be fixed in the next IDE
release. For more info, see these links:
http://arduino.cc/forum/index.php/topic,.html
/p/arduino/issues/detail?id=958
* ========================================================================= */
// uncomment &OUTPUT_READABLE_QUATERNION& if you want to see the actual
// quaternion components in a [w, x, y, z] format (not best for parsing
// on a remote host such as Processing or something though)
//#define OUTPUT_READABLE_QUATERNION
// uncomment &OUTPUT_READABLE_EULER& if you want to see Euler angles
// (in degrees) calculated from the quaternions coming from the FIFO.
// Note that Euler angles suffer from gimbal lock (for more info, see
// http://en.wikipedia.org/wiki/Gimbal_lock)
#define OUTPUT_READABLE_EULER
// uncomment &OUTPUT_READABLE_YAWPITCHROLL& if you want to see the yaw/
// pitch/roll angles (in degrees) calculated from the quaternions coming
// from the FIFO. Note this also requires gravity vector calculations.
// Also note that yaw/pitch/roll angles suffer from gimbal lock (for
// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock)
//#define OUTPUT_READABLE_YAWPITCHROLL
// uncomment &OUTPUT_READABLE_REALACCEL& if you want to see acceleration
// components with gravity removed. This acceleration reference frame is
// not compensated for orientation, so +X is always +X according to the
// sensor, just without the effects of gravity. If you want acceleration
// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
//#define OUTPUT_READABLE_REALACCEL
// uncomment &OUTPUT_READABLE_WORLDACCEL& if you want to see acceleration
// components with gravity removed and adjusted for the world frame of
// reference (yaw is relative to initial orientation, since no magnetometer
// is present in this case). Could be quite handy in some cases.
//#define OUTPUT_READABLE_WORLDACCEL
// uncomment &OUTPUT_TEAPOT& if you want output that matches the
// format used for the InvenSense teapot demo
//#define OUTPUT_TEAPOT
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState =
// MPU control/status vars
bool dmpReady =
// set true if DMP init was successful
uint8_t mpuIntS
// holds actual interrupt status byte from MPU
uint8_t devS
// return status after each device operation (0 = success, !0 = error)
uint16_t packetS
// expected DMP packet size (default is 42 bytes)
uint16_t fifoC
// count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
// orientation/motion vars
// [w, x, y, z]
quaternion container
VectorInt16
// [x, y, z]
accel sensor measurements
VectorInt16 aaR
// [x, y, z]
gravity-free accel sensor measurements
VectorInt16 aaW
// [x, y, z]
world-frame accel sensor measurements
// [x, y, z]
gravity vector
float euler[3];
// [psi, theta, phi]
Euler angle container
float ypr[3];
// [yaw, pitch, roll]
yaw/pitch/roll container and gravity vector
// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
// ================================================================
INTERRUPT DETECTION ROUTINE
// ================================================================
volatile bool mpuInterrupt =
// indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
mpuInterrupt =
// ================================================================
INITIAL SETUP
// ================================================================
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
// initialize serial communication
// (115200 chosen because it is required for Teapot Demo output, but it's
// really up to you depending on your project)
Serial.begin(115200);
while (!Serial); // wait for Leonardo enumeration, others continue immediately
// NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio
// Pro Mini running at 3.3v, cannot handle this baud rate reliably due to
// the baud timing being too misaligned with processor ticks. You must use
// 38400 or slower in these cases, or use some kind of external separate
// crystal solution for the UART timer.
// initialize device
// Serial.println(F(&Initializing I2C devices...&));
mpu.initialize();
// verify connection
// Serial.println(F(&Testing device connections...&));
Serial.println(mpu.testConnection() ? F(&MPU6050 connection successful&) : F(&MPU6050 connection failed&));
// wait for ready
// Serial.println(F(&\nSend any character to begin DMP programming and demo: &));
while (Serial.available() && Serial.read()); // empty buffer
while (!Serial.available());
// wait for data
while (Serial.available() && Serial.read()); // empty buffer again
// load and configure the DMP
Serial.println(F(&Initializing DMP...&));
devStatus = mpu.dmpInitialize();
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
// make sure it worked (returns 0 if so)
if (devStatus == 0) {
// turn on the DMP, now that it's ready
Serial.println(F(&Enabling DMP...&));
mpu.setDMPEnabled(true);
// enable Arduino interrupt detection
Serial.println(F(&Enabling interrupt detection (Arduino external interrupt 0)...&));
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
// set our DMP Ready flag so the main loop() function knows it's okay to use it
Serial.println(F(&DMP ready! Waiting for first interrupt...&));
dmpReady =
// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();
// 1 = initial memory load failed
// 2 = DMP configuration updates failed
// (if it's going to break, usually the code will be 1)
Serial.print(F(&DMP Initialization failed (code &));
Serial.print(devStatus);
Serial.println(F(&)&));
// configure LED for output
pinMode(LED_PIN, OUTPUT);
// ================================================================
MAIN PROGRAM LOOP
// ================================================================
void loop() {
// if programming failed, don't try to do anything
if (!dmpReady)
// wait for MPU interrupt or extra packet(s) available
while (!mpuInterrupt && fifoCount & packetSize) {
// other program behavior stuff here
// if you are really paranoid you can frequently test in between other
// stuff to see if mpuInterrupt is true, and if so, && from the
// while() loop to immediately process the MPU data
// reset interrupt flag and get INT_STATUS byte
mpuInterrupt =
mpuIntStatus = mpu.getIntStatus();
// get current FIFO count
fifoCount = mpu.getFIFOCount();
// check for overflow (this should never happen unless our code is too inefficient)
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
// reset so we can continue cleanly
mpu.resetFIFO();
Serial.println(F(&FIFO overflow!&));
// otherwise, check for DMP data ready interrupt (this should happen frequently)
} else if (mpuIntStatus & 0x02) {
// wait for correct available data length, should be a VERY short wait
while (fifoCount & packetSize) fifoCount = mpu.getFIFOCount();
// read a packet from FIFO
mpu.getFIFOBytes(fifoBuffer, packetSize);
// track FIFO count here in case there is & 1 packet available
// (this lets us immediately read more without waiting for an interrupt)
fifoCount -= packetS
#ifdef OUTPUT_READABLE_QUATERNION
// display quaternion values in easy matrix form: w x y z
mpu.dmpGetQuaternion(&q, fifoBuffer);
Serial.print(&!&);
Serial.print(q.x);
Serial.print(&#&);
Serial.print(q.y);
Serial.print(&#&);
Serial.print(q.z);
Serial.print(&#&);
Serial.print(q.w);
#ifdef OUTPUT_READABLE_EULER
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetEuler(euler, &q);
Serial.print(&!&);
Serial.print(euler[0] * 180/M_PI);
Serial.print(&#&);
Serial.print(euler[1] * 180/M_PI);
Serial.print(&#&);
Serial.print(euler[2] * 180/M_PI);
#ifdef OUTPUT_READABLE_YAWPITCHROLL
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
Serial.print(&!&);
Serial.print(ypr[0] * 180/M_PI);
Serial.print(&#&);
Serial.print(ypr[1] * 180/M_PI);
Serial.print(&#&);
Serial.print(ypr[2] * 180/M_PI);
#ifdef OUTPUT_READABLE_REALACCEL
// display real acceleration, adjusted to remove gravity
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetAccel(&aa, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
Serial.print(&areal\t&);
Serial.print(aaReal.x);
Serial.print(&\t&);
Serial.print(aaReal.y);
Serial.print(&\t&);
Serial.println(aaReal.z);
#ifdef OUTPUT_READABLE_WORLDACCEL
// display initial world-frame acceleration, adjusted to remove gravity
// and rotated based on known orientation from quaternion
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetAccel(&aa, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
Serial.print(&aworld\t&);
Serial.print(aaWorld.x);
Serial.print(&\t&);
Serial.print(aaWorld.y);
Serial.print(&\t&);
Serial.println(aaWorld.z);
#ifdef OUTPUT_TEAPOT
// display quaternion values in InvenSense Teapot demo format:
teapotPacket[2] = fifoBuffer[0];
teapotPacket[3] = fifoBuffer[1];
teapotPacket[4] = fifoBuffer[4];
teapotPacket[5] = fifoBuffer[5];
teapotPacket[6] = fifoBuffer[8];
teapotPacket[7] = fifoBuffer[9];
teapotPacket[8] = fifoBuffer[12];
teapotPacket[9] = fifoBuffer[13];
Serial.write(teapotPacket, 14);
teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
// blink LED to indicate activity
blinkState = !blinkS
digitalWrite(LED_PIN, blinkState);
Unity3D端:
using UnityE
using System.C
using System.T
using System.Collections.G
using System.IO.P
using System.Text.RegularE
using System.T
public class com : MonoBehaviour
public GameO//目标操作物体
private SerialP
private Thread recvT
float x,y,z;//存放欧拉角
// Use this for initialization
void Start()
Debug.Log(&start&);
sp = new SerialPort(&COM1&, 115200, Parity.None, 8, StopBits.One);
//串口初始化
if (!sp.IsOpen)
sp.Open();
recvThread = new Thread(ReceiveData);
recvThread.Start();
// Update is called once per frame
void Update()
Debug.Log(x+&&&&+y+&&&&+z);
//更新姿态
target.transform.eulerAngles=new Vector3(x,y,z);
private void ReceiveData()
char[] spil=&#&.ToCharArray();//“#”为串口传入一份数据内的分隔符,数据间的分隔符为“!”(ASICII为33)
char[] sbuf = new char[1024];
Byte[] buf = new Byte[1];
string sbReadline2str = string.E
if (sp.IsOpen) sp.Read(buf, 0, 1);
if (buf.Length == 0)
else if(buf[0]==33){//第一次找到数据头标志
while(true){//不断读取欧拉角
sp.Read(buf, 0, 1);//读一个字节
if(buf[0]!=33)//该份欧拉角未结束
//保存该字节
sbuf[i]=(char)buf[0];
i++;
String s=new String(sbuf,0,i);
String []ss=s.Split(spil);
//更新X,Y,Z
if(ss.Length==3)
x=float.Parse(ss[0]);
y=float.Parse(ss[1]);
z=float.Parse(ss[2]);
//接着读取下一组欧拉角
catch (Exception ex)
Debug.Log(ex);
private void SendSerialPortData(string data)
if(sp.IsOpen)
sp.WriteLine(data);
void OnApplicationQuit()
sp.Close();
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:13061次
排名:千里之外
原创:19篇

我要回帖

更多关于 arduino 串口接收 的文章

 

随机推荐