前言
这块属于随便扯扯,算是个开发备忘的说明吧。
最近有个课程作业,需要实现惯性导航,那么就先使用PySerial库实现加速度计的数值读取,后续再使用PyQt+多进程+matplotlib实现加速度、角速度曲线的实时绘制,这里主要是实现命令行中串口数据的读写、显示。
下位机传输信息
为了简单,用的Stm32 f103刷arduino的BL,使用Arduino进行开发
总体接线情况是MPU6050的IIC接PB6\PB7,关于Stm32的引脚映射如图。
顺便吐槽一下,Stm32使用ardunio开发使用IIC时默认只能用SCL1/SDA1,其他需要声明,谁让咱不会用keil呢
源代码如下,一般也都能找到,详细的解释可以移步这篇博文
#include <Wire.h>
// 定义为全局变量,可直接在函数内部使用
float gForceX, gForceY, gForceZ;
float rotX, rotY, rotZ;
long gyroX, gyroY, gyroZ;
long accelX, accelY, accelZ;
注意!!!!这个网上流传的程序存在Bug!!!!
经过博主一天的调试,发现一个问题,如果全局变量定义如上面代码所述,那么会出问题——你的测量值会超量程,并且X轴角速度的偏差会很大。先后从网上找程序测试、delay秒数调整、位运算测试啥的弄了一天,最后发现原因很无语。由于MPU6050使用两个寄存器存储一个数据,因此数据长度为2个字节,16位,如果使用long/int会使读取数据均为正数,超出量程,必须使用short型变量存储…就是这么简单的问题,解决方案就是修改定义:
short gyroX, gyroY, gyroZ;
short accelX, accelY, accelZ;
void setup() {
Serial.begin(9600);//设置波特率为9600
while(!Serial.available()){
continue;//等到串口可用进行下一步
while(Serial.read()>= 0){}//要首先发送一个信息才能实现初始化
//Serial.println("start communication");
}
Wire.begin();
setupMPU();
}
void loop() {
recordAccelRegisters();
recordGyroRegisters();
printData();
delay(500);
}
下面是初始化MPU,寄存器的详细信息可以参考MPU6050的技术手册,这里主要是通过0x6B重置/启动MPU6050,0x68的用途我也不晓得,技术手册说是重置数/模信号路径。
0x1B实现角速度范围的配置,0x1C实现加速度范围的配置,配置方式是向对应地址写入相关字节,0为默认情况,对应正负250度/秒和正负2倍重力加速度。
对于加速度和角速度,MPU6050采用16位有符号整数表示,因此可以通过 2 g ⋆ A C C E L ÷ 32768 2g\star ACCEL\div 32768 2