树莓派 连接 JY901(MPU9250) python 代码
先说BUG,最近要做项目需要树莓派和陀螺仪,资金充足的话肯定是买一个硬件卡尔曼滤波的传感器类似JY901模块,资金不足的就买MPU6050。
网上关于MPU6050在树莓派上的代码还能用,关于JY901的代码真的是千奇百怪,而且复制现象特别严重,有很多系统本身有问题,导致很多像我一样的新手在上面浪费了很多的时间。
本篇主要把这一个多星期折腾树莓派陀螺仪的经历总结一下,顺便帮助下其他像我一样的新手,把时间用在系统设计上。
网上的代码有 try except 判断,把运行时遇到的IOError全部判0处理,然后读出好像是陀螺仪旋转角度的数据,当然这样肯定是没有问题的,但是如果你拿到你的JY901模块用代码运行发现有大量的0数据出现,而且读出的数据压根跟陀螺仪旋转角度没有直接的关系。
那么我告诉你,你买的模块是错误的,仔细看下你的模块是不是每个边是不是4个引脚,看清模块上的芯片是不是MPU6050,用i2cdetect -y -1显示的硬件地址是不是0x68。
如果是我上面说的那三种情况,就不要瞎折腾了,你拿到的模块根本不是JY901,而是JY61,JY901使用MPU9250,而JY61用的是MPU6050,这里说下个人对这两模块认识到的区别:JY901可以修改I2C通讯地址,JY61不可以;JY901的I2C通讯地址初始化为0x50,JY61初始化地址是0x68。
一开始运行0数据特别少,后面0数据特别多,甚至都是0数据,是因为JY61模块默认是串口模式,用上位机选芯片型号JY61,既可以调成I2C工作模式,这样用网上关于树莓派 MPU6050的代码即可运行,数据稳定正常。
我就是正这个问题上纠结了一个多星期,严重的延后了我个人的工作计划,这个问题肯定绝大部分是我个人原因不够仔细导致的,但是还有一部分原因是因为某些店家,页面介绍,发给你的资料全部都是关于JY901,导致新手拿到传感器的时候先入为主,深深的记住了自己买的是JY901,当在树莓派上使用时出现了上面的这些问题,一直怀疑是自己代码的问题或者硬件电路的问题,一直谷歌百度解决各种莫名其妙的玄学问题。本人这一星期出现的问题有:1、运行 i2cdetect -y 1 有时候有显示硬件地址,有时候会消失,这也就是网上代码的IOError问题,就是因为I2c地址有时候找不到的原因导致的,解决办法就是用上位机选JY61芯片型号,改成I2C工作模式,就不会有I2C地址有时候会消失的这个问题了。2、上位机修改不了I2C地址, 归根揭底都是没弄对模块的问题,
同时还有一个注意的地方,因为树莓派在SDA和SCL引脚上有上拉电阻,所以在多I2C模块连接时不需要加上拉电阻。
========================================分割线===========================================
代码如下:
#!/usr/bin/python import smbus import math import types import ctypes import time import subprocess bus = smbus.SMBus(1) # or bus = smbus.SMBus(1) for Revision 2 boards addr1= 0x50 addr2 = 0x48 def calc_angle_value(x_angle,y_angle,z_angle): x = ((x_angle[1] << 8) | x_angle[0])/32768 * 180 y = ((y_angle[1] << 8) | y_angle[0])/32768 * 180 z = ((z_angle[1] << 8) | z_angle[0])/32768 * 180 if(x >= 180): x -= 360 if(y >= 180): y -= 360 if(z >= 180): z -= 360 return x,y,z def ReadData(address): x_angle = bus.read_i2c_block_data(address,0x3d,2) y_angle = bus.read_i2c_block_data(address,0x3e,2) z_angle = bus.read_i2c_block_data(address,0x3f,2) x,y,z = calc_angle_value(x_angle,y_angle,z_angle) return x,y,z while(True): try: right_x,right_y,right_z = ReadData(addr1) left_x,left_y,left_z = ReadData(addr2) print("Right Data: {:.4} {:.4} {:.4}".format(right_x,right_y,right_z)) print("Left Data: {:.4} {:.4} {:.4}".format(left_x,left_y,left_z)) except ValueError: continue