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 當然以上的都是把數據手冊的地址進行定義