树莓派 连接 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

 

 

posted @ 2019-04-08 21:21  浮躁世界中的一股清流  阅读(3362)  评论(0编辑  收藏  举报