zoukankan      html  css  js  c++  java
  • MPU9250九轴陀螺仪--读接口数据

    1.使用i2c链接到树莓派的scl , sda 接口vcc给3v引脚,gnd接树莓派gnd就ok。  

    2.要操作mpu必须使用mpu的寄存器实现对参数的设定以及读取,取官方下载资料看了一下,在github上找了一个python代码,运行不了bug太多了,然后精简了一下。终于能读出数据了,读出来的数据都是6个字节的,后来发现这哥们用python 读取mpu没有做字节合并,重写了一下,后来发现数据都是整数,不管我怎么旋转数字都是正的,看了网上的一片文章说寄存器度出来的是一个无符号整数。后来想了半天,用手机下了一个陀螺仪app发现会出现负数的情况,只要向相对轴相反方向做运动就会出现负数,于是想了ctypes,强制转换成int这回数据看起来是有正数和负数了,不过在陀螺仪平放着的时候读书优点太大了都达到3000以上了,明显不是,貌似是这个数字需要转换一下才能使用,我找了N多的资料,终于找到有个人mpu6050的代码里,有一个固定的常亮,他使用acc_x乘以这个固定的常数,然后我测试了一下,确实可行,只要将加速计的值乘以16.4就可以得到正确的值!

     陀螺仪读数要乘以13.我搜索了半天也没有找到为什么要乘以16.4 ,不找了,如果有人看到这篇文章知道为啥乘以16.4请留言,谢谢

    使用如下代码需要安装smbus库,在树莓派直接 sudo apt-get install py-smbus就ok了

    3.python代码如下:

    import smbus
    import sched, time
    import binascii
    from threading import Timer, Thread, Event
    from struct import *
    import ctypes
    from math import acos
    
    import sched, time
    import binascii
    from struct import *
    
    i2c = smbus.SMBus(1)
    addr = 0x68
    t0 = time.time()
    
    
    # ====== initial zone ======
    try:
        device_id = i2c.read_byte_data(addr, 0x75)
        print ("Device ID:" + str(hex(device_id)))
        print ("MPU9250 I2C Connected.")
        print("")
    except:
        print ("Connect failed")
        print ("")
    i2c.write_byte_data(0x68, 0x6a, 0x00)
    time.sleep(0.05);
    i2c.write_byte_data(0x68, 0x37, 0x02)
    i2c.write_byte_data(0x0c, 0x0a, 0x16)
    
    # set frequence for accelerator
    i2c.write_byte_data(0x68, 29, 9)
    
    
    # enable fifo and dmp
    # i2c.write_byte_data(0x68 , 106 , 32+64);
    
    # ====== intial done ======
    
    
    
    def mpu9250_data_get_and_write():
        # global t_a_g
    
        # keep AKM pointer on continue measuring
        i2c.write_byte_data(0x0c, 0x0a, 0x16)
        # get MPU9250 smbus block data
        # xyz_g_offset = i2c.read_i2c_block_data(addr, 0x13, 6)
        xyz_a_out = i2c.read_i2c_block_data(addr, 0x3B, 6)
        print("xyz_a_out" + str(list2word(xyz_a_out, calc_accelerator_value)))
        # print("xyz_a_out_org#:"+str(xyz_a_out))
    
        xyz_g_out = i2c.read_i2c_block_data(addr, 0x43, 6)
        print("xyz_g_out" + str(list2word(xyz_g_out, calc_gyro_value)))
        # xyz_a_offset = i2c.read_i2c_block_data(addr, 0x77, 6)
    
        # get AK8963 smb#us data (by pass-through way)
        xyz_mag = i2c.read_i2c_block_data(0x0c, 0x03, 6)
        # print("xyz_mag"+str(list2word(xyz_mag)))
        xyz_mag_adj = i2c.read_i2c_block_data(0x0c, 0x10, 3)
    
    
    def list2word(data_list=[], callback=''):
        data = data_list[:]
        if not len(data):
            return [];
    
        result = []
        for i in range(3):
            high_byte = data.pop(0)
            low_byte = data.pop(0)
            result.append(callback(float(ctypes.c_int16(((high_byte << 8) | low_byte)).value)))
    
        return result
    
    
    def calc_accelerator_value(value):
        return round(value / 16.4)
    
    
    def calc_gyro_value(value):
        return round(value / 131)
    
    
    def clear_i2c_and_close_file():
        i2c.write_byte_data(addr, 0x6A, 0x07)
    
    
    # solution 1: while true
    def while_true_method():
        # max_count = raw_input("Enter how many count you want.")
        max_count = 100;
        if max_count < 1: max_count = 1000
        print ("Data Counts: " + str(max_count))
    
        max_count = int(max_count)
        count = 1
    
        print ("")
        print ("MPU9250 9axis DATA Recording...")
        while True:
            # if count <= max_count:
            mpu9250_data_get_and_write()
            count += 1
            time.sleep(0.5)
            # else:
            pass
        # break;
    
    
    while_true_method();
    

      

    附:寄存器地址

    #define SMPLRT_DIV                 0X19 //陀螺仪采样率典型值为0X07 1000/(1+7)=125HZ
    
    #define CONFIG                         0X1A //低通滤波器  典型值0x06 5hz
    
    #define GYRO_CONFIG                0X1B //陀螺仪测量范围 0X18 正负2000度
    
    #define ACCEL_CONFIG            0X1C //加速度计测量范围 0X18 正负16g
    
    #define ACCEL_CONFIG2           0X1D //加速度计低通滤波器 0x06 5hz
    
    #define PWR_MGMT_1                  0X6B//电源管理1 典型值为0x00
    
    #define PWR_MGMT_2                 0X6C //电源管理2 典型值为0X00
    
     
    
    #define WHO_AM_I                    0X75 //器件ID MPU9250默认ID为0X71
    
    #define USER_CTRL                   0X6A //用户配置当为0X10时使用SPI模式
    
     
    
    #define MPU9250_CS        PDout(3) //MPU9250片选信号
    
    #define I2C_ADDR                    0X68  //i2c的地址   
    
    #define ACCEL_XOUT_H            0X3B  //加速度计输出数据
    
    #define ACCEL_XOUT_L            0X3C
    
    #define ACCEL_YOUT_H            0X3D
    
    #define ACCEL_YOUT_L            0X3E
    
    #define ACCEL_ZOUT_H            0X3F
    
    #define ACCEL_ZOUT_L            0X40
    
     
    
    #define TEMP_OUT_H               0X41  //温度计输出数据
    
    #define TEMP_OUT_L               0X42
    
     
    
    #define GYRO_XOUT_H              0X43  //陀螺仪输出数据
    
    #define GYRO_XOUT_L              0X44
    
    #define GYRO_YOUT_H              0X45
    
    #define GYRO_YOUT_L              0X46
    
    #define GYRO_ZOUT_H              0X47
    
    #define GYRO_ZOUT_L                 0X48
    
    当然以上的都是把数据手册的地址进行定义 
    

      

  • 相关阅读:
    借了个屏幕来用
    生命开始的地方
    看了STLPort的安装方法,晕了
    程序员必备的10大健康装备!
    《代码整洁之道》读书笔记
    Mockito使用
    学习Emacs的理由
    shell 脚本编程的10 个最佳实践
    MongoDB入门
    用Orgmode实践《奇特的一生》
  • 原文地址:https://www.cnblogs.com/onekey/p/10553711.html
Copyright © 2011-2022 走看看