Exploring negative G ‘errors’ from the IMU

I’ve been asking myself various questions and checking the answers through test flights:

  • Do the negative G values show up in passive flights?  If the motors aren’t powered up, negative G values are not seen.
  • What about alpf?  With alpf set to 0 or 1 (460 or 184 Hz accelerometer low pass filter), I see the negative G ‘error’, but set to 2 (92Hz) or greater it doesn’t happen.
  • What are the values of the other accelerometer and gyro readings when this happens with alpf set to 0?  These are all believable: ax = -4214, ay = -696, az = -270, qx = 2922, gy = 870, gz = 1531 – no magic hex numbers in there suggesting problems.
  • What about sampling frequency?  With alpf set to 0, but with the sampling frequency dropped from 500Hz to 200Hz (SMPLRT_DIV 1 => 4), there are still negative G ‘errors’.
  • What happens if the range is set to ±4g instead of ±2g with alpf set to 0?  The problem remains – there are negative G ‘errors’.

To me, that suggests that somehow, the negative G readings are not an ‘error’ but are real.  They are filtered out by the lower low pass filter frequencies.  The MPU-9250 is working perfectly.  I’ll continue running with sampling frequency of 500Hz, and alpf of 0, and with the diagnostic / protective code disabled.

This then points the blame for head-butting the ceiling towards the ESCs – it’s as though they have latched at maximum power.  The PWM signals I’m sending range from 1ms to 2ms inclusive, and I’m now wondering whether sometimes, the PWM output does hit 2ms and latches the ESC; I’ve turned down the maximum to 1.999ms and see what happens – it’s a hunch based on a long lost memory of something I’d seen or read.

7 thoughts on “Exploring negative G ‘errors’ from the IMU

    • readList increments the register address per byte. I used to use it when I was reading the 14 sequential data registers directly; the problem with that was the code had to wait for the next sample to be available and couldn’t risk missing one; I swapped to the IMU I2C FIFO because it means the IMU puts every sample in the FIFO, so my code can do something else (like use other sensors), and then come back to the FIFO to get any sensor readings that had happened in the mean time.

      The fact I’m getting duff data in the FIFO strongly suggests it’s an IMU firmware problem rather than my code problem. I definitely don’t get any I2C errors reported as I empty the IMU FIFO byte by byte. I’ve posted on the Invensense Developers Forum, but no response yet 🙁

      • https://github.com/PiStuffing/Quadcopter/blob/master/Quadcopter.py#L446-L453

        You could use readList to read 12 bytes from the FIFO buffer.
        I was doing something like this in C and when I was reading all bytes from FIFO buffer I got a error that look similar to yours.
        But It worked when I read each batch individually (12 bytes).

        Maybe it is related to your problem.
        Maybe reading all FIFO or reading individual bytes can lead to errors.

        • Does sound related, but for me smbus.readList increments the I2C address per byte. This was how I could read all the registers directly by a single readList(14). But for the FIFO, readList(12) on address 0x74 returns one byte each from 0x74 – 0x7F, whereas I need 12 reads all on 0x74. That’s why I’m having to read it byte by byte.

          Do you know if there’s a way to make readList _NOT_ increment the I2C register address per byte. Or is that a function of the I2C slave depending on the register being read? Should I just try it and see?

        • Lol, actually I was reading all FIFO including incomplete data 😛 (leading to error).

          When you power up the motors below the hovering speed, It produces the same errors?

        • I owe you a beer! Just tried readList on the FIFO address(0x74), and it reads the 12 bytes from the same address – a passive flight is showing valid readings for gravity etc. That was completely unexpected! When I do a readList on the accelerometer address (0x3B), I got one byte each from 0x3B to 0x48!


          Even better, it’s a fine day tomorrow, so I can test it outside!

Leave a Reply

Your email address will not be published. Required fields are marked *