MPU6050 - GY-521的简单使用

MPU6050 - GY-521的简单使用

1.任务说明:

本次的任务是:实现MPU6050-GY-521系列的简单使用。

  1. 在arduino中读取数据,并显示数据。
  2. 使用Python进行三维渲染,显示三维的平衡。

2.环境说明:

主机系统:Ubuntu19.04 (桌面版)

Python:3.71

arduino IDE: 2:1.0.5

arduino 板子:Arduino uno R3

测试板子:MPU6050-GY-512(淘宝都有买)

Arduino uno R3
在这里插入图片描述

MPU6050-GY-512

在这里插入图片描述

3.arduino接收与输出数据

(1)参考网站:

https://playground.arduino.cc/Main/MPU-6050/

https://github.com/makelove/Pi_Self_Driving_Car/tree/master/ROS/Kinetic/IMU/mpu6050

(2)实物连接:

在这里插入图片描述

(3)具体代码:

// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  Serial.print("AcX = ");Serial.print(AcX);
  Serial.print(" | AcY = ");Serial.print(AcY);
  Serial.print(" | AcZ = ");Serial.print(AcZ);
  Serial.print(" | Tmp = ");Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = ");Serial.print(GyX);
  Serial.print(" | GyY = ");Serial.print(GyY);
  Serial.print(" | GyZ = ");Serial.println(GyZ);
  delay(333);
}

(4)效果演示:

提示:使用串口接收器查看(arduino IDE 右上角处)

[

4.python接收数据与三维显示:

(1)参考网站:

<1>. arduino的代码参考:

https://www.basemu.com/3d-opengl-visualisation-of-the-data-from-an-mpu-6050.html

https://www.basemu.com/reading-data-from-the-mpu-6050-on-the-raspberry-pi-for-python.html

<2>pyhton的代码参考:

arduino向python传送数据:https://www.bilibili.com/video/av64658484/?p=2

python显示三维数据:https://www.basemu.com/3d-opengl-visualisation-of-the-data-from-an-mpu-6050.html

(2)具体代码:

<1>arduino 代码
// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  Serial.print(AcX);
  Serial.print(","); 
  Serial.print(AcY);
  Serial.print(","); 
  Serial.print(AcZ);
  Serial.print(","); 
  Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(","); 
  Serial.print(GyX);
  Serial.print(","); 
  Serial.print(GyY);
  Serial.print(","); 
  Serial.println(GyZ);
  delay(333);
}

以逗号为分隔符来输出数据,使用串口接收器查看(arduino IDE 右上角处)

这个也是arduino给电脑(Python)的角度数据。

在这里插入图片描述

<2>python 代码—获取数据

安装通信模块:serial库,

在命令行:pip install pyserial


# 导入通信的模块
import serial

# 创建串口通信
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.5)


# 不断搜索是否有信息传入
while 1:
    # 读取串口的信息
    val = ser.readline().decode('utf-8')

    # 以逗号来分割传入的数据
    parsed = val.split(',')

    # 去除末尾的数据
    parsed = [ x.rstrip() for x in parsed]

    # 把数据转化为数字类型
    parsed = [ eval(x) for x in parsed]
    print(parsed)

在Python里使数据变为列表类型,列表里又是浮点数类型,便于后面的计算。

在这里插入图片描述

<3>pyhton 代码—显示三维

显示三维的原理:是根据上面的代码先获取数据,再根于数据来显示模型。

所需要到的库:pygame , OpenGL

安装第三方库:pip install pygame ,pip install PyOpenGL

完整python代码:

"""
    成功运行
"""

#!/usr/bin/python

import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
from math import radians
from pygame.locals import *

# 导入通信的模块
import serial

# 创建串口通信
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.5)


SCREEN_SIZE = (800, 600)
SCALAR = .5
SCALAR2 = 0.2


def resize(width, height):
    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45.0, float(width) / height, 0.001, 10.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    gluLookAt(0.0, 1.0, -5.0,
              0.0, 0.0, 0.0,
              0.0, 1.0, 0.0)


def init():
    glEnable(GL_DEPTH_TEST)
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glShadeModel(GL_SMOOTH)
    glEnable(GL_BLEND)
    glEnable(GL_POLYGON_SMOOTH)
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST)
    glEnable(GL_COLOR_MATERIAL)
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glLightfv(GL_LIGHT0, GL_AMBIENT, (0.3, 0.3, 0.3, 1.0));


def read_values():
    # 读取串口的信息
    val = ser.readline().decode('utf-8')

    # 以逗号来分割传入的数据
    parsed = val.split(',')

    # 去除末尾的数据
    parsed = [x.rstrip() for x in parsed]

    if(len(parsed) > 2):
        # 把数据转化为数字类型
        parsed = [eval(x) for x in parsed]
        return parsed
    else:
        return [0,0,0,0,0]


def run():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, HWSURFACE | OPENGL | DOUBLEBUF)
    resize(*SCREEN_SIZE)
    init()
    clock = pygame.time.Clock()
    cube = Cube((0.0, 0.0, 0.0), (.5, .5, .7))
    angle = 0

    while True:
        then = pygame.time.get_ticks()
        for event in pygame.event.get():
            if event.type == QUIT:
                return
            if event.type == KEYUP and event.key == K_ESCAPE:
                return

        values = read_values()
        x_angle = values[0]/ 131
        print(x_angle)
        y_angle = values[1]/ 131
        print(y_angle)

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glColor((1., 1., 1.))
        glLineWidth(1)
        glBegin(GL_LINES)

        for x in range(-20, 22, 2):
            glVertex3f(x / 10., -1, -1)
            glVertex3f(x / 10., -1, 1)

        for x in range(-20, 22, 2):
            glVertex3f(x / 10., -1, 1)
            glVertex3f(x / 10., 1, 1)

        for z in range(-10, 12, 2):
            glVertex3f(-2, -1, z / 10.)
            glVertex3f(2, -1, z / 10.)

        for z in range(-10, 12, 2):
            glVertex3f(-2, -1, z / 10.)
            glVertex3f(-2, 1, z / 10.)

        for z in range(-10, 12, 2):
            glVertex3f(2, -1, z / 10.)
            glVertex3f(2, 1, z / 10.)

        for y in range(-10, 12, 2):
            glVertex3f(-2, y / 10., 1)
            glVertex3f(2, y / 10., 1)

        for y in range(-10, 12, 2):
            glVertex3f(-2, y / 10., 1)
            glVertex3f(-2, y / 10., -1)

        for y in range(-10, 12, 2):
            glVertex3f(2, y / 10., 1)
            glVertex3f(2, y / 10., -1)

        glEnd()
        glPushMatrix()
        glRotate(float(x_angle), 1, 0, 0)
        glRotate(-float(y_angle), 0, 0, 1)
        cube.render()
        glPopMatrix()
        pygame.display.flip()


class Cube(object):

    def __init__(self, position, color):
        self.position = position
        self.color = color

    # Cube information
    num_faces = 6

    vertices = [(-1.0, -0.05, 0.5),
                (1.0, -0.05, 0.5),
                (1.0, 0.05, 0.5),
                (-1.0, 0.05, 0.5),
                (-1.0, -0.05, -0.5),
                (1.0, -0.05, -0.5),
                (1.0, 0.05, -0.5),
                (-1.0, 0.05, -0.5)]

    normals = [(0.0, 0.0, +1.0),  # front
               (0.0, 0.0, -1.0),  # back
               (+1.0, 0.0, 0.0),  # right
               (-1.0, 0.0, 0.0),  # left
               (0.0, +1.0, 0.0),  # top
               (0.0, -1.0, 0.0)]  # bottom

    vertex_indices = [(0, 1, 2, 3),  # front
                      (4, 5, 6, 7),  # back
                      (1, 5, 6, 2),  # right
                      (0, 4, 7, 3),  # left
                      (3, 2, 6, 7),  # top
                      (0, 1, 5, 4)]  # bottom

    def render(self):
        then = pygame.time.get_ticks()
        glColor(self.color)

        vertices = self.vertices

        # Draw all 6 faces of the cube
        glBegin(GL_QUADS)

        for face_no in  range(self.num_faces):
            glNormal3dv(self.normals[face_no])
            v1, v2, v3, v4 = self.vertex_indices[face_no]
            glVertex(vertices[v1])
            glVertex(vertices[v2])
            glVertex(vertices[v3])
            glVertex(vertices[v4])
        glEnd()


if __name__ == "__main__":
    run()

显示效果如下:当我们转动一定角度时,在模型里,也对应转动一定的角度。

在这里插入图片描述

5.最后的提示:

先运行arduino 代码,在运行pyhton的完整代码,两者在共同一个电脑运行。

作者:张一根

日期:2019/10/4

  • 20
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MPU6050 是一种常用的六轴陀螺仪传感器模块,可以用于检测物体的加速度和角速度。要使用 MPU6050 模块,需要连接到 Arduino 单片机,并使用相应的库进行编程。 以下是使用 MPU6050 模块的基本步骤: 1. 连接 MPU6050 模块Arduino 单片机。连接方法如下: - 将 MPU6050 模块的 VCC 引脚连接到 Arduino 的 5V 引脚。 - 将 MPU6050 模块的 GND 引脚连接到 Arduino 的 GND 引脚。 - 将 MPU6050 模块的 SDA 引脚连接到 Arduino 的 A4 引脚。 - 将 MPU6050 模块的 SCL 引脚连接到 Arduino 的 A5 引脚。 2. 在 Arduino IDE 中安装 MPU6050 库。可以在库管理器中搜索 MPU6050 并安装。 3. 编写程序,使用 MPU6050 库读取 MPU6050 模块的数据。以下是一个简单的示例程序: ```c++ #include <Wire.h> #include <MPU6050.h> MPU6050 mpu; // 创建一个 MPU6050 对象 void setup() { Wire.begin(); // 初始化 I2C 总线 mpu.initialize(); // 初始化 MPU6050 Serial.begin(9600); // 初始化串口 } void loop() { int16_t ax, ay, az, gx, gy, gz; // 定义变量存储 MPU6050 的数据 mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); // 读取 MPU6050 的数据 Serial.print("加速度计:"); Serial.print(ax); Serial.print(", "); Serial.print(ay); Serial.print(", "); Serial.println(az); Serial.print("陀螺仪:"); Serial.print(gx); Serial.print(", "); Serial.print(gy); Serial.print(", "); Serial.println(gz); delay(10); } ``` 在这个程序中,我们使用了 Wire 库和 MPU6050 库,需要在 Arduino IDE 中安装这两个库才能正常编译和上传。在 `setup()` 函数中,我们初始化了 I2C 总线、MPU6050 传感器模块和串口。在 `loop()` 函数中,我们读取了 MPU6050 传感器模块的加速度计和陀螺仪数据,并通过串口输出到电脑上。程序每隔 10 毫秒执行一次。 通过这个程序,我们可以实时读取 MPU6050 传感器模块的加速度计和陀螺仪数据,用于控制舵机等其他组件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值