MPU6050 - GY-521的简单使用

MPU6050 - GY-521的简单使用

文章目录

  • MPU6050 - GY-521的简单使用
    • 1.任务说明:
    • 2.环境说明:
    • 3.arduino接收与输出数据
      • (1)参考网站:
      • (2)实物连接:
      • (3)具体代码:
      • (4)效果演示:
    • 4.python接收数据与三维显示:
      • (1)参考网站:
      • (2)具体代码:
        • <1>arduino 代码
        • <2>python 代码---获取数据
        • <3>pyhton 代码---显示三维
    • 5.最后的提示:

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-521的简单使用_第1张图片

MPU6050-GY-512

MPU6050 - GY-521的简单使用_第2张图片

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)实物连接:

MPU6050 - GY-521的简单使用_第3张图片

(3)具体代码:

// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include
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 右上角处)

MPU6050 - GY-521的简单使用_第4张图片

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
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)的角度数据。

MPU6050 - GY-521的简单使用_第5张图片

<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里使数据变为列表类型,列表里又是浮点数类型,便于后面的计算。

MPU6050 - GY-521的简单使用_第6张图片

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

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

MPU6050 - GY-521的简单使用_第7张图片

5.最后的提示:

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

作者:张一根

日期:2019/10/4

你可能感兴趣的:(控制硬件的学习,MPU6050-GY512,arduino,pyhton,三维模型)