I would like to filter angular velocity data from a "cheap" gyroscope (60$). These values are used as an input of a nonlinear controller in a quadcopter application. I am not interested in removing the bias from the readings.

Edit: I'm using a l2g4200d gyroscope connected via i2c with an Arduino uno. The following samples are acquired with the arduino, sent via serial and plotted using matlab.

When the sensor is steady, the plot shows several undesired spikes.

enter image description here

How can I filter these spikes?

1st approach: Spikes are attenuated but still present...

Let's consider the following samples in which a couple of fast rotations are performed. Let's assume that the frequency components of the "fast movement" are the ones I will deal with in the final application.

enter image description here

Below, the discrete Fourier transform of the signal in a normalized frequency scale and the second order ButterWorth low pass filter.

enter image description here

With this filter, the main components of the signal are preserved.

enter image description here

Although the undesired spikes are attenuated by a factor of three the plot shows a slight phase shift...

enter image description here

And the spikes are still present. How can I improve this result? Thanks.


1./2. I am using a breakout board from Sparkfun. You can find the circuit with the Arduino and the gyro in this post: Can you roll with a L3G4200D gyroscope, Arduino and Matlab? I have added pullup resistors to the circuit. I would exclude this option because other sensors are connected via the i2c interface and they are working correctly. I haven't any decoupling capacitors installed near the integrated circuit of the gyro. The breakout board I'm using has them (0.1 uF). Please check the left side of the schematic below, maybe I am wrong.

enter image description here

Motors have a separate circuit and I have soldered all the components on a protoboard.

  1. The gyro is in the quadcopter body but during the test the motors were turned off.

  2. That is interesting. The sampling frequency used in the test was 200Hz. Increasing the update freq from 200 to 400 hz doubled the glitching.

I found other comments on the web about the same breakout board and topic. Open the comments at the bottom of the page and Ctrl-F virtual1

  • $\begingroup$ What chip are you using, what circuit is it in, what communication protocol are you using, and how are you testing this? I could speculate on reasons for the spikes but they're all shots in the dark without more information. $\endgroup$
    – Chuck
    Oct 23, 2015 at 0:51
  • $\begingroup$ Please see my edit $\endgroup$
    – UserK
    Oct 23, 2015 at 1:12
  • $\begingroup$ This is an interesting question. Do you have any independent verification of velocity, i.e. an encoder that you could use to calculate the acceleration, or higher resolution accelerometer that you could borrow for profiling? $\endgroup$
    – Mark Booth
    Oct 23, 2015 at 12:01
  • 2
    $\begingroup$ Have you tried a simple median filter? You will still get some of the lag effect though. $\endgroup$ Oct 23, 2015 at 12:48
  • 1
    $\begingroup$ Another option could be to ignore those samples based on the difference from the previous sample (assuming those spikes are one single point with no ramping up and down). $\endgroup$ Oct 23, 2015 at 12:49

3 Answers 3


Did you try out median filtering?

This nonlinear technique is suitable to counteract the presence of spikes while preserving the high frequency content of the input signal.


You gave the part number and protocol, but

  1. Can you provide a schematic for how this is installed in a circuit?
  2. Are you using the module or an individual chip?
  3. Is this all soldered together or is it connected on a breadboard?
  4. Is this laying on a table or similar or is it actually in a quadcopter body? Are the quadcopter motors running?
  5. What sampling rate are you using?

I ask because the spikes seem too large to be "just" noise. My thoughts on troubleshooting would then be to address whatever the underlying cause of the spikes is rather than trying to filter them out of the output. Potential issues I can think of are related to the questions I'm asking, so for each question I ask I'm thinking it could be:

  1. It could be either a voltage supply issue or communication line issue. Things to look at on the schematic: (A) Check that the supply voltage is actually within the 2.4 - 3.6V allowable input range (page 11); (B) Check that decoupling capacitors are installed and connected to a suitable voltage; (C) Check that I2C pullup resistors are installed; (D) Check what other large equipment (read:motors) are installed in the circuit and check that the power supply is capable of delivering peak current.
  2. Again, checking for decoupling capacitors and if everything is soldered correctly; on the module everything could be expected to be soldered correctly, but pullup resistors are not included.
  3. Breadboard connections can be noisy, especially at high communication rates. Also, a breadboard connection implies that the system may not be securely attached to anything.
  4. While unlikely, a loose chip/module could be experiencing some vibration (maybe from nearby speakers) that could explain the spikes. If the motors are running, this is a lot more likely. In addition, the motors could be browning out your voltage supply, creating issues for the gyro.
  5. This is mostly a curiosity question, but higher communication rates tend to cause/exacerbate issues.

I would guess it's probably a supply voltage issue, either to the chip directly or on the communication line, but again, they're all shots in the dark without more information.


From a link OP posted, there was this comment/answer:

What did work was setting it to read both the A8 and the 28 registers, then compare them. If they differ, read them again! Seems to have solved 100% of my glitching. Now I can get on to calibrating in peace.

This, coupled with other users that have similar issues, would leave me to believe it's a defective chip design. If you evaluate the data and the least significant byte is, in fact, always 255 when you get this glitch, then you could always just check for that condition and either ignore that sample or substitute the previous reading for the current reading, or do what is suggested above by 'virtual1' on the other site. I would avoid setting it to zero because this may cause "inverse glitches" if you get that spike while there is actually valid data.

  • $\begingroup$ Please see EDIT2. I appreciate your help! $\endgroup$
    – UserK
    Oct 23, 2015 at 14:16
  • $\begingroup$ Ok so this seems to be the only way to solve the problem. Ignoring the undesired data as suggested by @Brian Lynch. Last question. Is there any frequency based approach to select only the spikes since they have always the same characteristics? $\endgroup$
    – UserK
    Oct 23, 2015 at 17:50
  • $\begingroup$ Thank you very much Chuck. I will accept your answer but first I need to 'implement' the solution. $\endgroup$
    – UserK
    Oct 23, 2015 at 17:58
  • $\begingroup$ @UserK - I'm not sure what you mean by "frequency based approach", but the spikes don't happen on a regular interval or pattern that I can tell, so I think your best bet would be to look for signs that the spike is happening, either by evaluating only the least significant byte for 255 or by comparing the A8 and 28 registers as virtual1 suggested externally. $\endgroup$
    – Chuck
    Oct 23, 2015 at 18:09
  • 1
    $\begingroup$ I think virtual1's suggestion is more "bulletproof" in that it detects a verified error by comparing registers and re-polls the device. If the output is 3 bytes long, then ignoring every result with 255 in the LSB means you ignore up to 2^(8+8) = 65,536 possibly valid outputs. If all you do is re-poll the device if the LSB is 255 and that value is valid you can wind up stuck continuously re-polling the device. $\endgroup$
    – Chuck
    Oct 23, 2015 at 18:10

One of the options is to utilize the exponential moving average. The below picture shows data corrupted by Gaussian noise with zero mean and 0.4 variance and how the filter does a good job to remove the spiky noisy data.

enter image description here

x = -pi:0.01:2*pi;
perfectY = cos(x); % generate data 
noisyY = perfectY + .4 * randn(1, length(perfectY)); % corrupt data by noise 

a = 0.13; % tuning parameter 
preSmoothY = cos(-pi); % arbitrary initial value 

for i = 1:length(noisyY)
    Smooth = (1-a)*preSmoothY + a*noisyY(i);
    preSmoothY = Smooth;
    expY(i) = Smooth;

plot( x,noisyY,'g', x, expY,'r', 'LineWidth', 2)
hold on
plot(x, perfectY, 'b','LineWidth', 2)
grid on
legend('noisy  data', 'filtered  data', 'data')

Another choice is using Kalman filter. It is an optimal filter if you meet the requirements which means no filter can perform better than the Kalman. Unfortunately, the filter imposes some constraints on the signal such as linearity and Gaussianity. Moreover, the system must be described precisely.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.