Search code examples
arduinoaccelerometerspigyroscope

Random Spikes while logging raw data from IMU using SPI on Arduino


I would need to make the noise characterization of the LSM9DS1 IMU. For this purpose I would need to acquire raw data from the sensors for a long time (around 10 hours) while in static conditions. I prepared a logging system composed by an Arduino Uno and the IMU connected to it using SPI protocol. The system works good enough, however, I get random spikes on the accelerometer and gyroscope even if the IMU is in static condition. These spikes seem to be always around +/- 250 from the mean value. The following figure shows these spikes on the X axis of the accelerometer. enter image description here

The IMU is set to provide data at 50 Hz and I also read data at the same frequency. Following is my Arduino code based on the LSM9DS1 library provided by Sparkfun:

#include <Wire.h>
#include <SPI.h>
#include <SparkFunLSM9DS1.h>

LSM9DS1 imu;

#define LSM9DS1_M_CS    10 // Can be any digital pin
#define LSM9DS1_AG_CS   9  // Can be any other digital pin

void setup() 
{
  Serial.begin(115200);

  imu.settings.device.commInterface = IMU_MODE_SPI;
  imu.settings.device.mAddress = LSM9DS1_M_CS;
  imu.settings.device.agAddress = LSM9DS1_AG_CS;

  if (!imu.begin())
  {
    Serial.println("Failed to communicate with LSM9DS1.");
    while (1);
  }


  imu.enableFIFO(false);
  imu.setFIFO(FIFO_OFF,0x00);
}

void loop()
{
  Serial.print(micros());
  Serial.print(" ");
  printAccel();
  printGyro(); 

  delay(20);

}

void printGyro()
{
  imu.readGyro();
  Serial.print(imu.gx);
  Serial.print(" ");
  Serial.print(imu.gy);
  Serial.print(" ");
  Serial.println(imu.gz);
}

void printAccel()
{
  imu.readAccel();
  Serial.print(imu.ax);
  Serial.print(" ");
  Serial.print(imu.ay);
  Serial.print(" ");
  Serial.print(imu.az);
  Serial.print(" ");
}

Solution

  • The "spikes" seem to be very low energy, maybe one spurious reading every now and again. You could certainly try to figure out exactly what is causing them (it could be something like some one slamming a door for all you know), but I think that is more of a hardware debug issue.

    I think ultimately you will want to filter out all that noise anyway. How complicated a digital filter you will need is dependent on how fast your "measurements" compared to the random noise in the measurements.

    One of simplest filters is the following, where filterValue is the "running" value, senseValue is the current raw measurement, and scaleFactor is a number < 1 (0.1, or 0.01 for eample). The smaller the number the more it will filter, but also the more "lag" you will see.

    filterValue = filterValue + scaleFactor * (senseValue - filterValue);

    I think once you filter the data reasonably, those "spikes" will vanish.

    Since you have data stored you can just run it thru the filter and see how it looks.