Black Lives Matter - Action and Equality. ... Adafruit is open and shipping.
0

MCP2221 & MPU9250 SAMPLE SPEED
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

MCP2221 & MPU9250 SAMPLE SPEED

by IvoO on Mon Jun 29, 2020 5:58 am

Hi

I used a MCP2221 plugged into usb data port on my windows 10 machine and connected my MPU9250 via i2c to read out the values.
But unfortunately I only get 12 measurements per second. So the sample rate is way to slow.
I know that the MPU 9250 can handle a much higher sample rate. I just can't get it working in combination with the MCP2221A

Code: Select all | TOGGLE FULL SIZE
import time
import board
import busio
import datetime
from adafruit_bus_device.i2c_device import I2CDevice
from adafruit_register.i2c_struct import UnaryStruct

# MPU6050 Registers
MPU6050_ADDR = 0x68
PWR_MGMT_1   = 0x6B
SMPLRT_DIV   = 0x19
CONFIG       = 0x1A
GYRO_CONFIG  = 0x1B
ACCEL_CONFIG = 0x1C
INT_ENABLE   = 0x38
ACCEL_XOUT_H = 0x3B
ACCEL_YOUT_H = 0x3D
ACCEL_ZOUT_H = 0x3F
TEMP_OUT_H   = 0x41
GYRO_XOUT_H  = 0x43
GYRO_YOUT_H  = 0x45
GYRO_ZOUT_H  = 0x47

#AK8963 registers
AK8963_ADDR   = 0x0C
AK8963_ST1    = 0x02
HXH          = 0x04
HYH          = 0x06
HZH          = 0x08
AK8963_ST2   = 0x09
AK8963_CNTL  = 0x0A
mag_sens = 4900.0 # magnetometer sensitivity: 4800 uT

bus = busio.I2C(board.SCL, board.SDA)
device = I2CDevice(bus, 0x68)

class DeviceControl:  # pylint: disable-msg=too-few-public-methods
    def __init__(self, i2c):
        self.i2c_device = i2c  # self.i2c_device required by UnaryStruct class

    register_SMPLRT_DIV = UnaryStruct(SMPLRT_DIV, "<B")  # 8-bit number
    register_PWR_MGMT_1 = UnaryStruct(PWR_MGMT_1, "<B")  # 8-bit number
    register_CONFIG = UnaryStruct(CONFIG, "<B")  # 8-bit number
    register_INT_ENABLE = UnaryStruct(INT_ENABLE, "<B")  # 8-bit number
   

def read_from_reg():
    result = bytearray(1)
    bus.writeto(0x68, bytes([INT_ENABLE]))
    bus.readfrom_into(0x68, result)
    return result

def MPU6050_start():

    registers = DeviceControl(device)

    # alter sample rate (stability)
    registers.register_SMPLRT_DIV = 7 # sample rate = 8 kHz/(1+samp_rate_div)

    #bus.write_byte_data(MPU6050_ADDR, SMPLRT_DIV, samp_rate_div)
   

    # reset all sensors
    registers.register_PWR_MGMT_1 = 0x00
   
    # power management and crystal settings
    registers.register_PWR_MGMT_1 = 0x01

   #Write to Configuration register
    registers.register_CONFIG = 0x00
   
   #Write to Gyro configuration register
    #bus.write_byte_data(Device_Address, GYRO_CONFIG, 24)


    #Write to Accel configuration register
    #bus.write_byte_data(Device_Address, ACCEL_CONFIG, 0x00)
    #bus.write_byte_data(Device_Address, ACCEL_CONFIG, range_value)
   
   #Write to interrupt enable register
    registers.register_INT_ENABLE = 1


    print(read_from_reg())





    #Write to Gyro configuration register
    gyro_config_sel = [0b00000,0b010000,0b10000,0b11000] # byte registers
    gyro_config_vals = [250.0,500.0,1000.0,2000.0] # degrees/sec
    gyro_indx = 0
    #bus.write_byte_data(MPU6050_ADDR, GYRO_CONFIG, int(gyro_config_sel[gyro_indx]))
    time.sleep(0.1)
    #Write to Accel configuration register
    accel_config_sel = [0b00000,0b01000,0b10000,0b11000] # byte registers
    accel_config_vals = [2.0,4.0,8.0,16.0] # g (g = 9.81 m/s^2)
    accel_indx = 0                           
    #bus.write_byte_data(MPU6050_ADDR, ACCEL_CONFIG, int(accel_config_sel[accel_indx]))
    #time.sleep(0.1)
    # interrupt register (related to overflow of data [FIFO])
    #bus.write_byte_data(MPU6050_ADDR, INT_ENABLE, 1)
    #time.sleep(0.1)
    return gyro_config_vals[gyro_indx],accel_config_vals[accel_indx]
   
def read_raw_bits(register):
    # read accel and gyro values
    result = bytearray(1)
    result2 = bytearray(1)

    bus.writeto(0x68, bytes([register]))
    bus.readfrom_into(0x68, result)

    bus.writeto(0x68, bytes([register + 1]))
    bus.readfrom_into(0x68, result2)

    high = int.from_bytes(result, byteorder='big')
    low = int.from_bytes(result2, byteorder='big')

    # combine higha and low for unsigned bit value
    value = ((high << 8) | low)
   
    # convert to +- value
    if(value > 32768):
        value -= 65536
    return value

def mpu6050_conv():
    # raw acceleration bits
    acc_x = read_raw_bits(ACCEL_XOUT_H)
    acc_y = read_raw_bits(ACCEL_YOUT_H)
    acc_z = read_raw_bits(ACCEL_ZOUT_H)

    # raw temp bits
    #t_val = read_raw_bits(TEMP_OUT_H) # uncomment to read temp
   
    # raw gyroscope bits
    gyro_x = read_raw_bits(GYRO_XOUT_H)
    gyro_y = read_raw_bits(GYRO_YOUT_H)
    gyro_z = read_raw_bits(GYRO_ZOUT_H)

    #convert to acceleration in g and gyro dps
    a_x = (acc_x/(2.0**15.0))*accel_sens
    a_y = (acc_y/(2.0**15.0))*accel_sens
    a_z = (acc_z/(2.0**15.0))*accel_sens

    w_x = (gyro_x/(2.0**15.0))*gyro_sens
    w_y = (gyro_y/(2.0**15.0))*gyro_sens
    w_z = (gyro_z/(2.0**15.0))*gyro_sens

    #temp = ((t_val)/333.87)+21.0 # uncomment and add below in return
    return a_x,a_y,a_z,w_x,w_y,w_z #,temp

def AK8963_start():
    #bus.writeto(AK8963_ADDR,AK8963_CNTL,0x00)
    time.sleep(0.1)
    AK8963_bit_res = 0b0001 # 0b0001 = 16-bit
    AK8963_samp_rate = 0b0110 # 0b0010 = 8 Hz, 0b0110 = 100 Hz
    AK8963_mode = (AK8963_bit_res <<4)+AK8963_samp_rate # bit conversion
    #bus.write_byte_data(AK8963_ADDR,AK8963_CNTL,AK8963_mode)
    time.sleep(0.1)
   
def AK8963_reader(register):
    # read magnetometer values

    result = bytearray(1)
    device.write(bytes([register - 1]))
    device.readinto(result)

    result2 = bytearray(1)
    device.write(bytes([register]))
    device.readinto(result2)

    high = result
    low = result2


    #low = bus.read_byte_data(AK8963_ADDR, register-1)
    #high = bus.read_byte_data(AK8963_ADDR, register)
    # combine higha and low for unsigned bit value
    value = ((high << 8) | low)
    # convert to +- value
    if(value > 32768):
        value -= 65536
    return value

def AK8963_conv():
    # raw magnetometer bits

    loop_count = 0
    while 1:
        mag_x = AK8963_reader(HXH)
        mag_y = AK8963_reader(HYH)
        mag_z = AK8963_reader(HZH)

        # the next line is needed for AK8963
        #if bin(bus.read_byte_data(AK8963_ADDR,AK8963_ST2))=='0b10000':
        #    break
        loop_count+=1
       
    #convert to acceleration in g and gyro dps
    m_x = (mag_x/(2.0**15.0))*mag_sens
    m_y = (mag_y/(2.0**15.0))*mag_sens
    m_z = (mag_z/(2.0**15.0))*mag_sens

    return m_x,m_y,m_z
   
MEASUREMENT_DATA = []

# start I2C driver
gyro_sens,accel_sens = MPU6050_start() # instantiate gyro/accel
#AK8963_start() # instantiate magnetometer


for i in range(100):

    t_start_run = time.time()
   
    Line = []
    Line.append(str(mpu6050_conv()))
    Line.append(",")
    Line.append(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"))
    Line.append("\n")
   
    MEASUREMENT_DATA.append(''.join(Line))
   
    t_end_run = time.time()
    t_delta_run = t_end_run - t_start_run
       
    if(t_delta_run < 0.01):
        time.sleep(0.01 - t_delta_run)


print(''.join(MEASUREMENT_DATA))

IvoO
 
Posts: 1
Joined: Sun Jun 28, 2020 3:47 am

Please be positive and constructive with your questions and comments.