1

我的 Pi 和 MPU6050 在性能(扫描速度)方面存在问题。代码的任务是尽可能快地以准确的间隔记录来自 MPU 的数据。

为了达到高扫描速度,我只记录原始寄存器值并稍后转换所有内容。此外,我将 I2C 波特率从 Raspberry 更改为 400kHz。

目前,该代码提供了最大 135Hz 的原始数据记录频率。

你能帮我获得更高的采样率和更好的准确间隔吗?其中更重要的一点是确切的区间。

#!/usr/bin/python

import smbus
from datetime import datetime, timedelta
import time

bus = smbus.SMBus(1) # Bus for Revision 2 boards
address = 0x68       # Sensor i2c address
# Power management registers
power_mgmt_1 = 0x6b
power_mgmt_2 = 0x6c

# Accelerometer
# Data register
ACCEL_XOUT0 = 0x3B
ACCEL_XOUT1 = 0x3C
ACCEL_YOUT0 = 0x3D
ACCEL_YOUT1 = 0x3E
ACCEL_ZOUT0 = 0x3F
ACCEL_ZOUT1 = 0x40
# Range
ACCEL_CONFIG_REGISTER = 0x1C
ACCEL_2G = 0x00
ACCEL_4G = 0x08
ACCEL_8G = 0x10
ACCEL_16G = 0x18
# Scale Modifiers
ACCEL_SCALE_MODIFIER_2G = 16384.0
ACCEL_SCALE_MODIFIER_4G = 8192.0
ACCEL_SCALE_MODIFIER_8G = 4096.0
ACCEL_SCALE_MODIFIER_16G = 2048.0

# Gyroscope
# Data register
GYRO_XOUT0 = 0x43
GYRO_XOUT1 = 0x44
GYRO_YOUT0 = 0x45
GYRO_YOUT1 = 0x46
GYRO_ZOUT0 = 0x47
GYRO_ZOUT1 = 0x48
# Range
GYRO_CONFIG_REGISTER = 0x1B
GYRO_250DEG = 0x00
GYRO_500DEG = 0x08
GYRO_1000DEG = 0x10
GYRO_2000DEG = 0x18
# Scale Modifiers
GYRO_SCALE_MODIFIER_250DEG = 131.0
GYRO_SCALE_MODIFIER_500DEG = 65.5
GYRO_SCALE_MODIFIER_1000DEG = 32.8
GYRO_SCALE_MODIFIER_2000DEG = 16.4

# Temperature
# Data register
TEMP_OUT0 = 0x41
TEMP_OUT1 = 0x42

# -- Functions --
def read_register(adr):
    return [bus.read_byte_data(address, adr),bus.read_byte_data(address, adr+1)]

def convert_register(raw_val):
    convert_val = (raw_val[0] << 8) + raw_val[1]
    if (convert_val >= 0x8000):
        return -((65535 - convert_val) + 1)
    else:
        return convert_val

def convert_temp(raw_val):
    raw_temp = convert_register(raw_val)
    temp = (raw_temp / 340) + 36.53
    return temp

def set_range_get_scale(register, range):
    bus.write_byte_data(address, register, range) # set new range
    time.sleep(0.5)
    current_range = bus.read_byte_data(address, register) # read current set range
    if register == ACCEL_CONFIG_REGISTER:
        if current_range == ACCEL_2G:
            return ACCEL_SCALE_MODIFIER_2G
        elif current_range == ACCEL_4G:
            return ACCEL_SCALE_MODIFIER_4G
        elif current_range == ACCEL_8G:
            return ACCEL_SCALE_MODIFIER_8G
        else: #current_range == ACCEL_16G
            return ACCEL_SCALE_MODIFIER_16G
    if register == GYRO_CONFIG_REGISTER:
        if current_range == GYRO_250DEG:
            return GYRO_SCALE_MODIFIER_250DEG
        elif current_range == GYRO_500DEG:
            return GYRO_SCALE_MODIFIER_500DEG
        elif current_range == GYRO_1000DEG:
            return GYRO_SCALE_MODIFIER_1000DEG
        else: #current_range == GYRO_2000DEG:
            return GYRO_SCALE_MODIFIER_2000DEG  

# -- INIT -- 
print('| Loading...')
bus.write_byte_data(address, power_mgmt_1, 0)
acc_scale = set_range_get_scale(ACCEL_CONFIG_REGISTER,ACCEL_2G)
gyro_scale = set_range_get_scale(GYRO_CONFIG_REGISTER,GYRO_250DEG)

# -- MAIN --
# query of parameters
freqInput = raw_input("Measuring frequency[Hz]: ")
durationInput=[0,0]
tmp = raw_input("Measuring duration[m]: ")
durationInput[0] = int(tmp)
tmp = raw_input("Measuring duration[s]: ")
durationInput[1] = int(tmp)

# Calculation of frequency
milsec = float(1000.0/float(freqInput))
if milsec==1000:
   freq=timedelta(0,1)
elif milsec%1==0:
   freq=timedelta(0,0,0,int(milsec))
else:
   freq=timedelta(0,0,(milsec-int(milsec))*1000,int(milsec))

# Set measurement duration
duration=timedelta(0,durationInput[1],0,0,durationInput[0]) # days, seconds, microseconds, milliseconds, minutes

# List for data record
time=[]
temp=[]
acc=[]
gyro=[]

# Loop
print('| Start Logging')
tend = datetime.now()+duration
t = datetime.now()
while datetime.now().time() < tend.time(): # interrupts if the total measuring time is passed
    t = datetime.now()
    time.append(datetime.now())
    temp.append(read_register(0x41))
    acc.append([read_register(0x3B),read_register(0x3D),read_register(0x3F)])
    gyro.append([read_register(0x43),read_register(0x45),read_register(0x47)])
    while datetime.now() < t+freq:  # interrupts if it time for the next record
        pass
tend = datetime.now()
print('| Finish Logging')

# Test Records
print('| Start Test Record')
if len(time) == len(temp) and len(time) == len(acc) and len(time) == len(gyro):
    print('| Finish Record Test; Result = OK')
else:
    print('| Finish Record Test; Result = FALSE')
    SystemExit(0)

# Convert Raw Data
print('| Start Raw Data Converting')
for i in range(len(time)):
    temp[i] = convert_temp(temp[i])
    for j in range(0,3):
        acc[i][j] = convert_register(acc[i][j]) / acc_scale
        gyro[i][j] = convert_register(gyro[i][j]) / gyro_scale
print('| Finish Raw Data Converting')

# write file
print ("| Start file writing")
name = datetime.now()
file = name.strftime('%Y%m%d_%H%M%S')
datei_out = open(file+".csv","w")
for i in range(len(time)):
    datei_out.write(str(i+1)+";") # number of measurment
    datei_out.write(str(time[i].time())+";") # time stamp of measurment
    datei_out.write(str(time[i]-time[0])+";") # time delta since measurement start
    datei_out.write(str(acc[i][0])+";") # Accelerometer X
    datei_out.write(str(acc[i][1])+";") # Accelerometer X
    datei_out.write(str(acc[i][2])+";") # Accelerometer X
    datei_out.write(str(gyro[i][0])+";") # Gyroscope X
    datei_out.write(str(gyro[i][1])+";") # Gyroscope X
    datei_out.write(str(gyro[i][2])+"\n") # Gyroscope X
datei_out.close()
print ("| Finish file writing")

# end
print ("| Completely Finish")
4

0 回答 0