Measuring Vibration using BNO055 accelerometer.

Hello,

I've been trying to measure the frequency of vibration using an accelerometer (BNO055).
First, I wrote the code using the Fast Fourier Transform (fft) library with a function generator as the input.
After making sure that the program gives out the same frequency as the function generator, I tried implementing the accelerometer into the code. However, the results are not correct. I'm outputting the frequencies with their corresponding amplitudes. And at the end it outputs the dominant frequency. Please find code and results below:

#define SAMPLES 128
#define SAMPLING_FREQUENCY 20 //Hz, must be less than 10000 

#include "arduinoFFT.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>

Adafruit_BNO055 bno = Adafruit_BNO055();
arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period;
unsigned long microseconds;

double vReal[SAMPLES];
double vImag[SAMPLES];

void setup() {
  Serial.begin(115200);
  sampling_period = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
  if (!bno.begin()) {
    Serial.print("Wiring error");
    while (1);
  }
}

void loop() {
  unsigned long t1 = micros();// initiate time to start count

  imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);// calling out acceleration from accelerometer

  //  Serial.print("a = ");
  //  Serial.println(euler.y()); // acceleartion in y direction

  /*SAMPLING*/
  for (int i = 0; i < SAMPLES; i++) {
    microseconds = micros();    //Overflows after around 70 minutes!

    vReal[i] = euler.y();
    vImag[i] = 0;

    while ((micros() - microseconds) < sampling_period); // control constant time-stamp
  }

  /*FFT*/
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
  double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

  Serial.println("    freq    ampl");
  for (int i = 0; i < (SAMPLES / 2); i++) {
    /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/
    Serial.print(i);
    Serial.print("  ");
    Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
    Serial.print(" Hz");
    Serial.print("   ");
    Serial.println(vReal[i], 1);    //View only this line in serial plotter to visualize the bins

  }
  Serial.print("\n");

  /*PRINT RESULTS*/
  Serial.print("f = ");
  Serial.print(peak);     //Print out what frequency is most dominant.
  Serial.println(" Hz");
  Serial.print("\n");

  while ((micros() - t1) < 100000);
}

Results when accelerometer is not moving:

    freq    ampl
0  0.0 Hz   6.2
1  0.2 Hz   2.7
2  0.3 Hz   0.0
3  0.5 Hz   0.0
4  0.6 Hz   0.0
5  0.8 Hz   0.0
6  0.9 Hz   0.0
7  1.1 Hz   0.0
8  1.2 Hz   0.0
9  1.4 Hz   0.0
10  1.6 Hz   0.0
11  1.7 Hz   0.0
12  1.9 Hz   0.0
13  2.0 Hz   0.0
14  2.2 Hz   0.0
15  2.3 Hz   0.0
16  2.5 Hz   0.0
17  2.7 Hz   0.0
18  2.8 Hz   0.0
19  3.0 Hz   0.0
20  3.1 Hz   0.0
21  3.3 Hz   0.0
22  3.4 Hz   0.0
23  3.6 Hz   0.0
24  3.7 Hz   0.0
25  3.9 Hz   0.0
26  4.1 Hz   0.0
27  4.2 Hz   0.0
28  4.4 Hz   0.0
29  4.5 Hz   0.0
30  4.7 Hz   0.0
31  4.8 Hz   0.0
32  5.0 Hz   0.0
33  5.2 Hz   0.0
34  5.3 Hz   0.0
35  5.5 Hz   0.0
36  5.6 Hz   0.0
37  5.8 Hz   0.0
38  5.9 Hz   0.0
39  6.1 Hz   0.0
40  6.3 Hz   0.0
41  6.4 Hz   0.0
42  6.6 Hz   0.0
43  6.7 Hz   0.0
44  6.9 Hz   0.0
45  7.0 Hz   0.0
46  7.2 Hz   0.0
47  7.3 Hz   0.0
48  7.5 Hz   0.0
49  7.7 Hz   0.0
50  7.8 Hz   0.0
51  8.0 Hz   0.0
52  8.1 Hz   0.0
53  8.3 Hz   0.0
54  8.4 Hz   0.0
55  8.6 Hz   0.0
56  8.8 Hz   0.0
57  8.9 Hz   0.0
58  9.1 Hz   0.0
59  9.2 Hz   0.0
60  9.4 Hz   0.0
61  9.5 Hz   0.0
62  9.7 Hz   0.0
63  9.8 Hz   0.0

f = 9.89 Hz

Results when accelerometer is moving:

    freq    ampl
0  0.0 Hz   1586.0
1  0.2 Hz   682.7
2  0.3 Hz   3.6
3  0.5 Hz   1.4
4  0.6 Hz   0.7
5  0.8 Hz   0.4
6  0.9 Hz   0.3
7  1.1 Hz   0.2
8  1.2 Hz   0.2
9  1.4 Hz   0.1
10  1.6 Hz   0.1
11  1.7 Hz   0.1
12  1.9 Hz   0.1
13  2.0 Hz   0.1
14  2.2 Hz   0.1
15  2.3 Hz   0.0
16  2.5 Hz   0.0
17  2.7 Hz   0.0
18  2.8 Hz   0.0
19  3.0 Hz   0.0
20  3.1 Hz   0.0
21  3.3 Hz   0.0
22  3.4 Hz   0.0
23  3.6 Hz   0.0
24  3.7 Hz   0.0
25  3.9 Hz   0.0
26  4.1 Hz   0.0
27  4.2 Hz   0.0
28  4.4 Hz   0.0
29  4.5 Hz   0.0
30  4.7 Hz   0.0
31  4.8 Hz   0.0
32  5.0 Hz   0.0
33  5.2 Hz   0.0
34  5.3 Hz   0.0
35  5.5 Hz   0.0
36  5.6 Hz   0.0
37  5.8 Hz   0.0
38  5.9 Hz   0.0
39  6.1 Hz   0.0
40  6.3 Hz   0.0
41  6.4 Hz   0.0
42  6.6 Hz   0.0
43  6.7 Hz   0.0
44  6.9 Hz   0.0
45  7.0 Hz   0.0
46  7.2 Hz   0.0
47  7.3 Hz   0.0
48  7.5 Hz   0.0
49  7.7 Hz   0.0
50  7.8 Hz   0.0
51  8.0 Hz   0.0
52  8.1 Hz   0.0
53  8.3 Hz   0.0
54  8.4 Hz   0.0
55  8.6 Hz   0.0
56  8.8 Hz   0.0
57  8.9 Hz   0.0
58  9.1 Hz   0.0
59  9.2 Hz   0.0
60  9.4 Hz   0.0
61  9.5 Hz   0.0
62  9.7 Hz   0.0
63  9.8 Hz   0.0

f = 9.89 Hz

You can see from the results that there are mainly two issues:

  1. It keeps giving 9.89 Hz as the dominant frequency even though it has no amplitude.

  2. When the accelerometer moves, you should expect values that are greater than 1 Hz to be present. However, it seems that the motion only increases the amplitude of 0 Hz and 0.2 Hz. This occurs even when the accelerometer is moving quite fast that the frequency should definitely be above 3 Hz.

I don't know what to change to make the readings correct. Keep in mind that this code worked with a function generator connected to analogue pin 0.

I would appreciate any help!

Thank you!

I forgot to mention that when I change the number of SAMPLES, the dominant frequency changes. However it still remains constant.

Thanks!