Ubuntu16.04系统利用串口读取MPU6050角度

Ubuntu16.04系统利用串口读取MPU6050角度


一、惯性传感器介绍

1.1 产品概述

本实验选取的是高精度6轴惯性导航模块,此六轴模块采用高精度的陀螺加速度计 MPU6050,通过处理器读取 MPU6050 的测量数据然后通过串口输出,免去了用户自己去开发 MPU6050 复杂的 I2C 协议,同时精心的 PCB布局和工艺保证了 MPU6050 收到外接的干扰最小,测量的精度最高。本实验采取的是通过串口读取角度信息。对应的模块以及引脚如下图所示。

在这里插入图片描述

1.2 硬件连接方式

本实验主要涉及到的是模块与电脑之间的通讯,所以需要 USB 转 TTL 电平的串口模块,本实验选取的是六合一的串口模块,如下图所示:
在这里插入图片描述
USB 串口模块连接 6050 模块的方法是: USB 串口模块的+5V, TXD, RXD, GND 接6050 模块的 VCC, RX, TX, GND。 注意 TXD 和 RXD 的交叉。需要注意的是六合一串口模块连接6050模块是需要将2号拨码开关博导OFF端,如下图所示:
在这里插入图片描述

1.3 通讯协议

电平: TTL 电平(非 RS232 电平,若将模块错接到 RS232 电平可能造成模块损坏)波特率: 115200/9600,停止位 1,校验位 0。

1.3.1 上位机至模块

说明:
1.模块上电以后需先保持静止,模块内部的 MCU 会在模块静止的时候进行自动校准(消除陀螺零漂), 校准以后 Z 轴的角度会重新初始化为 0, Z 轴角度输出为 0 时,可视为自动校准完成的信号。
2.出厂默认设置使用串口,波特率 115200, 帧率 100Hz。配置可通过上位机软件配置,因为所有配置都是掉电保存的,所以只需配置一次就行。

1.3.2 模块至上位机

模块发送至上位机每帧数据分为 3 个数据包,分别为加速度包,角速度包和角度包, 3个数据包顺序输出,本实验以角度包为例。波特率 115200 时每隔 10ms 输出 1 帧数据,波特率9600 时每隔 50ms输出一帧数据。
在这里插入图片描述角速度计算公式:
滚转角(x 轴) Roll=((RollH<<8)|RollL)/32768180(°)
俯仰角(y 轴) Pitch=((PitchH<<8)|PitchL)/32768
180(°)
偏航角(z 轴) Yaw=((YawH<<8)|YawL)/32768*180(°)
温度计算公式:
T=((TH<<8)|TL) /340+36.53 ℃
校验和:
Sum=0x55+0x53+RollH+RollL+PitchH+PitchL+YawH+YawL+TH+TL
注:
1.姿态角结算时所使用的坐标系为东北天坐标系, 正方向放置模块,如下图所示向左为 X 轴,向前为 Y 轴,向上为 Z 轴。 欧拉角表示姿态时的坐标系旋转顺序定义为为z-y-x,即先绕 z 轴转,再绕 y 轴转,再绕 x 轴转。
2.滚转角的范围虽然是±180 度,但实际上由于坐标旋转顺序是 Z-Y-X,在表示姿态的时候, 俯仰角(Y 轴)的范围只有±90 度,超过 90 度后会变换到小于 90 度,同时让 X 轴的角度大于 180 度。详细原理请大家自行百度欧拉角及姿态表示的相关信息。
3. 由于三轴是耦合的,只有在小角度的时候会表现出独立变化,在大角度的时候姿态角度会耦合变化,比如当 X 轴接近 90 度时,即使姿态只绕 X 轴转动, Y 轴的角度也会跟着发生较大变化,这是欧拉角表示姿态的固有问题。

1.4 数据解析示例代码

double a[3],w[3],Angle[3],T;
void DecodeIMUData(unsigned char chrTemp[])
{
	switch(chrTemp[1])
	{
		case 0x51:
			a[0] = (short(chrTemp[3]<<8|chrTemp[2]))/32768.0*16;
			a[1] = (short(chrTemp[5]<<8|chrTemp[4]))/32768.0*16;
			a[2] = (short(chrTemp[7]<<8|chrTemp[6]))/32768.0*16;
			T = (short(chrTemp[9]<<8|chrTemp[8]))/340.0+36.25;
			break;
		case 0x52:
			w[0] = (short(chrTemp[3]<<8|chrTemp[2]))/32768.0*2000;
			w[1] = (short(chrTemp[5]<<8|chrTemp[4]))/32768.0*2000;
			w[2] = (short(chrTemp[7]<<8|chrTemp[6]))/32768.0*2000;
			T = (short(chrTemp[9]<<8|chrTemp[8]))/340.0+36.25;
		    break;
		case 0x53:
			Angle[0] = (short(chrTemp[3]<<8|chrTemp[2]))/32768.0*180;
			Angle[1] = (short(chrTemp[5]<<8|chrTemp[4]))/32768.0*180;
			Angle[2] = (short(chrTemp[7]<<8|chrTemp[6]))/32768.0*180;
			T = (short(chrTemp[9]<<8|chrTemp[8]))/340.0+36.25;
			breakprintf("a = %4.3f\t%4.3f\t%4.3f\t\r\n",a[0],a[1],a[2]);
		printf("w = %4.3f\t%4.3f\t%4.3f\t\r\n",w[0],w[1],w[2]);
		printf("Angle = %4.2f\t%4.2f\t%4.2f\tT=%4.2f\r\n",Angle[0],Angle[1],Angle[2],T);
	}
}

二、实验步骤

1.串口初始化(c语言版)

代码如下(示例):

int LKSerialInit()
{
    leftknee_nFd = open(LKDEVICE, O_RDWR|O_NOCTTY|O_NDELAY);   //打开串口USB0
    if(-1 == leftknee_nFd)
    {
        perror("Open Serial Port Error!\n");
        return -1;
    }
    if( (fcntl(leftknee_nFd, F_SETFL, 0)) < 0 )
    {
        perror("Fcntl F_SETFL Error!\n");
        return -1;
    }
    if(tcgetattr(leftknee_nFd, &leftknee_stOld) != 0)
    {
        perror("tcgetattr error!\n");
        return -1;
    }

    leftknee_stNew = leftknee_stOld;
    cfmakeraw(&leftknee_stNew);//将终端设置为原始模式,该模式下全部的输入数据以字节为单位被处理
    /**1. tcgetattr函数用于获取与终端相关的参数。
    *参数fd为终端的文件描述符,返回的结果保存在termios结构体中
    */
    //set speed
    cfsetispeed(&leftknee_stNew, BAUDRATE);   //设置波特率115200s
    //set databits
    leftknee_stNew.c_cflag |= (CLOCAL|CREAD); //设置控制模式状态,本地连接,接收使能
    leftknee_stNew.c_cflag &= ~CSIZE;         //字符长度,设置数据位之前一定要屏掉这个位
    leftknee_stNew.c_cflag |= CS8;            //8位数据长度
    //set parity
    leftknee_stNew.c_cflag &= ~PARENB;
    leftknee_stNew.c_iflag &= ~INPCK;         //无奇偶检验位
    //set stopbits
    leftknee_stNew.c_cflag &= ~CSTOPB;        //1位停止位

    //stNew.c_oflag = 0; //输出模式
    //stNew.c_lflag = 0; //不激活终端模式

    leftknee_stNew.c_cc[VTIME]=0;             //指定所要读取字符的最小数量
    leftknee_stNew.c_cc[VMIN]=1;              //指定读取第一个字符的等待时间,时间的单位为n*100ms
    //假设设置VTIME=0,则无字符输入时read()操作无限期的堵塞
    /**3. 设置新属性,TCSANOW:所有改变立即生效*/
    tcflush(leftknee_nFd,TCIFLUSH);           //清空终端未完毕的输入/输出请求及数据。

    if( tcsetattr(leftknee_nFd,TCSANOW,&leftknee_stNew) != 0 )
    {
        perror("tcsetattr Error!\n");
        return -1;
    }
    return leftknee_nFd;
}

2.Ubuntu系统下操作流程

首先插入USB转ttl模块(插入顺序一定对应好程序的接受顺序,避免出现数据交叉接受现象),然后输入以下命令查询USB通道,一般从USB0开始,结果如下图所示。

ls -m /dev/ttyUSB*

在这里插入图片描述 然后依次修改串口使用权限,每次重新插入或者重启电脑都要重新修改,命令依次为:

sudo chmod 777 /dev/ttyUSB0 
sudo chmod 777 /dev/ttyUSB01

在这里插入图片描述 然后就是运行程序,最终结果如下图所示(本实验只计算了x/y/z的角度):
在这里插入图片描述
在这里插入图片描述

3. 完整程序

完整程序
https://download.csdn.net/download/ljduzun/13719494

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值