买了个mpu9250开始折腾,找了好多资料,看了好多文章啊,mpu9250的资料不是很多。
使用i2c链接到树莓派的scl , sda 接口vcc给3v引脚,gnd接树莓派gnd就ok。
开始折腾:
要操作mpu必须使用mpu的寄存器实现对参数的设定以及读取,取官方下载资料看了一下,在github上找了一个python代码,运行不了bug太多了,然后精简了一下。
终于能读出数据了,读出来的数据都是6个字节的,后来发现这哥们用python 读取mpu没有做字节合并,重写了一下,后来发现数据都是整数,不管我怎么旋转数字都是正的,看了网上的一片文章说寄存器度出来的是一个无符号整数。
后来想了半天,用手机下了一个陀螺仪app发现会出现负数的情况,只要向相对轴相反方向做运动就会出现负数,于是想了ctypes,强制转换成int这回数据看起来是有正数和负数了,不过在陀螺仪平放着的时候读书优点太大了都达到3000以上了,明显不是,貌似是这个数字需要转换一下才能使用,我找了N多的资料,终于找到有个人mpu6050的代码里,有一个固定的常亮,他使用acc_x乘以这个固定的常数,然后我测试了一下,确实可行,只要将加速计的值乘以16.4就可以得到正确的值!
陀螺仪读书要乘以13.我搜索了半天也没有找到为什么要乘以16.4 ,不找了,如果有人看到这篇文章知道为啥乘以16.4请留言或email给我[email protected]谢谢
使用如下代码需要安装smbus库,在树莓派直接 sudo apt-get install py-smbus就ok了
python代码如下:
import smbusimport sched, timeimport binasciifrom threading import Timer, Thread, Eventfrom struct import *import ctypesfrom math import acos import sched, timeimport binasciifrom struct import * i2c = smbus.SMBus(1)addr = 0x68t0 = 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 acceleratori2c.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 truedef 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();
时间: 2024-10-24 19:07:50