Accelerometer - What am I doing wrong?

Hi,

For a school project, we are using a MPU-6050 accelerometer which is placed under a headband (on the users forehead), and a vibrating source (on the back of the head) which is held tightly conjoined with the same headband that the accelerometer is underneath. The vibrating source is secured so it doesn't move during testing.

Basically, we know that the vibrating source produces a sine wave. Right now, I am using a 3rd-Party app named PuTTY, which basically allows me to save data directly as a txt. file from the Arduino. The system on the back of the head vibrates at 60Hz. Research shows that sampling rate should be about 4ish times higher than real frequency vibration, so I am sampling at 4ms. We are doing this in the time domain.

This is my code `#include <Wire.h>

#define MPU_ADDR 0x68 // MPU-6050 I2C address

int16_t ax, ay, az;

void setup() {
Serial.begin(2000000);
Wire.begin();
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);

// Configure accelerometer range to ±4g
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x1C); // ACCEL_CONFIG register
Wire.write(0x08); // Set to 0x08 for ±4g range
Wire.endTransmission(true);
}

void loop() {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDR, 6, true); // request 6 bytes (3 axis acceleration data)

// Read the acceleration data from the sensor
ax = Wire.read() << 8 | Wire.read();
ay = Wire.read() << 8 | Wire.read();
az = Wire.read() << 8 | Wire.read();

// Amplify the acceleration values in the x and y directions
float amplified_ax = (ax / 16384.0) * 100;
float amplified_ay = (ay / 16384.0) * 100;
float amplified_az = (az / 16384.0) * 100;

// Output the amplified acceleration values in a single line separated by commas
Serial.print(amplified_ax, 4);
Serial.print(",");
Serial.print(amplified_ay, 4);
Serial.print(",");
Serial.println(amplified_az, 4);

delay(4);
}
`

There are a few issues we are encountering

  1. We run 1min tests, hoping for 15000 samples (4ms sampling rate) within this time. We never seem to return the 15000 samples. It's often more around a 7-8ms sampling rate.
  2. As I said earlier, the device has an expected sine wave output. I don't believe the reading across the head is effecting this. There is an artificial mastoid system here: [Artificial Mastoid | Type 4930 | Brüel & Kjær] which is used in the calibration of hearing aids. We use this system, we get a sine wave output from it.


This is the desired output.

image
This is what we're getting.

  1. I am using an MPU60-50 accelerometer, which should be good enough to detect this vibration. I am using it also with an Arduino uno. I am using these cables as a connection. https://www.amazon.com/gp/product/B07GD2RP9C/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1
    Noted, I am also only using the VCC,GND SCL, SDA pins of the accelerometer. There are XDA,XCL,ADC,INT pins being unused currently.

Any response is truly appreciated

If you are sampling at 4x the input frequency, you can't expect the output waveform to resemble a sine wave. The posted graph is not a surprise. For even approximate resemblance to a sine wave, sample at at least 10x the input frequency.

What is the default Output Data Rate? Set that to be at least as high as the sample rate.

Why choose +/- 4g range? You are simply throwing away resolution.

The desired output I showed was from another groups data. They were using a different accelerometer and are using something other than arduino. They we're sampling 4x as well.

The output data rate is 4ms or 250ish a second. We are using 2000000 baud rate.

The +/-4g is something I just changed to like an hour ago as a shot in the dark. We have been testing at 2g

If by ODR, you're refering to Baud rate, do you mean to set the baud to the lowest level?

No. Check the sensor data sheet. The ODR is an extremely important parameter.

They we're sampling 4x as well

They are making the same mistake.

ODR is 1kHz. The professor makes us sample 4x and the group that got the sine wave looking like that already received A's

That is the actual sensor sample rate. Now, you need to calculate from the time needed for the I2C transaction with the sensor, the serial Baud rate and number of characters sent, how many samples/second you are transmitting to the PC.

Oh, and what do you think this does?

delay(4);

noInterrupts();
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 3999; // 16 MHz / (prescaler * desired frequency) - 1
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS11) | (1 << CS10); // Prescaler 64
TIMSK1 |= (1 << OCIE1A); // Enable timer compare interrupt
interrupts();

Check the setting of the DLPF, too. It should be turned off.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.