Servo doesn't rotate

Hello,

I’m a beginner using Arduino, I’m trying to have a one axis camera stabilizer working for a motorcycle, starting from an existing tutorial which you can find here :

With some help from the autor I’ve been able to compile and upload correctly the following code :

// 2 servo planar stabilization system
// wp
// Jan 2016
//
// Based on Jeff Rowber's work found at
// https://github.com/jrowberg/i2cdevlib/blob/master/Arduino/MPU6050/MPU6050.cpp
//
// Use at your own risk.
//
// This code is placed under the MIT License (MIT)
//
// Copyright (c) 2016 woojay poynter

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
//

// Servo Connection
// BROWN - gnd
// red - 5v
// yellow - d10 (pwm on Sero 1)
//        - d11 (servo 2)

// MPU Connection
//
// VCC - 5v
// GND - GND
// SCL - A5 (w/ 10k PuR)
// SDA - A4 (w/ 10k PuR)
// INT - D2 (not used)

#include <Servo.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
//#include "MPU6050.h" // not necessary if using MotionApps include file
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

#define LED_PIN 13
bool blinkState = true;

Servo Servo1;   // First Servo off the chassis
Servo Servo2;   // Second Servo off the chassis

int Servo1Pos = 0;
int Servo2Pos = 0;

float mpuPitch = 0;
float mpuRoll = 0;
float mpuYaw = 0;


// define MPU instance
MPU6050 mpu;                    // class default I2C address is 0x68; specific I2C addresses may be passed as a parameter here

// MPU control/status vars
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

// relative ypr[x] usage based on sensor orientation when mounted, e.g. ypr[PITCH]
#define PITCH   1     // defines the position within ypr[x] variable for PITCH; may vary due to sensor orientation when mounted
#define ROLL  2     // defines the position within ypr[x] variable for ROLL; may vary due to sensor orientation when mounted
#define YAW   0     // defines the position within ypr[x] variable for YAW; may vary due to sensor orientation when mounted

My current mounting is exactly the same as described in the tutorial, using two 9g servos :

But, as soon as I connect the board to a power source (from my computer or an external USB power source, once again as shown in the tutorial) … nothing happens
The servos should begin rotating to calibrate, then rotate when moving the MPU6050 chip

Maybe I’m missing something in the code that I should modify ?

Could somebody please help me with this ?

Thank you very much

Second part of the code :

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup()
{

  Servo1.attach(10);  // attaches the servo on D11 to the servo object
  Servo2.attach(11);  // Second servo on D11
  delay(50);
  Servo1.write(0); // These are command checks to see if the servos work and
  Servo2.write(60); // to help w/ the initial installation.
  delay(500); // Make sure these movements are clear from the rest of the chassis.
  Servo1.write(180);
  Servo2.write(120);
  delay(500);
  Servo1.write(0);
  Servo2.write(90);
  delay(500);

  // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif

  Serial.begin(115200);
  while (!Serial);      // wait for Leonardo enumeration, others continue immediately

  // initialize device
  Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();

  // verify connection
  Serial.println(F("Testing device connections..."));
  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

  // load and configure the DMP
  Serial.println(F("Initializing DMP"));
  devStatus = mpu.dmpInitialize();


  // INPUT CALIBRATED OFFSETS HERE; SPECIFIC FOR EACH UNIT AND EACH MOUNTING CONFIGURATION!!!!

  mpu.setXGyroOffset(118);
  mpu.setYGyroOffset(-44);
  mpu.setZGyroOffset(337);
  mpu.setXAccelOffset(-651);
  mpu.setYAccelOffset(670);
  mpu.setZAccelOffset(1895);

  // make sure it worked (returns 0 if so)
  if (devStatus == 0)
  {
    // turn on the DMP, now that it's ready
    Serial.println(F("Enabling DMP"));
    mpu.setDMPEnabled(true);

    // enable Arduino interrupt detection
    Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)"));
    mpuIntStatus = mpu.getIntStatus();

    // get expected DMP packet size for later comparison
    packetSize = mpu.dmpGetFIFOPacketSize();
  }
  else
  {
    // ERROR!
    // 1 = initial memory load failed, 2 = DMP configuration updates failed (if it's going to break, usually the code will be 1)
    Serial.print(F("DMP Initialization failed code = "));
    Serial.println(devStatus);
  }

  // configure LED for output
  pinMode(LED_PIN, OUTPUT);

} // setup()



// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop(void)
{
  processAccelGyro();
}   // loop()



// ================================================================
// ===                    PROCESS ACCEL/GYRO IF AVAILABLE       ===
// ================================================================

void processAccelGyro()
{

  // Get INT_STATUS byte
  mpuIntStatus = mpu.getIntStatus();

  // get current FIFO count
  fifoCount = mpu.getFIFOCount();

  // check for overflow (this should never happen unless our code is too inefficient)
  if ((mpuIntStatus & 0x10) || fifoCount == 1024)
  {
    // reset so we can continue cleanly
    mpu.resetFIFO();
    Serial.println(F("FIFO overflow!"));
    return;
  }

  if (mpuIntStatus & 0x02)  // otherwise continue processing
  {
    // check for correct available data length
    if (fifoCount < packetSize)
      return; //  fifoCount = mpu.getFIFOCount();

    // read a packet from FIFO
    mpu.getFIFOBytes(fifoBuffer, packetSize);

    // track FIFO count here in case there is > 1 packet available
    fifoCount -= packetSize;

    // flush buffer to prevent overflow
    mpu.resetFIFO();

    // display Euler angles in degrees
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
    mpuPitch = ypr[PITCH] * 180 / M_PI;
    mpuRoll = ypr[ROLL] * 180 / M_PI;
    mpuYaw  = ypr[YAW] * 180 / M_PI;

    // flush buffer to prevent overflow
    mpu.resetFIFO();

    // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);

    // flush buffer to prevent overflow
    mpu.resetFIFO();

    Servo1.write(-mpuPitch + 90);
    Servo2.write(mpuRoll + 90);
    //delay(10);

    // flush buffer to prevent overflow
    mpu.resetFIFO();

  } // if (mpuIntStatus & 0x02)
}  // processAccelGyro()

You are starting at a level that is far too advanced for your skills. Start at the beginning and learn about how Arduino works. There are many simple programs and projects that don't take long to work through. Without those skills, you can't make useful changes in a complicated program that is working, or fix one that is not.

For this project, first learn to make one servo move the way you want.
Then learn how to communicate with the IMU, and what the numbers that it produces mean.
Finally, go back to the original project, study the code and learn what each section does.

Yep, you are right and I'm aware of it
If this is the only way I'll do like this

As I can only work on this during my holidays, it's true that I hoped to find a working software in order to focus on the conception of the hardware part (which is more my domain)

I'm still looking for an answer on this code in order to have it working before my work takes my time, but I'll focus on the basics too

Thank you

Servo problems are often due to an inadequate servo power supply.

...R

As Robin2 points out, there may be a power supply problem. Your diagram does not show any batteries or power supplies, but it does show the servos and the Arduno connected to the same power lines. This is a mistake that beginners often make, and it almost never works (as thousands of posts on this forum describe).

It would take just a few minutes to set up a servo and the Arduino, following one of the simple examples. Power the servo separately, but connect the grounds of the two power supplies together. Do not trust ANY example that shows the servo connected to the same power supply as the Arduino. A USB connection cannot safely power even one servo!

On a final note, "Instructables" is one of the worst places to look for advice. Most of the people who post there don't know what they are doing, and mislead many others with their mistakes -- often leading to damaged equipment.

Never power servos from the Arduino 5V rail, its highly unlikely to work and may cause
damage. Separate power for motors and microcontrollers is the rule.

addesign:
http://www.instructables.com/id/Gyro-Stabilizer-W-Arduino-and-Servo/

That site reckons:
"MPU -> Arduino
VCC -> 5V (this powers the rail and hence the whole system including the servos)"

That info above is misleading. It says Arduino, and then it immediately refers to Vcc of 5V. This sort of indicates that they're saying the arduino's Vcc 'rail' powers everything, including the servos.

If that's what they're reallying saying, then it is just wrong.

To get things working reliably, two power supplies should be involved ....ie. power the arduino with power supply #1. And power the servos with power supply #2.

Well that's instructables for you. Much of the stuff there is bad practice from people who don't
really understand what they are doing - there is no curator sorting the wheat from the chaff.

Thank you for all your answers
It is good to know how reliable is instructables, I'll keep it in mind

I now have this mounting :

The calibration phase works good (the two servos are rotating to detect available space)
But the gyro compensation phase has only worked once

I'm a bit confused about this :
First, I read that the MPU-6050 has an integrated regulator and can be connecter to whether 3.3 or 5V
On some forums, I read that it has to be connected to the 3.3V exclusively

The fact that the gyro function has only worked once had me to think that the MPU is damaged, could it be due to the 5V supply ?

The MPU6050 is a 3.3 V device, and will quickly be destroyed if exposed to 5V, either via the power supply or via the I/O connections.

Some modules containing the 6050 are 5V compatible and have built in regulators and level shifters, others aren't.

You didn't say what you have, but I would not be surprised if the module has been destroyed -- another bonus from the "Instructables" crowd?

Yep, seems so
But it's mainly my fault, I was aware of my doubt and kept on 5v..

Well, I should receive a new one for a couple of € by the end of the week

I'll use this time to focus on the basics as you advised me

I'll keep you informed of my advancement

Thank you very much again for taking the time to answer my stupid questions

Sorry you are having so much trouble, but again there are lots of pitfalls for a beginner and an advanced project like this.

Stick with it and don't hesitate to post more questions. It will be fun when it finally works!