MPU-6050 motion detection

Hi everyone, sorry for my english, i’m french :grinning:

I’m a newbie to arduinos, and i have a little problem that is driving me crazy :slight_smile: , I’ve done many searches before posting here, but any of them helped me.

I got a mpu-6050 (accelerometer + gyro + temperature sensor) built on a GY-521 board.

I just want the arduino (a romeo ble mini based on atmega 328p and the same bootloader as arduino uno) to execute some code if the sensor detects motion (and i want to set the motion threshold).

I’ve read many topics on many boards before posting but the solutions were too complicated for me.
By the way, librairies and sketches written by Jeff Rowberg don’t seem to give good results in my case (the measurement sketch sends unreadable characters in the serial monitor)
whereas this simple raw values measurements sketch works fine

// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
  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);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333);
}

Thanks for your help :slight_smile:

sends unreadable characters in the serial monitor

This is almost always because you have selected the wrong Baud rate (Serial.begin(value)).

With the MPU6050 accelerometer, you can detect acceleration, but not straight line, constant velocity motion. The gyro allows you to detect rotation, but not acceleration or straight line motion.

Thank you jremington,

in the sketch, the baud rate is set to 38400. So once, I tried to change the baud rate in the serial monitor to 38400, but then the ide was unable to detect any arduino devices in COM ports. I had to set back the default baud rate in the arduino config file to solve this problem. So maybe I need to think in the other way : changing the baud rate of the sketch to 9600 to be suitable with the serial monitor ?

jremington:
With the MPU6050 accelerometer, you can detect acceleration, but not straight line, constant velocity motion. The gyro allows you to detect rotation, but not acceleration or straight line motion.

I'm not sure to understand : I want to detect motion from a speed that I first set, no matter the direction or the axis of the motion (the arduino should detect voluntary motions, not unvoluntary shakes). Is it possible ?

The Baud rate in Serial.begin() must match the Baud rate setting in the serial monitor.

I want to detect motion from a speed that I first set, no matter the direction or the axis of the motion

I don't understand this. "motion" can mean many things.

jremington:
The Baud rate in Serial.begin() must match the Baud rate setting in the serial monitor.

You're right, i've just set the baud rate to 9600 in Serial.begin(), and now it seems to work fine, thank you.

jremington:
I don't understand this. "motion" can mean many things.

If the sensor suddenly moves (very fast), I want the arduino to be aware of this, and to run some code :slight_smile:

"suddenly moves" means it accelerates. That acceleration can be measured by the accelerometer.

jremington:
That acceleration can be measured by the accelerometer.

And how do you achieve that ? And how to set the threshold ?

You are already measuring the acceleration with the accelerometer.

whereas this simple raw values measurements sketch works fine

Evidently, you don't understand what the numbers mean. The data sheet will help with that, along with some experimentation.

jremington:
Evidently, you don't understand what the numbers mean. The data sheet will help with that, along with some experimentation.

According to what I've read, the numbers (of the accelerometer) represent the gravity applying to the x,y and z axis of the sensor, am I wrong ?

The acceleration due to gravity is measured along with the accelerations due to all other forces.

You can see this effect if you hold the sensor steady, with the X, Y or Z axis straight up and down.

Ok thank you, I'm going to try a few things, I'll be back if I'm still lagging :wink:

I tried this time to use the gyro even if I’m not sure to understand what are the numbers it returns (the robot I’m working on is spherical so I can use the gyro). I’ve uploaded this code :

#include <Wire.h>

#include <Romeo_m.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t GyX,GyY,GyZ;
void setup(void)
{ 
     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);
     Romeo_m.Initialise();
     //Serial.begin(9600); //Set Serial Baud
} 
void loop(void)
{ 
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,6,true);  // request a total of 14 registers
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  
  if(GyX > 20000 || GyY > 20000 || GyZ > 20000)
    {
            Romeo_m.motorControl(Forward,200,Forward,200); // the motors move forward at a speed of 200
            delay(1000); // during 1 sec
            Romeo_m.motorStop(); //then they stop
            delay(2000); // we wait 2 sec before starting again
    };
    
}

The sensitivity is pretty high but I think I can improve this point. The problem now is that this sketch seems to work fine only when the arduino is linked to the PC (through USB) AND powered by batteries. When the board is only running on batteries, the motors don’t move, I’m wondering why.

the motors don't move,

Get rid of the motors.

Make the setup as simple as possible, just the Arduino and the sensor, and make sure that you understand how the sensor works before adding other problems.

jremington:
Get rid of the motors.

Make the setup as simple as possible, just the Arduino and the sensor, and make sure that you understand how the sensor works before adding other problems.

I think now that I get it. To get accelerations in Gs, I have to divide the numbers by 16384 and to get rotation speeds with the gyro (in degrees per second ), I have to divide the numbers by 131.

These numbers are exactly what I'm looking for.
Now the problem is that I can't run code (motors) only on battery.