I'm experimenting with an MPU6050 six-axis accelerometer/gyro reading data with a Raspberry Pi via I2C. The six-axis response makes sense in general as I rotate it by hand, rotating moves the gravity vector correctly per the accelerometer channels, and short rotations around each axis generate reasonable-looking gyroscope values.
But when I set it down on something that should isolate it from vibrations and just take data for a long time, I see strange non-statistical noise in some channels.
I wrote a short script (shown below) that samples all six channels for 400 iterations, then increments the low pass filter (seven levels from
0x06) and then increments the gain for both accel and gyro (four levels;
0x00, 0x08, 0x10, 0x18). So that's 28 tests with 400 samples each. The data rate is about 55 to 60 measurements of all six axes per second. The characteristic frequency for each setting of the digital low-pass filter from the register map pdf is:
and the data sheet pdf.
Below I show the data which ranges from -/+ 32,767. The only thing I've changed is to subtract the mean of the 400 measurements at each setting so just the noise is displayed.
As the seven low-pass filter settings increase, the frequency decreases and the noise decreases as expected. However, there are these sudden spikes of +/- 200 to 300 ADC counts. They are not exactly 256, but in that ballpark with seems slightly suspicious.
I also show the raw data and standard deviations per test in the second plot.
Question: Does this kind of behavior - this non-statistical, spiky noise - look familliar to anyone? I'm waiting on a second gyro to compare, but that will take many days, and I'd like to see if there is anything I can do in the mean time. Each of the six channels has a very different behavior wrt noise. Inside the IC there are six separate MEMs devices each connected to its own dedicated ADC.
Script for the Raspberry Pi to read the module via I2C:
#!/usr/bin/python import web import smbus import math import time urls = ('/', 'index') pwrmgmt_1 = 0x6b pwrmgmt_2 = 0x6c dlpf_set_addr = 0x1a gyro_scale_addr = 0x1b accel_scale_addr = 0x1c scales = 0x00, 0x08, 0x10, 0x18 dlpfs = 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 pairs = ((0x3b, 0x3c), (0x3d, 0x3e), (0x3f, 0x40), (0x43, 0x44), (0x45, 0x46), (0x47, 0x48)) setups =  for scale in scales: for dlpf in dlpfs: setups.append((scale, dlpf)) nsetups = len(setups) bus = smbus.SMBus(1) address = 0x68 ic = 0 isetup = 0 nsamples = 400 def read_six(): vals =  for ahi, alo in pairs: high = bus.read_byte_data(address, ahi) low = bus.read_byte_data(address, alo) val = (high << 8) + low if val >= 0x8000: val = -((65535 - val) + 1) vals.append(val) return vals class index: def GET(self): global ic, nsamples global isetup, nsetups, setups global accel_scale_addr, gyro_scale_addr, dlpf_set_addr six = read_six() six_str = str(six)[1:-1] ic += 1 if not ic % nsamples: isetup += 1 scale, dlpf = setups[isetup % nsetups] bus.write_byte_data(address, accel_scale_addr, scale) bus.write_byte_data(address, gyro_scale_addr, scale) bus.write_byte_data(address, dlpf_set_addr, dlpf) return six_str + ", " + str(isetup) if __name__ == "__main__": # wake the 6050 up since it starts in sleep mode bus.write_byte_dta(address, pwrmgmt_1, 0) time.sleep(0.5) scale, dlpf = setups[isetup] bus.write_byte_data(address, accel_scale_addr, scale) bus.write_byte_data(address, gyro_scale_addr, scale) bus.write_byte_data(address, dlpf_set_addr, dlpf) print "setup scale: ", scale print "setup dlpf: ", dlpf time.sleep(0.1) ic = 0 app = web.application(urls, globals()) app.run()