Connecting Servo Motor with MPU6050

Hi, i'm a Mechatronics student and i'm working on a project so I can end my last year. I'm doing a gimbal with 3 axis, connected to an Arduino Leonardo and a MPU6050. I searched how to connect the MPU6050 to the arduino, but I could only find the connections to an Arduino UNO. I Connected how it said, and it wasn´t working. I searched a bit more and I figured it out, the connections on an Arduino Leonardo are different from the ones in Leonardo.
So, now that the Arduino is reading the values of the MPU6050, i continued with my work, which was connecting the 3 servo motors SG-90 to the Arduino, and make it move consequently the values of the MPU. I started to connect only 1 servo motor. I tried connecting the pins I searched, and the servo motor wasn´t working how i wanted it. I can´t find a resolution.
I would like you to tell me where should I connect the Servo Motor, and if i can´t, should i change to the Arduino UNO? Thank you.

The connections of the MPU6050 to the Arduino Leonardo are:

  • VCC to 5v
  • GND to GND
  • SCL to 3
  • SCA to 2
  • INT to 7

The connections of the Servo Motors SG-90 to the Arduino Leonardo are:

  • Brown - GND
  • Red - 5v
  • Orange - 13

The servos should not be connected to the Arduino's 5V pin. They should have separate connections to a 5V supply that can provide enough current for them. For 3 x SG90s it's wise to have at least 2A available, 3A would be safer. The power supply ground, servo grounds and the Arduino ground must be connected together.

The servo signal wires just need a standard digital pin so pin 13 on a Leonardo should be fine. Of course how well it works depends on the code and you haven't shown us that.

Also note the MPU6050 is a 3.3V device and will NOT take 5V. Though perhaps you actually have a breakout board that allows the use of a 5V supply?

Steve

slipstick:
The servos should not be connected to the Arduino's 5V pin. They should have separate connections to a 5V supply that can provide enough current for them. For 3 x SG90s it's wise to have at least 2A available, 3A would be safer. The power supply ground, servo grounds and the Arduino ground must be connected together.

The servo signal wires just need a standard digital pin so pin 13 on a Leonardo should be fine. Of course how well it works depends on the code and you haven't shown us that.

Also note the MPU6050 is a 3.3V device and will NOT take 5V. Though perhaps you actually have a breakout board that allows the use of a 5V supply?

Steve

I'm thinking about using one 9V battery, so now that you just talked about the Amps, is 1 9V battery enough for the whole systeM?
No i'm not using a breakout board, im powering the whole circuit with the 5v from the arduino, which is connected (for now) to the computer.
Sorry for the inconvenience, but the code is too big, so instead ill provide you the code as an attachment.

MPU6050_DMP6.ino (15.7 KB)

I'm thinking about using one 9V battery, so now that you just talked about the Amps, is 1 9V battery enough for the whole systeM?

What type of 9V battery would that be ?

A PP3 (rectangular with terminals on the top) will not provide enough current even for the Arduino for very long, let alone the servos

UKHeliBob:
What type of 9V battery would that be ?

A PP3 (rectangular with terminals on the top) will not provide enough current even for the Arduino for very long, let alone the servos

I was thinking about that one, but since you say it can´t be, is there any that is portable?

is there any that is portable?

4 AAs would be more suitable, but much heavier, of course

UKHeliBob:
4 AAs would be more suitable, but much heavier, of course

Thank you, ill change my structure so the batteries can fit.
About the problem in the code/connections, are you able to help me find my error? I'm still thinking that i should change to Arduino UNO, since everyone does the gimbals with it, but that would cost me 1 more month waiting for it to arrive. But before I make that decision, i would like to fight a bit more with the leonardo.

Filipe-Moleiro:
Thank you, ill change my structure so the batteries can fit.
About the problem in the code/connections, are you able to help me find my error? I'm still thinking that i should change to Arduino UNO, since everyone does the gimbals with it, but that would cost me 1 more month waiting for it to arrive. But before I make that decision, i would like to fight a bit more with the leonardo.

I don't see a problem with using an leonardo
Try this code and tell me if it works for you reading the MPU6050

This is my version of the demo sketch with some fixes we discovered

Z
If this works we are in business and I can further assist you.

MPU6050_Latest_code_Leonardo_int_pin_7.ino (7.98 KB)

Filipe-Moleiro:
Sorry for the inconvenience, but the code is too big, so instead ill provide you the code as an attachment.

The reason the servo doesn't work is because there is no code in there that even tries to do anything with a servo.

Steve

zhomeslice:
I don't see a problem with using an leonardo
Try this code and tell me if it works for you reading the MPU6050

This is my version of the demo sketch with some fixes we discovered

Z
If this works we are in business and I can further assist you.

Tried your code, but this error appears.

'getGravity' was not declared in this scope

Ah yes I did add an alternate function for get gravity elsewhere. I made corrections to use the native version found in the MPU6050_6Axis_MotionApps20.h

now with that working :slight_smile: your values will be drifting a little

Get the calibration values for the MPU6050 calibration code I'm attaching also

you will find the MPU6050 much more stable now.

How this code works.
your MPU6050 triggers an interrupt about ever 10ms to let you know the DMP is ready. it triggers the i2c bus request to get the 42 bytes of data stored in the FIFO buffer which has lots of data available for you to use.

  Default MotionApps v2.0 42-byte FIFO packet structure:    
 [QUAT W][      ][QUAT X][      ][QUAT Y][      ][QUAT Z][      ][GYRO X][      ][GYRO Y][      ] [GYRO Z][      ][ACC X ][      ][ACC Y ][      ][ACC Z ][      ][      ]    
  0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20  21  22  23   24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41

The functions like the getGravity use the QUAT W,X,Y,Z to calculate the values. the resulting output with my code is angles in Degrees but I convert this from radians so both are easily available for you to use.

Look for the MPUMath() funtion

// ================================================================
// ===                        MPU Math                          ===
// ================================================================
float Yaw, Pitch, Roll;
void MPUMath() {
  mpu.dmpGetQuaternion(&q, fifoBuffer);
  mpu.dmpGetGravity(&gravity, &q);
  mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
  Yaw = (ypr[0] * 180.0 / M_PI);
  Pitch = (ypr[1] *  180.0 / M_PI);
  Roll = (ypr[2] *  180.0 / M_PI);
  getYawPitchRollInDeg(ypr, &q, &gravity);
  
  DPRINTSTIMER(100) {
    DPRINTSFN(15, " W:", q.w, -6, 4);
    DPRINTSFN(15, " X:", q.x, -6, 4);
    DPRINTSFN(15, " Y:", q.y, -6, 4);
    DPRINTSFN(15, " Z:", q.z, -6, 4);

    DPRINTSFN(15, " Yaw:", Yaw, -6, 2);
    DPRINTSFN(15, " Pitch:", Pitch, -6, 2);
    DPRINTSFN(15, " Roll:", Roll, -6, 2);
    DPRINTSFN(15, " Yaw:", ypr[0], -6, 2);
    DPRINTSFN(15, " Pitch:", ypr[1], -6, 2);
    DPRINTSFN(15, " Roll:", ypr[2], -6, 2);
    DPRINTLN();
  }
}

This routine will only trigger every 10ms when real data is received.
It conveniently provides you with angles in degrees ready for you to use.
Note The DPRINTS*** arn macros to provide easy Debugging output to the serial monitor
they are just glorified Serial.println() and can be deleted and replaced with your code.
Example Macro:

#define  DPRINTSFN(StrSize,Name,...) {char S[StrSize];Serial.print("\t");Serial.print(Name);Serial.print(" "); Serial.print(dtostrf((float)__VA_ARGS__ ,S));}//StringSize,Name,Variable,Spaces,Percision

Serial prints a tab Prints the name and a space then prints the number by converting it to a string using dtostrf()
lots of stuff done with this one macro :slight_smile:

Also note that the code I provided is not blocking so you have lots of processing time available to do other stuff

void loop() {
  if (mpuInterrupt ) { // wait for MPU interrupt or extra packet(s) available
    GetDMP(); // only runs every 10ms when the interrupt is triggered
  }
// place other non blocking code here 
}

Z

MPU6050_Latest_code_Leonardo_int_pin_7.ino (7.88 KB)

MPU6050_calibration.ino (7.64 KB)

Sorry for really late reply, but I was only able to work on my project again today. I used the codes you sent, and I downloaded the libraries that were missing, now I get this error from the code MPU6050_Latest_code_Leonardo_int_pin_7

'getYawPitchRollInDeg' was not declared in this scope

Filipe-Moleiro:
Sorry for really late reply, but I was only able to work on my project again today. I used the codes you sent, and I downloaded the libraries that were missing, now I get this error from the code MPU6050_Latest_code_Leonardo_int_pin_7

'getYawPitchRollInDeg' was not declared in this scope

This line can be removed :slight_smile: it is already done with the above 3 lines. i thought I got them all

  Yaw = (ypr[0] * 180.0 / M_PI);
  Pitch = (ypr[1] *  180.0 / M_PI);
  Roll = (ypr[2] *  180.0 / M_PI);
  // getYawPitchRollInDeg(ypr, &q, &gravity); // << yaw pitch and roll are converted to degrees in the above 3 lines so my all in one function isn't needed any more.
// Remark out the above function call

Thanks for your patience sorry about the error.

Z

zhomeslice:
This line can be removed :slight_smile: it is already done with the above 3 lines. i thought I got them all

  Yaw = (ypr[0] * 180.0 / M_PI);

Pitch = (ypr[1] *  180.0 / M_PI);
  Roll = (ypr[2] *  180.0 / M_PI);
  // getYawPitchRollInDeg(ypr, &q, &gravity); // << yaw pitch and roll are converted to degrees in the above 3 lines so my all in one function isn't needed any more.
// Remark out the above function call




Thanks for your patience sorry about the error.

Z

I'm using the 3.3v pin in leonardo to power the mpu, and the 5v pin to power the sg90, tried the code and it's not working. I don't understand why.

Filipe-Moleiro:
I'm using the 3.3v pin in leonardo to power the mpu, and the 5v pin to power the sg90, tried the code and it's not working. I don't understand why.

The MPU6050 breakout board VCC pin is a 5V pin. there is a Voltage regulator that provides 3.3V on the breakout board and also the i2c pullup resistors are provided and attached to the 3.3V side of the Voltage regulator.

Z

zhomeslice:
The MPU6050 breakout board VCC pin is a 5V pin. there is a Voltage regulator that provides 3.3V on the breakout board and also the i2c pullup resistors are provided and attached to the 3.3V side of the Voltage regulator.

Sorry if this sounds dumb, but you telling me that i should power everything with the 5v arduino pin?
Another thing, i forgot to put my own offsets, i will try as soon as possible and update you with the results.

Filipe-Moleiro:
Sorry if this sounds dumb, but you telling me that i should power everything with the 5v arduino pin?
Another thing, i forgot to put my own offsets, i will try as soon as possible and update you with the results.

So Just to be sure that we don't blow up the MPU6050 Chip. I am talking about these Breakout boards

at the top left next to the VCC pin is a voltage regulator that looks like this one

if your breakout board has this you are 5V Safe and this includes the i2c buss. The I2c Buss has pull up resistors the are connected to the 3.3v supply so you do not need to provide any pullup resistors.


*** With this said *** the ADO (Address Select) Pin is only connected to ground with a pull down resistor and
**IS NOT 5V safe. ** But by adding a 2.4K resistor to the ADO pin The 4.7K and 2.4K will become a voltage divider and 5V applied to the 2.4K resistor is good providing a 3.3v to the MPU6050 Pin.


If you need to provide the MPU6050 breakout with 3.3V you will want to perform surgery on the breakout board by bypassing The voltage regulator.

if you don't and you provide the mpu with 3.3V the LED will probably be off because the 3.3V voltage regulator has low voltage shutoff.

Found this in the Datasheet:

Because the LM3940 is a true low dropout regulator, it can hold its 3.3-V output in regulation with input voltages as low as 4.5 V

Voltage Regulator Datasheet: http://www.ti.com/lit/ds/symlink/lm3940.pdf

Z

zhomeslice:


*** With this said *** the ADO (Address Select) Pin is only connected to ground with a pull down resistor and
IS NOT 5V safe. But by adding a 2.4K resistor to the ADO pin The 4.7K and 2.4K will become a voltage divider and 5V applied to the 2.4K resistor is good providing a 3.3v to the MPU6050 Pin.


If you need to provide the MPU6050 breakout with 3.3V you will want to perform surgery on the breakout board by bypassing The voltage regulator.

if you don't and you provide the mpu with 3.3V the LED will probably be off because the 3.3V voltage regulator has low voltage shutoff.

Found this in the Datasheet:
Voltage Regulator Datasheet: http://www.ti.com/lit/ds/symlink/lm3940.pdf

Z

Well this is strange, bc my mpu has that breakout board, but when i power it with 3.3v from the arduino, the led turns on. I'm not connecting the ad0 to anything, so ill try that, does it have to be a specific gnd or just any?

Filipe-Moleiro:
Well this is strange, bc my mpu has that breakout board, but when i power it with 3.3v from the arduino, the led turns on. I'm not connecting the ad0 to anything, so ill try that, does it have to be a specific gnd or just any?

If the voltage regulator is not the one I believe they they use it may not cut out at 4.5V dropping power to the MPU but there is a voltage drop across the regulator that could reach the low limits of the MPU or the Arduino input (i2c buss) and int pin (usually pin 2 on the uno).
The MPU6050 can handle as low as 2.375V with a max of 3.46V found on the datasheet. Now there is another issue to consider what is the lowest voltage your ATMega MPU considers as a HIGH value so the i2c bus can work. we are pulling the i2c buss high from the 3.3V side of the MUP6050 breakout board regulator.
To be safe :slight_smile:
If you have the voltage regulator on the MPU6050 breakout you can use 5V, not that it can't work by powering the breakout VCC off of 3.3v it gives you a better chance that nothing will be out of limits. I'm concerned that there would be problems by the fact we are outside of design specs on the MPU6050 breakout board.
Z

zhomeslice:
If the voltage regulator is not the one I believe they they use it may not cut out at 4.5V dropping power to the MPU but there is a voltage drop across the regulator that could reach the low limits of the MPU or the Arduino input (i2c buss) and int pin (usually pin 2 on the uno).
The MPU6050 can handle as low as 2.375V with a max of 3.46V found on the datasheet. Now there is another issue to consider what is the lowest voltage your ATMega MPU considers as a HIGH value so the i2c bus can work. we are pulling the i2c buss high from the 3.3V side of the MUP6050 breakout board regulator.
To be safe :slight_smile:
If you have the voltage regulator on the MPU6050 breakout you can use 5V, not that it can't work by powering the breakout VCC off of 3.3v it gives you a better chance that nothing will be out of limits. I'm concerned that there would be problems by the fact we are outside of design specs on the MPU6050 breakout board.
Z

I've changed the offsets to myown ones, it is still not working. My connections are:
Mpu to arduino:
VCC-5v
GND-GND
SCL-3
SCA-2
AD0-GND
INT-7

servo motor to arduino:
yellow-13
red-5v
brown-ground