MPU6050 Acceleration Detection

Hi,

I am new to coding and I am struggling to how to modify this code so that the LED is triggered when there is acceleration. I am wanting to place this in a vehicle and trigger an output when the vehicle is moving. However right now this code detects all motion not just acceleration which makes it too sensitive. Any guidance on what to modify is appreciated.

Thanks Sean


#include <Wire.h>
#include <MPU6050.h>

MPU6050 mpu;

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

  Serial.println("Initialize MPU6050");
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Error");
    delay(1000);
  }
  pinMode(13, OUTPUT);

  mpu.setThreshold(2);
}

void loop()
{
  Vector rawGyro = mpu.readRawGyro();
  Vector normGyro = mpu.readNormalizeGyro();
float normal_x = normGyro.XAxis;
float normal_y = normGyro.YAxis;
float normal_z = normGyro.ZAxis;
  Serial.print(" Xnorm = ");
  Serial.print(normal_x);
  Serial.print(" Ynorm = ");
  Serial.print(normal_y);
  Serial.print(" Znorm = ");
  Serial.println(normal_z);

  if(abs(normal_x) + abs(normal_y) + abs(normal_z) > 0.2){
    digitalWrite(13, HIGH);
  }else{
    digitalWrite(13, LOW);
  }
  
  delay(10);
}

Your question is a bit confusing. Do you wan the LED to come on only when the vehicles speed is increasing or whenever the vehicle is moving?
Forward only?

When its moving. Forward for sure, Reverse is optional. Thanks

The gyro won't do much for you, as it measures rate of rotation, and drifts with an offset. The acceleration sensor is more useful, but it detects the acceleration due to gravity, added to acceleration due to other forces as a 3D vector.

The usual method of detecting a change in motion is to calculate the total acceleration, which is, for floating point acceleration values:


float acc_tot = sqrt (ax*ax + ay*ay  + az*az);

and compare that to the resting value.

1 Like

Couldn't you just keep a running sum of ax and another for ay and when that sum is not close to zero then the vehicle is in motion?

Try it and see what happens!

I will directly.
The principle is sound though, right? The sum of accelerations is 0 when an object has come to rest.

No, the principle is not sound, for several reasons.

  1. accelerometer noise
  2. moving in a straight line at constant velocity == no acceleration
  3. the method assumes that the accelerometer Z axis is pointing perfectly parallel to the force of gravity

This code worked for me, thanks for the help.

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

Adafruit_MPU6050 mpu;

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

  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  // set accelerometer range to +-8G
  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  
  // set gyro range to +- 500 deg/s
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);

  // set filter bandwidth to 21 Hz
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);

  delay(100);

  pinMode(13, OUTPUT);

}

void loop() {
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");

  Serial.println("");
  delay(500);

   if(abs(a.acceleration.x) + abs(a.acceleration.y) + abs(a.acceleration.z) > 15.0){
    digitalWrite(13, LOW);
    delay(60000);
  }else{
    digitalWrite(13, HIGH);
  }
}