亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

IMU (6 DOF) 运动传感器入门

组件和用品

Arduino UNO
× 1
惯性测量单元 (IMU)(6 度自由度)
× 1

关于这个项目

今天我们将研究最好的 IMU(惯性测量单元)传感器,并了解它如何与 Arduino 连接。稍后在我们的下一个教程中,我们将尝试在 3D 中可视化运动传感。

我们将使用的 IMU 传感器模块以 MPU-6050 传感器为中心。

MPU-6050 设备结合了3 轴陀螺仪3 轴加速度计 在同一个硅片上,以及一个板载数字运动处理器™ (DMP™) ,处理复杂的 6 轴 MotionFusion 算法。

这些 MotionTracking 设备专为满足智能手机、平板电脑和可穿戴传感器的低功耗、低成本和高性能要求而设计。

您需要的东西:

硬件:

1) Arduino UNO

2) MPU 6050 传感器

3) 连接电线

软件: Arduino IDE

通信协议: 该 IMU 传感器使用 I2C 总线协议与 Arduino 通信。

您可以单独处理加速度计和陀螺仪,但它们不如这个组合模块那么准确。

现在,让我们继续看接线图和连接配置文件。

参考下面这两个图中的任何一个进行连接。

如果您遇到上述数字的问题,请不要惊慌......

通过下面的连接引脚配置文件:

将 5V [IMU MPU-6050] 连接到 VCC [ARDUINO]

将 SDA [IMU MPU-6050] 连接到模拟输入 (A4) [ARDUINO]

将 SCL [IMU MPU-6050] 连接到模拟输入 (A5) [ARDUINO]

将 GND [IMU MPU-6050] 连接到 GND [ARDUINO]

将 INTPIN [IMU MPU-6050] 连接到引脚 2(数字 PWM 引脚)[ARDUINO]

在这里,如果您的 MPU 6050 模块有 5V 引脚,那么您可以将其连接到 arduino 的 5V 引脚。否则,您必须将其连接到 3.3V 引脚以避免任何过压问题。

所以现在我们已经设置了硬件,是时候对 Arduino 进行编程了。

首先,为了测试 MPU 6050,请点击此链接并下载 MPU 6050 的 arduino 库。有一个名为“MPU6050.zip”的 zip 文件夹。下载文件夹并解压缩其内容。执行此操作后,复制库文件夹“MPU6050”并将其粘贴到 Arduino 的库文件夹中。也就是说,你必须去Arduino的“libraries”文件夹所在的位置,然后将这个“MPU6050”文件夹粘贴在里面。

接下来,您需要下载另一个名为“I2Cdev.zip”的库(如果之前未安装)并将其粘贴到 Arduino 的库中,方法与之前的库相同。

所以现在,在 Arduino 的“libraries”文件夹中,我们有两个新实体。 (图:8)

现在,点击 arduino IDE,看看这些新库是否可见(图 (9))。

在您的草图中包含这些库之前,您需要获取 MPU6050 的代码。参考图(10)

(文件> 示例> MPU6050> 示例> MPU6050_DMP6)。点击这个“MPU6050_DMP6”文件。

接下来,在此草图中包含库“I2Cdev”和“MPU6050”[图 (11)]。

完成所有步骤后,编译草图[图(12)]。

现在,最后一步仍然......

如果您注意到此窗口的右下角,消息显示“COM1 上的 Arduino/Genuino Uno”,请确保其是否正确。如果不是,请参考 [图 (14)]。现在不要单击串行监视器。只有在上传草图后[如图(13)],才能进行下一步。

您必须确保每次连接 Arduino 时都分配了正确的端口。

对这个新窗口感到困惑?嗯,那是你的输出屏幕。从技术上讲,我们称其为串行监视器。这就是我们从不同传感器读取值的地方。

STEP:工具>串行监视器或,快捷键(Ctrl + Shift + M)

如果您在上传草图时遇到问题,即使您选择了正确的端口。单击此链接(适用于 Windows 用户)。对于 Mac 用户,请参阅指南。 Linux 用户参考此网页获取指导。

上传代码后,打开串口监视器并将“波特率”更改为115200。如果您选择任何其他波特率,那么您将看到垃圾注释,因为它们不会同步。 注意: 8MHz 或更慢的主机处理器,如以 3.3v 运行的 Teensy @ 3.3v 或 Ardunio Pro Mini,无法可靠地处理此波特率,因为波特时序与处理器滴答声太不对齐。在这些情况下,您必须使用 38400 或更慢的,或者为 UART 定时器使用某种外部独立晶体解决方案。

如果您在屏幕上没有看到“初始化 I2C 设备...”这句话,请按 RESET 按钮。它现在应该可以工作了。 [图(15)]


知识角>> 您将看到一行内容为“发送任何字符以开始 DMP 编程和演示:”什么是 DMP??

答案: DMP 代表数字运动处理 . Invense 的 MPU 6050 具有内置运动处理器。它处理来自加速度计和陀螺仪的值,为我们提供准确的 3D 值;即偏航,俯仰和滚动。 [图(16)]


知识角>> 我们看到传感器和arduino之间的通信是基于I2C总线协议的。同样,我们还在这个项目中包含了一个 I2C 库。你知道吗,I2C 代表什么?

答案: I2C 总线物理上由 2 条有源电线和一个接地连接组成。有源线,称为 SDA SCL , 都是双向的。 SDA 是串行数据线,SCL 是串行时钟线。连接到总线的每个设备都有自己唯一的地址,无论是 MCU、LCD 驱动程序、内存还是 ASIC。这些芯片中的每一个都可以充当接收器和/或发送器,具体取决于功能。很明显,LCD驱动器只是一个接收器,而存储器或I/O芯片既可以是发送器也可以是接收器。I2C总线是多主总线。这意味着可以连接多个能够启动数据传输的 IC。 I2C 协议规范规定,在总线上启动数据传输的 IC 被视为总线主控器。因此,当时所有其他IC都被认为是Bus Slaves。由于总线主控一般是微控制器,例如,总线主控是ArduinoUno。同样,MPU 传感器是总线从设备。


在我的下一个教程中以 3D 形式可视化运动。点击这里




代码

  • MPU 传感器的 Arduino 代码
MPU 传感器的 Arduino 代码Arduino
*/// I2Cdev 和 MPU6050 必须作为库安装,否则两个类的 .cpp/.h 文件// 必须在项目的包含路径中#include "I2Cdev.h"#include "MPU6050_6Axis_MotionApps20 .h"//#include "MPU6050.h" // 如果使用 MotionApps 包含文件则不需要 // 如果 I2Cdev I2CDEV_ARDUINO_WIRE 实现需要 Arduino Wire 库// 用于 I2Cdev.h#if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE #include "Wire .h"#endif// 类默认 I2C 地址为 0x68// 此处可以将特定 I2C 地址作为参数传递// AD0 低 =0x68(SparkFun 突破和 InvenSense 评估板的默认值)// AD0 高 =0x69MPU6050 mpu;/ /MPU6050 处理器(0x69); // <-- 用于 AD0 高/* ========================================================================注意:除了连接 3.3v、GND、SDA 和 SCL,此草图取决于 MPU-6050 的 INT 引脚连接到 Arduino 的外部中断 #0 引脚。在 Arduino Uno 和 Mega 2560 上,这是数字 I/O 引脚 2。 * ========================================================================*//* =========================================================================注意:使用 Serial.write(buf, len) 时,带有 Leonardo 板的 Arduino v1.0.1 会生成编译错误。茶壶输出使用此方法。该解决方案需要修改 Arduino USBAPI.h 文件,幸运的是这很简单,但很烦人。这将在下一个 IDE 版本中修复。有关详细信息,请参阅以下链接:http://arduino.cc/forum/index.php/topic,109987.0.html http://code.google.com/p/arduino/issues/detail?id=958 * =========================================================================*/// 如果您想查看 [w, x, y, z] 格式(不适合在远程主机上解析//,例如Processing 或其他东西)//#define OUTPUT_READABLE_QUATERNION// 如果您想查看欧拉角//(以度为单位)根据即将到来的四元数计算,请取消注释“OUTPUT_READABLE_EULER”来自 FIFO。// 请注意,欧拉角会受到万向节锁定(有关更多信息,请参阅// http://en.wikipedia.org/wiki/Gimbal_lock)//#define OUTPUT_READABLE_EULER// 如果您愿意,请取消注释“OUTPUT_READABLE_YAWPITCHROLL”查看偏航/// 俯仰/滚转角(以度为单位),这是根据来自 FIFO 的四元数计算的//。请注意,这也需要重力矢量计算。// 另请注意,偏航/俯仰/滚转角会受到万向节锁定(有关// 更多信息,请参阅:http://en.wikipedia.org/wiki/Gimbal_lock)#define OUTPUT_READABLE_YAWPITCHROLL/ / 取消注释“OUTPUT_READABLE_REALACCEL”,如果你想看到加速度//去除重力的组件。该加速度参考系//未针对方向进行补偿,因此根据//传感器,+X 始终为+X,只是没有重力的影响。如果你想要加速度 // 补偿方向,我们使用 OUTPUT_READABLE_WORLDACCEL 代替。//#define OUTPUT_READABLE_REALACCEL // 如果你想看到加速度 // 移除并调整重力的组件 // 参考(偏航是相对于初始方向,因为在这种情况下不存在磁力计//)。在某些情况下可能非常方便。//#define OUTPUT_READABLE_WORLDACCEL// 如果您希望输出与用于 InvenSense 茶壶演示的// 格式相匹配//#define OUTPUT_TEAPOT#define LED_PIN 13 //(Arduino 是 13 ,Teensy 是 11,Teensy++ 是 6)boolblinkState =false;// MPU 控制/状态 varsbool dmpReady =false; // 如果 DMP 初始化成功则设置为真uint8_t mpuIntStatus; // 保存来自 MPUuint8_t devStatus 的实际中断状态字节; // 每次设备操作后返回状态(0 =成功,!0 =错误)uint16_t packetSize; // 预期的 DMP 数据包大小(默认为 42 字节)uint16_t fifoCount; // 当前 FIFOuint8_t fifoBuffer[64] 中所有字节的计数; // FIFO 存储缓冲区// 方向/运动 varsQuaternion q; // [w, x, y, z] 四元数 containerVectorInt16 aa; // [x, y, z] 加速传感器测量VectorInt16 aaReal; // [x, y, z] 无重力加速度传感器测量值VectorInt16 aaWorld; // [x, y, z] 世界坐标系加速度传感器测量值矢量浮点重力; // [x, y, z] 重力向量float euler[3]; // [psi, theta, phi] 欧拉角 containerfloat ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll 容器和重力矢量// InvenSense 茶壶的数据包结构 demouint8_t teapotPacket[14] ={ '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };// ==================================================================// ===中断检测程序 ===// ================================================================volatile bool mpuInterrupt =false; // 指示 MPU 中断引脚是否已变为 highvoid dmpDataReady() { mpuInterrupt =true;}// ================================================================// ===初始设置 ===// =================================================================void setup() { // 加入 I2C 总线(I2Cdev 库不会自动执行此操作)#if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR =24; // 400kHz I2C 时钟(如果 CPU 为 8MHz,则为 200kHz)#elif I2CDEV_IMPLEMENTATION ==I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // 初始化串行通信 //(选择 115200 是因为茶壶演示输出需要它,但它 // 真的取决于你的项目) Serial.begin(115200);而(!串行); // 等待 Leonardo 枚举,其他人立即继续 // 注意:8MHz 或更慢的主机处理器,如 Teensy @ 3.3v 或 Ardunio // Pro Mini 以 3.3v 运行,由于 // 波特计时,无法可靠地处理此波特率与处理器滴答声太不对齐。在这些情况下,您必须使用 // 38400 或更慢,或者为 UART 定时器使用某种外部独立的 // 晶体解决方案。 // 初始化设备 Serial.println(F("Initializing I2C devices...")); mpu.initialize(); // 验证连接 Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 连接成功") :F("MPU6050 连接失败")); // 等待就绪 Serial.println(F("\n发送任意字符开始 DMP 编程和演示:"));而 (Serial.available() &&Serial.read()); // 空缓冲区 while (!Serial.available()); // 等待数据 while (Serial.available() &&Serial.read()); // 再次清空缓冲区 // 加载并配置 DMP Serial.println(F("Initializing DMP...")); devStatus =mpu.dmpInitialize(); // 在这里提供您自己的陀螺仪偏移量,按最小灵敏度进行缩放 mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); // 我的测试芯片的出厂默认值为 1688 // 确保它正常工作(如果是,则返回 0) if (devStatus ==0) { // 打开 DMP,现在它已准备就绪 Serial.println(F("Enabling DMP. ..")); mpu.setDMPEnabled(true); // 启用 Arduino 中断检测 Serial.println(F("启用中断检测 (Arduino 外部中断 0)...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus =mpu.getIntStatus(); // 设置我们的 DMP Ready 标志,以便主 loop() 函数知道可以使用它 Serial.println(F("DMP ready! Waiting for first interrupt...")); dmpReady =真; // 获取预期的 DMP 数据包大小以供稍后比较 packetSize =mpu.dmpGetFIFOPacketSize(); } else { // 错误! // 1 =初始内存加载失败 // 2 =DMP 配置更新失败 //(如果它会中断,通常代码将为 1) Serial.print(F("DMP Initialization failed (code ")); Serial.print(F("DMP Initialization failed (code ")); Serial.打印(devStatus);Serial.println(F(“)”)); } // 配置 LED 输出 pinMode(LED_PIN, OUTPUT);}// ==============================================================// ===主程序循环 ===// ================================================================void loop() { // 如果编程失败,不要尝试做任何事情 if (!dmpReady) return; // 等待 MPU 中断或额外的数据包可用,而 (!mpuInterrupt &&fifoCount  1 个可用数据包 //(这让我们可以立即读取更多数据而无需等待中断) fifoCount -=packetSize; #ifdef OUTPUT_READABLE_QUATERNION // 以简单的矩阵形式显示四元数值: w x y z mpu.dmpGetQuaternion(&q, fifoBuffer); Serial.print("quat\t"); Serial.print(q.w); Serial.print("\t"); Serial.print(q.x); Serial.print("\t"); Serial.print(q.y); Serial.print("\t"); Serial.println(q.z); #endif #ifdef OUTPUT_READABLE_EULER // 以度为单位显示欧拉角 mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetEuler(euler, &q); Serial.print("euler\t"); Serial.print(euler[0] * 180/M_PI); Serial.print("\t"); Serial.print(euler[1] * 180/M_PI); Serial.print("\t"); Serial.println(euler[2] * 180/M_PI); #endif #ifdef OUTPUT_READABLE_YAWPITCHROLL // 以度为单位显示欧拉角 mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); Serial.print("ypr\t"); Serial.print(ypr[0] * 180/M_PI); Serial.print("\t"); Serial.print(ypr[1] * 180/M_PI); Serial.print("\t"); Serial.println(ypr[2] * 180/M_PI); #endif #ifdef OUTPUT_READABLE_REALACCEL // 显示真实加速度,调整去除重力 mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetAccel(&aa, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); Serial.print("area\t"); Serial.print(aaReal.x); Serial.print("\t"); Serial.print(aaReal.y); Serial.print("\t"); Serial.println(aaReal.z); #endif #ifdef OUTPUT_READABLE_WORLDACCEL // 显示初始世界坐标系加速度,调整以消除重力 // 并根据四元数的已知方向旋转 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); #endif #ifdef OUTPUT_TEAPOT // 以 InvenSense 茶壶演示格式显示四元数值:teapotPacket[2] =fifoBuffer[0];茶壶包[3] =fifoBuffer[1];茶壶包[4] =fifoBuffer[4];茶壶包[5] =fifoBuffer[5];茶壶包[6] =fifoBuffer[8];茶壶包[7] =fifoBuffer[9];茶壶包[8] =fifoBuffer[12];茶壶包[9] =fifoBuffer[13]; Serial.write(teapotPacket, 14);茶壶包[11]++; // packetCount,故意在 0xFF 处循环 #endif // 闪烁 LED 以指示活动闪烁状态 =!blinkState;数字写入(LED_PIN,blinkState); }}

示意图


制造工艺

  1. 带 RPi 的线跟踪传感器
  2. 带有 RPi 的环境传感器 API
  3. 使用 Raspberry Pi 的运动传感器
  4. 带有 PIR 运动传感器的 Raspberry Pi GPIO:最佳教程
  5. 将 HC-SR501 PIR 运动传感器与 Raspberry Pi 连接
  6. TJBot 入门
  7. 开始使用 RAK 831 Lora Gateway 和 RPi3
  8. RAK831 LoRa 网关和 RPi3 入门
  9. 保险业人工智能入门:入门指南
  10. Arduino教程01:入门
  11. Eagle Group 入门:您需要了解的内容
  12. My.Cat.com 入门