MPU6050 Problem to operate with sensor data

Hello all, I'm starting with Arduino projects and i'm currently facing a problem that maybe someone here can help me. My project is small car that has a self balancing platform over it. The platform rotation is provided by a servo motor. And over this platform a MPU6050 sensor is placed to get its angle. This car will walk through an irregular surface and the platform should be always parallel (90 degress) with this surface.

The problem starts when the code operate my current read with the error obtained from the setpoint.

My code is bellow and the problem is written in red:

#include<Wire.h>
#include "Servo.h"

//Start I2C address for MPU6050
  const int MPU=0x68;  

//Variables to storage sensor data
  int AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
  int degA = 0, degP = 0;
  int servoOutputPercentage = 0, servoOutputDegrees = 0;

//Control variables
  float setPoint = 50; //50% means that my platform is 90 degress
  float error = 0;
   
//DC car motor control
  int TransistorPin = 3;
  int PotencPin = A0;
  int ReadPot = 0;
  int ValuePWM = 0;
  
Servo myservo;


void setup()
{
  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B); 
   
//Starting MPU-6050
  Wire.write(0); 
  Wire.endTransmission(true);
  
//Set platform to start position
  myservo.attach(9);
  myservo.write(90);

 delay(3000); 
  
}

void loop()
{ 
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  
  //Requesting data from sensor
  Wire.requestFrom(MPU,14,true);  
  
  //Reading values from MPU
  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)


//Limiting the values from sensor from 65 to 115 degrees
  if(AcY<=-4500) AcY=-4500;
  if(AcY>=5000) AcY=5000;

//Converting AcY to angles and percentage 
   degA = map(AcY, -17000, 17000, 0, 179);
   degP = map(AcY, -4500, 5000, 0, 100);     


  error = setPoint - degP; //comparing my setpoint with current read from MPU in percentage
  
  servoOutputPercentage=degP + error; [b][color=red]Here is the problem, my variable servoOutputPercentage stays always locked in 90[/color][/b]

  servoOutputDegrees=map(servoOutputPercentage, 0, 100, 65, 115); 

  
//Servo output
  myservo.write(servoOutputDegrees);

 
//DC motor control
  ReadPot = analogRead(PotencPin);
  ValuePWM = map(ReadPot, 0, 1023, 0, 255);
  analogWrite(TransistorPin, ValorPWM);

       
    
  delay(100); 
}

Could you please help me in this case?

Thanks in advance.

Please edit your post and enclose the code in code tags ("</>" button).

Hii..
I am unable to find the problem that you mentioned is marked red in your post. I think you are not getting the right values from the sensor MPU6050. I suggest you to try this code for MPU-6000 , a similiar module. You can use it without further editing. First try interfacing of only this sensor.

MPU-6000 Arduino code

In case you experience any problem with working of servo motor alongwith the sensor, try to separate the power requirements. I hope this solves your problem.

batman_d408:
Hii..
I am unable to find the problem that you mentioned is marked red in your post. I think you are not getting the right values from the sensor MPU6050. I suggest you to try this code for MPU-6000 , a similiar module. You can use it without further editing. First try interfacing of only this sensor.

MPU-6000 Arduino code

In case you experience any problem with working of servo motor alongwith the sensor, try to separate the power requirements. I hope this solves your problem.

Thank you batman_d408 but unfortunatelly I cant find the MPU6000 where I live. But I'm glad for your effort!

Thanks!
Guilherme Porto

You can use the same code mentioned above in the link for your module (MPU-6050)also as their datasheets are same. The code would work for you as well. :slight_smile:

No, no, no.

The code you are using for acquiring data from the MPU 6050 is perfect!!!! Here is the deal:

You are finding the error this way:

  error = setPoint - degP; //comparing my setpoint with current read from MPU in percentage

Which is fine, but then you turn around and assign servoOutputPercentage this value:

  servoOutputPercentage=degP + error; [b][color=red]Here is the problem, my variable servoOutputPercentage stays always locked in 90[/color][/b]

This will always give you 90 degrees because the original setPoint is 50 (or 90 degrees) and NEVER UPDATES. Also, if you compare the two lines of code I have quoted, you can easily see that servoOutputPercentage = setPoint. This is because setPoint = error + degP which is equal to servoOutputPercentage. Therefore, servoOutputPercentage = setPoint.

Does this help? :wink: