0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

怎样用Arduino和Wekinator创建传感器控制接口

454398 来源:工程师吴畏 2019-08-02 17:31 次阅读

输入指令

在这个项目的输入方面,我们需要将MPU6050传感器Arduino UNO连接。

参考下图,获取有关如何将传感器连接到Arduino的帮助。

怎样用Arduino和Wekinator创建传感器控制接口

详细说明了MPU6050传感器与Arduino UNO之间的连接。

安装Arduino库

首先,从GitHub下载I2C和MPU6050库,以便与Arduino接口

解压缩或解压缩下载文件后,导航到Arduino文件夹,复制I2C和MPU6050文件夹并将它们放在Arduino IDE库文件夹中。

Arduino IDE库文件夹中I2C和MPU6050文件夹的位置。

上传代码流程

撒哈拉title title

启动Arduino IDE。

查找MPU6050文件夹下的示例文件。

打开MPU6050_DMP6文件。

示例下的MPU6050_DMP6文件的位置和MPU6050文件夹。

现在,上传Arduino IDE代码并显示串口监视器。

如果显示输出,那么这表示你‘已成功将传感器与Arduino连接。

输出数据显示在Arduino中。

要将数据发送到Processing,需要对代码进行一些更改。

首先取消注释117代码行并注释100代码行。

上传代码再次和它笑uld在串口监视器中显示为不可读的字符。

处理代码说明

为了从Arduino接收数据并移动3D模型,需要从bitbucket下载’toxiclibs‘库.org。

复制zip文件中的所有文件夹并将其粘贴到Processing library文件夹中。

Processing library文件夹可以可在以下位置找到:处理文件夹》模式》 Java》库。

现在,将下面的代码粘贴到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!)

// 。..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!)

// (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);

}

上传后代码,窗口应该如下所示。

输出代码指令

就输出过程而言,一个简单的界面将被设置为从Wekinator接收一个DTW输出。

在界面内,一个方框根据收到的Wekinator输入向左或向右移动。

你可以找到并下载加工草图在Wekinator网站上。

下载‘Simple DTW-controlled-game’文件并在Processing中运行后,它应该如下例所示。

Wekinator说明

启动Wekinator软件并按照以下步骤操作:

设置输入值为2.

将输出值设置为1.

将输出类型保留为默认设置“所有动态时间扭曲”并指定3种手势类型。

‘创建新项目’窗口,显示Wekinator中的输入,输出和手势类型字段。

单击“下一步”,弹出“新建项目”窗口。

‘新项目’窗口,在Wekinator中包含输出行字段。

然后,单击输出1行上的“加号”按钮并向左倾斜传感器。输出将沿该方向移动框。

‘新项目’窗口,带有添加/删除按钮。

现在,单击输出2行上的“加号”按钮,然后向右倾斜传感器。输出将相应地移动框。

‘New Project’窗口,在Wekinator中用输出2行中的添加/删除按钮。

最后,单击输出3行中的加号按钮并向后倾斜传感器。输出将导致框跳转。

‘New Project’窗口,带有在Wekinator中圈出的添加/删除按钮。

‘新建项目’窗口,输出3行中的添加/删除按钮被圈起来。

录制完成后,根据样本训练Wekinator并运行程序。

然后方框会响应传感器倾斜的方向移动

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2551

    文章

    51080

    浏览量

    753378
  • Arduino
    +关注

    关注

    188

    文章

    6469

    浏览量

    187024
收藏 人收藏

    评论

    相关推荐

    怎样用THS3201实现输出功率可调?

    怎样用THS3201实现输出功率可调?
    发表于 08-26 08:28

    怎样用Arduino测试锂电池容量

    本文详细介绍了如何用Arduino测量锂电池的容量。并附有电路图和Arduino的程序代码。
    的头像 发表于 07-30 09:14 888次阅读
    <b class='flag-5'>怎样用</b><b class='flag-5'>Arduino</b>测试锂电池容量

    怎么表测量温度传感器的好坏

    表是一种常用的测量工具,可以用来测量电压、电流、电阻等参数。然而,对于温度传感器的测量,万表可能不是最佳选择。温度传感器通常使用热电偶、热敏电阻或半导体
    的头像 发表于 06-19 15:06 2510次阅读

    振动电阻式传感器测量模块的传感器接口

    振动电阻式传感器测量模块的传感器接口 RM502模块采用了高精度模拟信号驱动和采集威廉希尔官方网站 ,能够驱动和测量对电阻精度要求较高的传感器。它采用恒流驱动和实时电流测量,有效避免了环境温度变化引
    的头像 发表于 06-11 14:13 381次阅读
    振动电阻式<b class='flag-5'>传感器</b>测量模块的<b class='flag-5'>传感器</b><b class='flag-5'>接口</b>

    stm32f105主控作为传感器信号采集,精度和抗干扰怎样

    stm32f105主控作为传感器信号采集,精度和抗干扰怎样。。。。?模拟采样的时候,外围如何处理比较得当。。 现在做个东西,INA128U 采集压力
    发表于 05-11 08:08

    英飞凌推出用于Arduino的XENSIVTM传感器扩展板

    全球功率系统和物联网领域的半导体巨头英飞凌科技股份公司,近日宣布推出一款专为Arduino用户打造的XENSIV™传感器扩展板。这款多功能工具,特别为智能家居和各类消费应用中的智能传感器系统评估而设计。
    的头像 发表于 05-10 10:50 641次阅读

    英飞凌推出用于Arduino的XENSIV传感器扩展板, 搭载英飞凌和Sensirion的智能家居应用传感器

    的XENSIVTM传感器扩展板,这是一款专为评估智能家居和各种消费应用中的智能传感器系统而设计的多功能工具。这款创新型扩展板将英飞凌丰富的传感器产品与Sensirion的SHT35湿度和温度
    发表于 05-07 16:35 830次阅读
    英飞凌推出用于<b class='flag-5'>Arduino</b>的XENSIV<b class='flag-5'>传感器</b>扩展板, 搭载英飞凌和Sensirion的智能家居应用<b class='flag-5'>传感器</b>

    怎样用STM8L的PB3/TIM2_TRIG的引脚测量脉宽?

    怎样用STM8L的PB3/TIM2_TRIG的引脚测量脉宽?
    发表于 05-07 06:55

    stm32f100怎样用重映射功能?

    的是stm32f100c8t6b芯片,现在想用将PB1映射为TIM1_CH3N,在调用GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_TIM1)时, GPIO_PinAFConfig和GPIO_AF_TIM1都没定义,stm32f100
    发表于 05-07 06:06

    英飞凌和盛思锐合作推出一款支持Arduino传感器扩展板

    据麦姆斯咨询报道,近期,英飞凌(Infineon)推出了一款支持Arduino传感器扩展板,用于评估智能家居和其它消费类应用中的智能传感器系统。
    的头像 发表于 04-10 09:05 2301次阅读

    ​车传感器频繁损坏的原因及解决方案

    1.车传感器频繁损坏的原因?雷卯EMC小哥,在汽车客户做整改中发现,车传感器频繁损坏,主要的共同原因:不稳定的电压。在车辆工作过程中,电压波动是无法避免的。这些波动可能源自发动机的
    的头像 发表于 03-06 08:02 1180次阅读
    ​车<b class='flag-5'>用</b><b class='flag-5'>传感器</b>频繁损坏的原因及解决方案

    如何连接Arduino声音传感器控制带有声音的LED

    在本教程中,您将学习如何连接Arduino声音传感器控制带有声音的LED。在本指南结束时,您将拥有一个可以正常工作的声控LED!
    的头像 发表于 02-11 10:21 3040次阅读
    如何连接<b class='flag-5'>Arduino</b>声音<b class='flag-5'>传感器</b>以<b class='flag-5'>控制</b>带有声音的LED

    如何设置Arduino霍尔效应传感器

    在本指南中,您将学习如何设置Arduino霍尔效应传感器,特别是US1881,以检测磁场。这对于需要查找电机的转速或机器中其他运动的项目非常有用。
    的头像 发表于 02-11 10:14 1449次阅读
    如何设置<b class='flag-5'>Arduino</b>霍尔效应<b class='flag-5'>传感器</b>

    水位传感器工作原理 怎样判断水位传感器好坏

    水位传感器是一种用于测量液体水位高低的仪器。它们通常被用于工业和农业领域,以检测液体在容器或水池中的水位,可以帮助控制液位的变化,确保系统的正常运行。 水位传感器的工作原理可以分为多种类型,下面将
    的头像 发表于 01-17 14:33 3710次阅读

    测量是激光传感器还是超声波传感器

    测量是激光传感器还是超声波传感器  激光传感器和超声波传感器都是常用的测量工具,它们在不同的场景下具有各自的优点和适用性。在进行测量选择时
    的头像 发表于 01-03 15:59 582次阅读