輸入指令
在這個(gè)項(xiàng)目的輸入方面,我們需要將MPU6050傳感器與Arduino UNO連接。
參考下圖,獲取有關(guān)如何將傳感器連接到Arduino的幫助。
詳細(xì)說明了MPU6050傳感器與Arduino UNO之間的連接。
安裝Arduino庫
首先,從GitHub下載I2C和MPU6050庫,以便與Arduino接口。
解壓縮或解壓縮下載文件后,導(dǎo)航到Arduino文件夾,復(fù)制I2C和MPU6050文件夾并將它們放在Arduino IDE庫文件夾中。
Arduino IDE庫文件夾中I2C和MPU6050文件夾的位置。
上傳代碼流程
撒哈拉title title
啟動Arduino IDE。
查找MPU6050文件夾下的示例文件。
打開MPU6050_DMP6文件。
示例下的MPU6050_DMP6文件的位置和MPU6050文件夾。
現(xiàn)在,上傳Arduino IDE代碼并顯示串口監(jiān)視器。
如果顯示輸出,那么這表示你‘已成功將傳感器與Arduino連接。
輸出數(shù)據(jù)顯示在Arduino中。
要將數(shù)據(jù)發(fā)送到Processing,需要對代碼進(jìn)行一些更改。
首先取消注釋117代碼行并注釋100代碼行。
上傳代碼再次和它笑uld在串口監(jiān)視器中顯示為不可讀的字符。
處理代碼說明
為了從Arduino接收數(shù)據(jù)并移動3D模型,需要從bitbucket下載’toxiclibs‘庫.org。
復(fù)制zip文件中的所有文件夾并將其粘貼到Processing library文件夾中。
Processing library文件夾可以可在以下位置找到:處理文件夾》模式》 Java》庫。
現(xiàn)在,將下面的代碼粘貼到Processing然后上傳。
代碼是MPU6050庫中包含的示例的修改版本。
import processing.serial.*;
import processing.opengl.*;
import toxi.geom.*;
import toxi.processing.*;
import oscP5.*;
import netP5.*;
OscP5 oscP5;
NetAddress dest;
ToxiclibsSupport gfx;
Serial port; // The serial port
char[] teapotPacket = new char[14]; // InvenSense Teapot packet
int serialCount = 0; // current packet byte position
int synced = 0;
int interval = 0;
float[] q = new float[4];
Quaternion quat = new Quaternion(1, 0, 0, 0);
float[] gravity = new float[3];
float[] euler = new float[3];
float[] ypr = new float[3];
void setup() {
// 300px square viewport using OpenGL rendering
size(300, 300, OPENGL);
gfx = new ToxiclibsSupport(this);
// setup lights and antialiasing
lights();
smooth();
// display serial port list for debugging/clarity
println(Serial.list());
// get the first available port (use EITHER this OR the specific port code below)
String portName = Serial.list()[0];
// get a specific serial port (use EITHER this OR the first-available code above)
//String portName = “COM4”;
// open the serial port
port = new Serial(this, portName, 115200);
// send single character to trigger DMP init/start
// (expected by MPU6050_DMP6 example Arduino sketch)
port.write(’r‘);
/* start oscP5, sending messages at port 9000 */
oscP5 = new OscP5(this,9000);
dest = new NetAddress(“127.0.0.1”,6448);
}
void draw() {
if (millis() - interval 》 1000) {
// resend single character to trigger DMP init/start
// in case the MPU is halted/reset while applet is running
port.write(’r‘);
interval = millis();
}
// black background
background(0);
// translate everything to the middle of the viewport
pushMatrix();
translate(width / 2, height / 2);
// 3-step rotation from yaw/pitch/roll angles (gimbal lock?。?/p>
// 。..and other weirdness I haven’t figured out yet
//rotateY(-ypr[0]);
//rotateZ(-ypr[1]);
//rotateX(-ypr[2]);
// toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock?。?/p>
// (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of
// different coordinate system orientation assumptions between Processing
// and InvenSense DMP)
float[] axis = quat.toAxisAngle();
rotate(axis[0], -axis[1], axis[3], axis[2]);
// draw main body in red
fill(255, 0, 0, 200);
box(10, 10, 200);
// draw front-facing tip in blue
fill(0, 0, 255, 200);
pushMatrix();
translate(0, 0, -120);
rotateX(PI/2);
drawCylinder(0, 20, 20, 8);
popMatrix();
// draw wings and tail fin in green
fill(0, 255, 0, 200);
beginShape(TRIANGLES);
vertex(-100, 2, 30); vertex(0, 2, -80); vertex(100, 2, 30); // wing top layer
vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30); // wing bottom layer
vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70); // tail left layer
vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70); // tail right layer
endShape();
beginShape(QUADS);
vertex(-100, 2, 30); vertex(-100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80);
vertex( 100, 2, 30); vertex( 100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80);
vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2, 30); vertex(100, 2, 30);
vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, -30, 98); vertex(-2, -30, 98);
vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, 0, 70); vertex(-2, 0, 70);
vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2, 0, 70); vertex(-2, 0, 70);
endShape();
popMatrix();
//Send the OSC message
sendOsc();
}
void serialEvent(Serial port) {
interval = millis();
while (port.available() 》 0) {
int ch = port.read();
if (synced == 0 && ch != ‘$’) return; // initial synchronization - also used to resync/realign if needed
synced = 1;
print ((char)ch);
if ((serialCount == 1 && ch != 2)
|| (serialCount == 12 && ch != ‘ ’)
|| (serialCount == 13 && ch != ‘ ’)) {
serialCount = 0;
synced = 0;
return;
}
if (serialCount 》 0 || ch == ‘$’) {
teapotPacket[serialCount++] = (char)ch;
if (serialCount == 14) {
serialCount = 0; // restart packet byte position
// get quaternion from data packet
q[0] = ((teapotPacket[2] 《《 8) | teapotPacket[3]) / 16384.0f;
q[1] = ((teapotPacket[4] 《《 8) | teapotPacket[5]) / 16384.0f;
q[2] = ((teapotPacket[6] 《《 8) | teapotPacket[7]) / 16384.0f;
q[3] = ((teapotPacket[8] 《《 8) | teapotPacket[9]) / 16384.0f;
for (int i = 0; i 《 4; i++) if (q[i] 》= 2) q[i] = -4 + q[i];
// set our toxilibs quaternion to new data
quat.set(q[0], q[1], q[2], q[3]);
// below calculations unnecessary for orientation only using toxilibs
// calculate gravity vector
gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]);
gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]);
gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
// calculate Euler angles
euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]);
euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1);
// calculate yaw/pitch/roll angles
ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2]));
ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2]));
// output various components for debugging
//println(“q: ” + round(q[0]*100.0f)/100.0f + “ ” + round(q[1]*100.0f)/100.0f + “ ” + round(q[2]*100.0f)/100.0f + “ ” + round(q[3]*100.0f)/100.0f);
//println(“euler: ” + euler[0]*180.0f/PI + “ ” + euler[1]*180.0f/PI + “ ” + euler[2]*180.0f/PI);
println(“ypr: ” + ypr[0]*180.0f/PI + “ ” + ypr[1]*180.0f/PI + “ ” + ypr[2]*180.0f/PI);
}
}
}
}
void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) {
float angle = 0;
float angleIncrement = TWO_PI / sides;
beginShape(QUAD_STRIP);
for (int i = 0; i 《 sides + 1; ++i) {
vertex(topRadius*cos(angle), 0, topRadius*sin(angle));
vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle));
angle += angleIncrement;
}
endShape();
// If it is not a cone, draw the circular top cap
if (topRadius != 0) {
angle = 0;
beginShape(TRIANGLE_FAN);
// Center point
vertex(0, 0, 0);
for (int i = 0; i 《 sides + 1; i++) {
vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
angle += angleIncrement;
}
endShape();
}
// If it is not a cone, draw the circular bottom cap
if (bottomRadius != 0) {
angle = 0;
beginShape(TRIANGLE_FAN);
// Center point
vertex(0, tall, 0);
for (int i = 0; i 《 sides + 1; i++) {
vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
angle += angleIncrement;
}
endShape();
}
}
void sendOsc() {
OscMessage msg = new OscMessage(“/wek/inputs”);
msg.add((float)ypr[2]); // x-axis
msg.add((float)ypr[1]); // y -axis
oscP5.send(msg, dest);
}
上傳后代碼,窗口應(yīng)該如下所示。
輸出代碼指令
就輸出過程而言,一個(gè)簡單的界面將被設(shè)置為從Wekinator接收一個(gè)DTW輸出。
在界面內(nèi),一個(gè)方框根據(jù)收到的Wekinator輸入向左或向右移動。
你可以找到并下載加工草圖在Wekinator網(wǎng)站上。
下載‘Simple DTW-controlled-game’文件并在Processing中運(yùn)行后,它應(yīng)該如下例所示。
Wekinator說明
啟動Wekinator軟件并按照以下步驟操作:
設(shè)置輸入值為2.
將輸出值設(shè)置為1.
將輸出類型保留為默認(rèn)設(shè)置“所有動態(tài)時(shí)間扭曲”并指定3種手勢類型。
‘創(chuàng)建新項(xiàng)目’窗口,顯示W(wǎng)ekinator中的輸入,輸出和手勢類型字段。
單擊“下一步”,彈出“新建項(xiàng)目”窗口。
‘新項(xiàng)目’窗口,在Wekinator中包含輸出行字段。
然后,單擊輸出1行上的“加號”按鈕并向左傾斜傳感器。輸出將沿該方向移動框。
‘新項(xiàng)目’窗口,帶有添加/刪除按鈕。
現(xiàn)在,單擊輸出2行上的“加號”按鈕,然后向右傾斜傳感器。輸出將相應(yīng)地移動框。
‘New Project’窗口,在Wekinator中用輸出2行中的添加/刪除按鈕。
最后,單擊輸出3行中的加號按鈕并向后傾斜傳感器。輸出將導(dǎo)致框跳轉(zhuǎn)。
‘New Project’窗口,帶有在Wekinator中圈出的添加/刪除按鈕。
‘新建項(xiàng)目’窗口,輸出3行中的添加/刪除按鈕被圈起來。
錄制完成后,根據(jù)樣本訓(xùn)練Wekinator并運(yùn)行程序。
然后方框會響應(yīng)傳感器傾斜的方向移動
-
傳感器
+關(guān)注
關(guān)注
2553文章
51523瀏覽量
757354 -
Arduino
+關(guān)注
關(guān)注
188文章
6477瀏覽量
188114
發(fā)布評論請先 登錄
相關(guān)推薦
工業(yè)用傳感器的應(yīng)用領(lǐng)域 無線傳感器網(wǎng)絡(luò)的優(yōu)勢與挑戰(zhàn)
基于PIR傳感器的電路圖 帶Arduino的PIR傳感器設(shè)計(jì)
![基于PIR<b class='flag-5'>傳感器</b>的電路圖 帶<b class='flag-5'>Arduino</b>的PIR<b class='flag-5'>傳感器</b>設(shè)計(jì)](https://file1.elecfans.com/web2/M00/F8/8E/wKgaomaFGdGAXD7dAAJFBD5A3Aw866.png)
怎么用萬用表測量溫度傳感器的好壞
振動電阻式傳感器測量模塊的傳感器接口
![振動電阻式<b class='flag-5'>傳感器</b>測量模塊的<b class='flag-5'>傳感器</b><b class='flag-5'>接口</b>](https://file1.elecfans.com/web2/M00/EC/66/wKgZomZilkKATCBvAAImCNwVhpg656.png)
stm32f105主控作為傳感器信號采集器,精度和抗干擾怎樣?
英飛凌推出用于Arduino的XENSIVTM傳感器擴(kuò)展板
英飛凌推出用于Arduino的XENSIV傳感器擴(kuò)展板, 搭載英飛凌和Sensirion的智能家居應(yīng)用傳感器
![英飛凌推出用于<b class='flag-5'>Arduino</b>的XENSIV<b class='flag-5'>傳感器</b>擴(kuò)展板, 搭載英飛凌和Sensirion的智能家居應(yīng)用<b class='flag-5'>傳感器</b>](https://file1.elecfans.com/web2/M00/E1/DB/wKgZomY56T2Ab9y-AAHA5bKO2yI618.jpg)
stm32f100怎樣用重映射功能?
英飛凌和盛思銳合作推出一款支持Arduino的傳感器擴(kuò)展板
STM32F412G-DISCO怎樣用MX生成fatfs的代碼?
?車用傳感器頻繁損壞的原因及解決方案
![?車<b class='flag-5'>用</b><b class='flag-5'>傳感器</b>頻繁損壞的原因及解決方案](https://file.elecfans.com/web2/M00/11/AF/pYYBAGEjX2CAcHQBAAAbjMuxM3k247.jpg)
評論