0

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
    mpu.enableFIFO(True)


    # Test connection:
    if mpu.testConnection():
        print("Connection working.")
    else:
        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')
        #print("----1----")
        # Main loop
        while True:
            mpudata_a, mpudata_g, mpudata_temp = mpu.getFIFOData()
            #print("----2----")
            data = mpudata_a + mpudata_g + mpudata_temp
            # print(data)
            data_imu.write(str(data).replace("[", "").replace("]", "") + "\n")



if __name__ == "__main__":

    led = Led()
    led.setColor('Green')

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

    with open(errfile, 'w', 1) as efile:
        try:
            main()
        except KeyboardInterrupt:
            led.setColor('Yellow')
        except Exception as e:
            led.setColor('Red')
            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:
                continue
            # 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()
                break

            else:
                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.resetFIFO()
            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
  • 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 Oct 31 '19 at 9:04
  • yes,it runs on raspi – 段永旭 Oct 31 '19 at 9:16
  • @段永旭, 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 Oct 31 '19 at 15:17
  • 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 Oct 31 '19 at 15:29
  • @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 – 段永旭 Nov 2 '19 at 8:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.