mpu9250 buffer overflow notes

Viewed 20 times

I’m now working with mpu9250 for my master thesis, but I’m quite new to hardware device. My goal is to collect the data at the sample rate and postprocess these data via allan deviation. So I just want to get the data from 512 bytes fifo, but when I’m trying to read out the data, it always overflows which annoying me a lot.

I know the method is to set the reading speed faster than the fifo writing speed, so I remove the time sleep in my loop, but it seems overflows sooner than before. I’m a little bit confused, because the reading speed depends on the writing speed.

here are my code:

#!/usr/bin/env python3

import os
import time
import sys
import struct
import csv
from datetime import datetime
from mpu9250_FIFO import MPU9250
from navio.leds import Led

def main():

    # Initialize MPU9250
    mpu = MPU9250()
    # Set maximum SPI bus speed in Hz, default=10000000
    # MPU8250 features:
    # -- 1MHz SPI serial interface for communicating with all registers
    # -- 20MHz SPI serial interface for reading sensor and interrupt registers
    mpu.bus_open(max_speed_hz=10000000)  # Hz

    # Initialize sensors
    # samle_rate unit is Hz
    # low_pass_filter_gt is the low pass filter for gyroscope and temperature sensors. possible values are:
    #           Gyroscope Sensor              |           Temperature Sensor          |        Bits
    #               250 Hz                    |                4000 Hz                |        0x00   NO_DLPF
    #               184 Hz                    |                 188 Hz                |        0x01
    #                92 Hz                    |                  98 Hz                |        0x02
    #                41 Hz                    |                  42 Hz                |        0x03
    #                20 Hz                    |                  20 Hz                |        0x04
    #                10 Hz                    |                  10 Hz                |        0x05
    #                 5 Hz                    |                   5 Hz                |        0x06
    #              3600 Hz                    |                4000 Hz                |        0x07   NO_DLPF
    # low_pass_filter_accel is the low pass filter for accelerometer, possible values are:
    #           Accelerometer Sensor          |                 Bits
    #             218.1 Hz                    |                 0x00
    #             218.1 Hz                    |                 0x01
    #                99 Hz                    |                 0x02
    #              44.8 Hz                    |                 0x03
    #              21.2 Hz                    |                 0x04
    #              10.2 Hz                    |                 0x05
    #              5.05 Hz                    |                 0x06
    #               420 Hz                    |                 0x07       NO_DLPF
    sampleRate = 50
    sampleRateDiv = int(1000 / sampleRate - 1)
    mpu.initialize(sample_rate_div=sampleRateDiv, low_pass_filter_gt=0x01, low_pass_filter_a=0x01)

    # Set accelerometer scale, default is 16G
    # BITS_FS_2G = 0x00
    # BITS_FS_4G = 0x08
    # BITS_FS_8G = 0x10
    # BITS_FS_16G = 0x18
    mpu.set_acc_scale(0x08)       # +/-4G

    # Set gyroscope scale, default is 2000DPS
    # BITS_FS_250DPS = 0x00
    # BITS_FS_500DPS = 0x08
    # BITS_FS_1000DPS = 0x10
    # BITS_FS_2000DPS = 0x18
    mpu.set_gyro_scale(0x08)      # +/-500dps

    # Enable FIFO to collect data

    # Test connection:
    if mpu.testConnection():
        print("Connection working.")
        print("Connection to one of the sensors is faulty.")

    # find new filename
    # fileending = 1
    # while True:
    #     if os.path.isfile('/home/pi/Duan/Python/meas_data/mpufile_{}_IMU.txt'.format(fileending)) is True:
    #         fileending += 1
    #     else:
    #         break
    # open('', '', 1) enables line buffering
    # with open('/home/pi/Duan/Python/meas_data/mpufile_{}_IMU.txt'.format(fileending), 'w', 1) as dat_imu:

    now = datetime.now().strftime('%d-%m-%Y_%H:%M:%S')
    fname = '/home/pi/Duan/Python/meas_data/mpu9250_data_' + now + r'.txt'

    with open(fname, 'w', 1) as data_imu:
        # write headers to file
        data_imu.write('Sample Rate: %d Hz\n' % sampleRate)
        data_imu.write('mpu_accel_1, mpu_accel_2, mpu_accel_3, mpu_gyro_1, mpu_gyro_2, mpu_gyro_3, temp\n')
        # Main loop
        while True:
            mpudata_a, mpudata_g, mpudata_temp = mpu.getFIFOData()
            data = mpudata_a + mpudata_g + mpudata_temp
            # print(data)
            data_imu.write(str(data).replace("[", "").replace("]", "") + "\n")

if __name__ == "__main__":

    led = Led()

    errfile = "/home/pi/Duan/Python/errorfile.txt"

    with open(errfile, 'w', 1) as efile:
        except KeyboardInterrupt:
        except Exception as e:
            efile.write("Some error occured:\n{}".format(e))
    def getFIFOData(self):
        while True:
            mpu_int_status = self.getIntStatus()
            INT_FIFO_OFLOW_BIT = 0x10  # the 4th bit is set to 1 when FIFO buffer is overflowed    
            fifoCount = self.getFIFOCount()
             #print("fifoCount:%d" % fifoCount)

            if fifoCount < 14:
            # check for overflow (this shouldn't happen)
            elif (mpu_int_status & 0x10 == 0x10) or fifoCount>=512:
                print("fifoCount is: %d" % fifoCount)
                print("FIFO is overflow!")
                # print("Reset FIFO...")
               # self.resetFIFO()

                packet_count = int(fifoCount/14)
            #    print("packet count:%d" % packet_count)
                for i in range(0, packet_count):
                    response = self.ReadRegs(self.__MPUREG_FIFO_R_W, 14)
                    # print(response)
                    # Get Accelerometer values
                    for i in range(0, 3):
                        data = self.byte_to_float(response[i * 2:i * 2 + 2])
                        self.accelerometer_data[i] = self.G_SI * data / self.acc_divider
                   # print(self.accelerometer_data)
                    # Get temperature
                    i = 3
                    temp = self.byte_to_float(response[i * 2:i * 2 + 2])
                    self.temperature[i - 3] = (temp / 333.87) + 21.0
                    # print(self.temperature)
                    # Get gyroscope values
                    for i in range(4, 7):
                        data = self.byte_to_float(response[i * 2:i * 2 + 2])
                        self.gyroscope_data[i - 4] = (self.PI / 180) * data / self.gyro_divider
                   # print(self.gyroscope_data)

                return self.accelerometer_data, self.gyroscope_data, self.temperature

    def getIntStatus(self):
        return self.ReadReg(self.__MPUREG_INT_STATUS)

    def getFIFOCount(self):
        response = self.ReadRegs(self.__MPUREG_FIFO_COUNTH, 2)
        fifoCount = self.byte_to_float(response)
        return fifoCount

    def resetFIFO(self):
        self.WriteReg(self.__MPUREG_USER_CTRL, 0x00)
        self.WriteReg(self.__MPUREG_USER_CTRL, 0x04)    # reset fifo mode
        self.WriteReg(self.__MPUREG_USER_CTRL, 0x40)    # FIFO_EN
        print('fifo is reset!')

    def enableFIFO(self, flag):
        self.WriteReg(self.__MPUREG_FIFO_EN, 0x00)
        if flag:
            self.WriteReg(self.__MPUREG_FIFO_EN, 0xF8)
        print('fifo is enabled!')`
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/SO7tN.png

migrated from arduino.stackexchange.com yesterday

This question came from our site for developers of open-source hardware and software that is compatible with Arduino.

  • Are you sure that this code runs on an Arduino UNO. I’m not an Arduino guru, but I don’t know any possibility to run python code on a Arduino UNO. And if you have a python question it would be better to ask on the python channel. From your code I would expect it runs on a raspberry pi. So the Raspi Channel would be a better choice to ask on. – Peter Paul Kiefer 2 days ago
  • yes,it runs on raspi – 段永旭 2 days ago
  • @段永旭, Ah let me see. If you don’t sleep, then you might be reading too fast. MPU9250 gyro max output data rate is only 8kHz. So it can’t follow and becomes crazy, buffer explodes, … 🙂 BTW, SPI 10MHz is too fast for testing. Try 1MHz and MPU9250 might like it. – tlfong01 yesterday   
  • If you are attempting to read as fast as possible you should not be using Python. Are you sure Python can keep up with the data rate? – joan yesterday
  • @tlfong01, I’ve tried to set it to 1MHz, but it still overflows. And I check the time cost of my main loop, every time the reading is stucked due to some unknown reasons, and the time cost rises to 1or 2 seconds, and the fifo count is then over 512 and causes overflow. It’s quite annoying T_T – 段永旭 1 hour ago
  • @段永旭, Many thanks for reporting result on my suggestion. It seems obvious that the reading function is making all the trouble. But I think this problem seems not that difficult to solve. First thing first, my troubleshooting trick is to zoom the big picture into the problem area. I must confess I have not even skimmed through your frighteningly long code. But please confirm one thing: (1) Is it possible to REMOVE everything related to MPU9250? If yes, then write a short test WITHOUT this statement: “from mpu9250_FIFO import MPU9250”. I know I might be asking too much, but / continure, … – tlfong01 23 mins ago   
  • Or (1) Just input the “from mpu9250_FIFO import MPU9250”, but do not feed real realtime input from MMPU9250. Instead DIY one, yes, just one fake test byte data into the buffer, and profile / time for one or repeat 10 times the time cost. So what I am suggest is 抽絲剝繭 to the very bottom layer, … Ah sorry, I need to go to meet a friend for dinner. So see you late this evening or tomorrow, or after weekend. Good luck and cheers. – tlfong01 16 mins ago   
  • Ah, one more thing before I go: Similarly, when later using real data, there is no point mixing both gyro and accelero data. Remove either one to focus just one type (gyro or accelero) of data. If you find the problem cause of gyro, of course you know accelero have the same cause. Similarly, when DIYing fake data, just use a simple integer 123 etc, not even floating point (OK, if you must use float point, then use int(float(123)), hopefully 水落 and 石出. Bye. – tlfong01 9 mins ago    Delete

Categories: Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: