Self balancing robot


It’s really been a very long time since I added this on my todo list, and in the past couple of week-ends I finally found the time to do it.

And for once, I managed to avoid over-designing it, and produce something that actually works and is fun to play with, even though it lacks features… the proof is that my 2years old son did enjoy playing with it for several minutes ! 🙂

I initially wanted to “tune” one of his remote controlled cars, but I didn’t want to break the poor toy for nothing, so I started designing a 3D printable chassis.

Various 3D printed parts

Various 3D printed parts

I re-used 2 Meccano wheels so I needed 2 big gears for them, one adapter from the motor shaft to the same format of gear and finally some sort of simple body that would hold the motor in the right position.

Body and wheels

Body and wheels

For housing the electronics, including the battery (I used a small and nice 850mAh 2 cell LiPo that I had lying around), the easiest choice was to use a simple plastic box. This later proved to be quite a good idea, as I find it gives a cute look to the robot…

The box containing all the electronics

The box containing all the electronics

As for the electronics choices, it went for the easiest route:

  • most importantly, I used one of these really cheap and really powerful 6DOF IMUs : MPU6050
  • for the brains I used an Arduino Nano clone that I had lying around (which is partially broken as the USB doesn’t work, but it doesn’t matter I program it using the ISP header directly)
  • a L293D motor controller (really one of the worst out there, but I don’t need much more). Here is a very useful documentation link
  • a L7805CV voltage regulator (it turned out that the one on the Arduino is not powerful enough for the MCU, the IMU and the motor controller logic)
  • a most basic electrolytic 100uF capacitor on the line from the battery, to smooth out any eventual noise

On the software side, the only (but really important) 3rd party library I had to use was MPU6050_6Axis_MotionApps20.h (the power of Arduino is really in all these libraries freely available… if you can get hold of any device connectable to an Arduino, you can be sure somebody has already written a library for it ! 🙂 )

And here’s the code:


____________ Main file SelfBalancingRobot.ino ___________

#include "BButil.h"

#define MOTOR_ENABLE_PIN 3
#define MOTOR_DIRA_PIN 4
#define MOTOR_DIRB_PIN 5
#define LED_PIN 13

// angle is in radians
// gyro is in radians per sec, doesn't normally go beyond 1000
// the 2 have opposite signs
AngleGyroData _angleData = {0, 0};

float _initAngle;

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

	mpu_setup();

	pinMode(MOTOR_ENABLE_PIN, OUTPUT);
	pinMode(MOTOR_DIRA_PIN, OUTPUT);
	pinMode(MOTOR_DIRB_PIN, OUTPUT);
	pinMode(LED_PIN, OUTPUT);

	// configure the initial angle, which is assumed to be the "stable" position
	delay(1000);
	while(mpu_getData(&_angleData));//wait to get valid data
	_initAngle = _angleData.angle;
}

long currentTime, lastTime = 0;
float integralErr = 0, INTEGRAL_ERR_MAX = 10, actualAngle, ANGLE_OFFSET = 0.035;

void loop(){
	currentTime = millis();

	if(currentTime - lastTime > 1){
		// get the MPU data if available
		int8_t res = mpu_getData(&_angleData);

		// if res != 0 the data is not yet ready or there were errors, so ignore and keep trying
		if(res == 0){
			actualAngle = _angleData.angle - ANGLE_OFFSET;

			// 1. update the speed, apply PID algo (for the D, we don't need to do it manually as the sensor already gives us the gyro value which is the derivative of the angle)
			int16_t speed = 1200 * actualAngle + 90 * integralErr - 1.5 * _angleData.gyro;
			//if(speed > -50 && speed < 50) speed = 0;
			speed = constrain(speed, -255, 255);
			analogWrite(MOTOR_ENABLE_PIN, map(abs(speed), 0, 255, 50, 255));
			//analogWrite(MOTOR_ENABLE_PIN, abs(speed));
			integralErr = constrain(integralErr + actualAngle, -INTEGRAL_ERR_MAX, INTEGRAL_ERR_MAX);

			// 2. figure out which DIRECTION to go
			if(speed > 0){
				digitalWrite(MOTOR_DIRA_PIN, HIGH);
				digitalWrite(MOTOR_DIRB_PIN, LOW);

				digitalWrite(LED_PIN, LOW);
			}else{
				digitalWrite(MOTOR_DIRA_PIN, LOW);
				digitalWrite(MOTOR_DIRB_PIN, HIGH);

				digitalWrite(LED_PIN, HIGH);
			}
	//Serial.print(_angleData.angle); Serial.print(" / "); Serial.print(_angleData.gyro); Serial.print(" @ "); Serial.println(speed);

			// 3. keep track of the timings so that we do the update at regular intervals
			lastTime = currentTime;
		}
	}
}

____________ Tiny wrapper around the IMU library   MPU6050.ino ___________

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation is used in I2Cdev.h
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
// AD0 high = 0x69 This is the ONLY way I can make my cheap banggood.com board work, wile also connectiong AD0 to VCC
MPU6050 mpu(0x69);

/* Connect VCC, GND, SDA, SCL and the MPU-6050's INT pin to Arduino's external interrupt #0.
   On the Arduino Uno and Mega 2560, this is digital I/O pin 2. */

// MPU control/status vars
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint8_t fifoBuffer[64];          // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container

VectorFloat gravity;    // [x, y, z]            gravity vector
float yawPitchRoll[3];  // [z, y, x]   yaw/pitch/roll container
int16_t gyros[3];      // [x, y, z] gyros container

bool mpu_setup() {
    Wire.begin(); // join I2C bus (I2Cdev library doesn't do this automatically)

    Serial.print(F("Init I2C "));
    mpu.initialize();

    Serial.print(F("ID")); Serial.println(mpu.getDeviceID());

    // verify connection
    Serial.println(F("Test conns"));
    Serial.println(mpu.testConnection() ? F("Conn success") : F("Conn failed"));

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

    // 0 = success, !0 = error
    if (devStatus == 0) {
        Serial.println(F("Enable DMP"));
        mpu.setDMPEnabled(true);

        // get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("Set INTrrpts"));

        return true;
    } 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 ERR ")); Serial.println(devStatus);

        return false;
    }
}

int8_t mpu_getData(AngleGyroData* data){
    uint8_t mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count (all bytes currently in the FIFO)
    uint16_t fifoCount = mpu.getFIFOCount();

    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount >= 1024) {
        mpu.resetFIFO(); // reset so we can continue cleanly
        return -1; //FIFO overflow
    // otherwise, check for DMP data ready interrupt (this should happen frequently)
    } else if (mpuIntStatus & 0x02) {
        if (fifoCount >= packetSize) {
          // read 1st packet from FIFO, don't bother with the rest
          mpu.getFIFOBytes(fifoBuffer, packetSize);
          mpu.resetFIFO(); // reset so we can continue cleanly
        }

        // in case there were plenty of packets in the FIFO, only transform the last one, to avoid wasting CPU for nothing
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(yawPitchRoll, &q, &gravity);
        mpu.dmpGetGyro(gyros, fifoBuffer);

        // all we care is the Y axis data
        data->angle = yawPitchRoll[1];
        data->gyro =  gyros[1];

        return 0; // all good
    }else {
      return -2; //Wrong Status
    }
}

// The temperature sensor is -40 to +85 degrees Celsius.
// It is a signed integer.
// According to the datasheet: 340 per degrees Celsius, -512 at 35 degrees.
// At 0 degrees: -512 - (340 * 35) = -12412
int8_t mpu_getTemp(){
  return (mpu.getTemperature() + 12412.0) / 340.0;
}

____________ Small utility struct  BButil.h ____________________________

#ifndef BBUTIL_h
#define BBUTIL_h

#include <Arduino.h>

struct AngleGyroData {
    float angle;
    int16_t gyro;
};

#endif

And the SCHEMATIC as several people have asked for it:

Basic Schematic

Basic Schematic

150 Responses to Self balancing robot

  1. Pingback: Self Balancing Robot – V4 | Robotics / Electronics / Physical Computing

  2. Ian says:

    Hi trandi,
    Can you give an example of output value of “angleData.angle” and “angleData.gyro”
    Thank you …

  3. ahmpaul says:

    Good day trandi … if the sensor turn into 15 degrees .. What is the ouput value of “_angleData.angle AND _angleData.gyro” ? thank You ..

    • trandi says:

      .angle should be 15degs in radians divided by 1000 (I think haven’t looked at the code for a while).
      Your question is meaningless for .gyro, as the gyroscope measures the speed at which the angle changes….

  4. Danny says:

    Hi trandi, is data ->gyro =data[1]; value already divided by its corresponding lsb/dps or not?

    • trandi says:

      Can’t remember exactly but I think it’s already divided by 1000 or something equally random, just to reduce the variable size….
      It doesn’t really matter as you compensate in the PID coeficients, which you scale accordigly….

  5. Che says:

    Hi trandi,
    when did the value res == 0 happen?
    in this code,
    unt8_t res =mpu_getData(&_angleData);

  6. Che says:

    hi trandi, are you putting the the *data at int8_t mpu_getData(AngleGyroData* data) to AngleGyroData _angleData
    without typing
    data = &_angleData;
    ?

  7. Che says:

    hi trandi, i would like to ask where/how did you get the values(1900, 90,-1.5) in pid algorithm for the speed.

  8. Good Day Trandi .. Can you Give me a link for Formula for the PID ?? Thank you ..
    zexuzahmpaul22@gmail.com

    • trandi says:

      Hi, there’s really no formula beyond the code that’s on the post…

      • John Paul says:

        Thank you .. Why did you subtract the Derivative value ?

      • John Paul says:

        Why did you Subtract the Derivative value ?

      • trandi says:

        The gyros are configured such that if the derivative term is positive it means the robot is going towards the set point or where we want it to be, so need to diminish the PID number such that we do not overshoot.
        Example: the P is +5 (for example you’re 5 degrees to the right) and the D is +100. The way the accelerometre/gyros are set up is that it means that the robot is actually moving towards REDUCING the 5 degrees, so we can lower the overall PID value such that we don’t overshoot.

      • JohnPaul says:

        Thank you …

      • John Paul says:

        Hi .. Trandi can you explain this code “int8_t mpu_getData(AngleGyroData* data)”
        and
        “int8_t res = mpu_getData(&_angleData)” How does it work ?
        Sorry if i can’t understand ..

        Thank you..

      • trandi says:

        AngleGyroData is a struct (like an object but just with data, no methods on it). The mpu_getData() function takes a reference / pointer to that struct and populates it with the required data. The “res” is just to confirm if the data has been populated properly.

        It’s pretty much standard C, I’m not sure what your background is ?

        Dan

        On 20 October 2016 at 13:02, Robotics / Electronics / Physical Computing wrote:

        >

      • John says:

        Dan, What is the meaning of this code “data->angle = yawPitchRoll[1];

        data->gyro = gyros[1]; .. I’m trying to Study your Code .. I’m just a beginner for programming ..
        Thank You ..

      • trandi says:

        The MPU not only provides raw acceleration / gyros, but what’s really neat is that it does some very complex calculations (integration, filtering, etc. …) and provides the angles directly (“yawPitchRoll”).
        Also it provides everything on all the 3 axis, whereas I only need 1, and hence the data->angle and data->gyro which contain 2 numbers, the angle and gyro on 1 axis only !

        Hope this helps.
        Dan

        P.S. what are you studying the code for ?

  9. Alex Stavin says:

    Hey, do you still have the software for this? I’ve watched a recent tutorial from EEEnthusiast (Arduino Gyroscope MPU-6050 Tutorial) and wanted to build a quadcopter by combining your idea and his tutorial.

    Thanks,
    Alex

  10. Junjie Raga says:

    Thanks sir, works like a charm now… but i need more torque on my motor I’m planning to use a geared motor. but for now it’s perfectly working I just have to put more weight at the bottom part to assist the motor for balance. I just cant put weights on top since the motor cant compensate due to lack of torque. any suggestions for gear ratio’s for a geared motor?

    I’m so thankful for guys like you who help guys like me. have a nice day!

  11. Junjie Raga says:

    I uploaded the codes(I compiled prior everything is fine but I get this error on the serial monitor.( I’m using LB11847 motor driver) my motors are not responding also.

    Init I2C ID0
    Test conns
    Conn failed
    Init DMP
    DMP ERR 1

    • trandi says:

      Your problem has probably to do with the ADDRESS used on the I2C bus.
      If you look at the code you’ll find this:

      // class default I2C address is 0x68
      // specific I2C addresses may be passed as a parameter here
      // AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
      // AD0 high = 0x69 This is the ONLY way I can make my cheap banggood.com board work, wile also connectiong AD0 to VCC
      MPU6050 mpu(0x69);

      I’m using 0x69 because I’ve wired the AD0 pin HIGH, but by default it comes unwired.

      Dan

      • Junjie Raga says:

        yup, got it, mine is an InvenSense 0x68 – the motor is running now I’m yet to tune it to balance properly, however I’m using two motors. can you give me a hint for the codes, i would really appreciate it.. I’m newbie..

        I’m using a motor Driver Shield on top of my Arduino Uno r3

      • trandi says:

        Just wire the motors such that they appear as one. No point in changing the code to deal with 2 motors until you’re able to balance with one… On 11 May 2016 12:57, “Robotics / Electronics / Physical Computing” wrote:

        >

      • Junjie Raga says:

        Motors spins only in one direction. as I tilt the mpu back and forward.

  12. Pingback: Self Balancing Robot – V2 | Robotics / Electronics / Physical Computing

  13. Prime says:

    Hi trandi.

    Thank you for sharing your code. It really helped us. We made the same project and our robot balanced pretty fine. However, i like to know more about the library you used, bbutil.h, what is it’s significance and how it work.

    Looking forward to hearing your reply.

    • trandi says:

      Hi Steve,

      If you look at the code in the post, there are actually 3 files, separated by a long “______” (sorry, was to lazy to create 3 separate code tags 🙂 ).
      You’ll notice at the end the below:

      ____________ Small utility struct BButil.h ____________________________

      #ifndef BBUTIL_h
      #define BBUTIL_h

      #include

      struct AngleGyroData {
      float angle;
      int16_t gyro;
      };

      #endif

      That’s it, “bbutil.h” is just a tiny little struct that I use the share data.

      Happy to hear that you found my post useful, feel free to post a picture of your own robot, I’d be curious to see how it looks/works…

      Dan

    • Steve says:

      Hi trandi, can you send me an email at primaiansteve@gmail.com, I would like to ask more about the code if that’s okey with you. 🙂

  14. dayle says:

    hi can you please help me. i compile the 3 files into one directory and yet it it doesnt work

    SelfBalancingRobot.ino:3:20: error: BButil.h: No such file or directory
    SelfBalancingRobot:17: error: ‘AngleGyroData’ was not declared in this scope
    SelfBalancingRobot:17: error: ‘data’ was not declared in this scope
    SelfBalancingRobot:13: error: ‘AngleGyroData’ does not name a type
    SelfBalancingRobot.ino: In function ‘void setup()’:
    SelfBalancingRobot:29: error: ‘_angleData’ was not declared in this scope
    SelfBalancingRobot:29: error: ‘mpu_getData’ cannot be used as a function
    SelfBalancingRobot:30: error: ‘_angleData’ was not declared in this scope
    SelfBalancingRobot.ino: In function ‘void loop()’:
    SelfBalancingRobot:41: error: ‘_angleData’ was not declared in this scope
    SelfBalancingRobot:41: error: ‘mpu_getData’ cannot be used as a function
    MPU6050.ino: In function ‘int8_t mpu_getData(AngleGyroData*)’:
    MPU6050:64: error: ‘int8_t mpu_getData(AngleGyroData*)’ redeclared as different kind of symbol
    SelfBalancingRobot:17: error: previous declaration of ‘int8_t mpu_getData’

    • trandi says:

      the first line of your error “BButil.h: No such file or directory” shows that is does NOT find a file called BButil.h in the current directory (where the main .ino is).
      So what do you mean by “i compile the 3 files into one directory and yet it it doesnt work” ???
      Can you provide the exact structure of the files and how you organised them ?

      Dan

  15. Ben says:

    Hi Dan,

    Nice blog and cool project. Can you give any specs on the motor you used? I’m using a RadioShack 3V DC motor and experiencing something similar to what Frank was describing: when approaching high tilt angles the arduino freezes, the motor locks in at max speed and serial monitor stops transmitting.

    I’m about at my wit’s end troubleshooting, I’ve placed capacitors (to ground) on both the high and 5V sides of the voltage regulator, powered the motor and sensors separately with the Nano powered by USB, placed LEDs in place of the motor (without any freezing, so it does seem to be noise generated by the motor causing the problem), stacked L293Ds three high and built an H bridge from 2N2222s (I’m considring building a 2N2222, TIP120/125s Darlington Pair H bridge just to get some satisfaction over this motor) but all this has led me to conclude I need a less noisy motor. If you have one you can suggest it would be appreciated.

    Thanks a lot.

    • trandi says:

      Hi Ben, thank you and sorry to hear you’re having issues, believe me I know how frustrating it can be…
      I can’t tell you exactly what motor I used as it was simply salvaged from a printer….BUT I can confirm it’s easily twice as big as yours AND I run it at 8V, so it packs much more punch than yours….
      So all I can recommend is to get a bigger motor, and/or use more voltage…

      Hope this helps,
      Dan

  16. Very cool project, thanks to your post. We try to improve your robot by using two DC motors and controlled by android phone. This is the video https://www.youtube.com/watch?v=-eFD635sEn8

  17. Very cool project, thanks to your post. We try to improve your robot by using two dc motors and controlled by android phone.This is the video https://www.youtube.com/watch?v=-eFD635sEn8

  18. lester says:

    Very cool project, thanks to your post Trandi. We try to improve your robot by using two DC motors and controlled by android phone.
    This is the video https://www.youtube.com/watch?v=-eFD635sEn8

  19. Davide says:

    Hi trandi, I’ve just remake your very cool project!! Ok, it’s a little ugly but it works! Soon I’ll wanna improve it! (especially the look)… I made a video 😉 https://www.youtube.com/watch?v=9P3X7iagU2E&feature=youtu.be

    • trandi says:

      Hi Davide,
      Thank you for sharing, that looks nice !
      I’m glad that my project was of use…

      Dan

      P.S. slightly scary they way you connect the LiPo, you do know of course that if you short its leads you’ll probably have a nice flame/fire… 🙂

      • Davide says:

        I know, you’re about lipo…. 😀 listen.. I’ve got a problem: basically if I keep lipo in my hand the robot stands up well balanced, but if I put battery on it fall down.. in my opinion the motor has enough power to keep up balanced the robot and the lipo too.. the problem is the H bridge, I use (as you tell in your project) the l293d which can handle about 1-1.5 amps (it’s right?) so it’s not enough.. the result is that the robot falls down because motor doesn’t have enough current to stand up.. can you suggest me a more powerful H bridge? Maybe a 4-5 amps H bridge can be fine.. thank you trandi 😉

  20. john says:

    Hi trandi, ive tried your code and the i2c is a success but then it says set INTrrpts, what do I need to do thank you
    john

  21. Huu Phuoc says:

    Hi! I am doing this project, my robot can move but I have a problem: when I put something on robot, it’s not still balancing. I read your code and I think we use PID controller but I can’t do like you. Can you help me?

    • trandi says:

      Hi,
      Glad you find my post useful.
      There’s not much I can do with so little information, and even with more details fine tuning the PID can’t really be done remotely.
      IF the robot balances with nothing on it, that already a very good sign ! Check on the Internet guides on how to tune a PID controller, and also double check that your motor is powerful / fast enough…

      • Huu Phuoc says:

        Yep! May be I have not used PID Autotune Library and my motor is not realy fast (280RPM). I will improve it. Thanks a lot :D.

  22. Andreas Meerkamp says:

    I tried your code and it works but I have a problem with the speed in your code which says:

    int16_t speed = 1200 * actualAngle + 90 * integralErr – 1.5 * _angleData.gyro;

    My sensor readings are:

    0 degree, actualAngle 0.00, integralErr around 5 to 10, gyro close to 0
    5 degree, actualAngle 0.09, integralErr around 5 to 10, gyro close to 0
    10 degree, actualAngle 0.18, integralErr around 5 to 10, gyro close to 0

    So this integralErr always causes high speed values. If I change your code like this

    int16_t speed = 1200 * actualAngle

    I get it somewhat balancing but not stable. Any suggestions for that?

    Thanks for sharing your code, regards from Munich, Germany,
    Andreas

    • trandi says:

      You can ignore the integralErr, but you HAVE to use the _angleData.gyro, which is basically the derivative of the angle (the “D” in the PID) and is the most important for good stability. If the numbers from your sensor don’t match mine (quite possible, even with the same sensor, if it’s configured differently), just tweak the constant (1.5 in this case) by increasing or decreasing it.

      Dan

      On 29 December 2014 at 12:31, Robotics / Electronics / Physical Computing wrote:

      >

  23. Arnaud C Silveira says:

    Hi my friends , i live in Brazil i have problems with code ,you have a complet code?
    Thank´s

    • trandi says:

      Hi Arnaud, all the code that you need is in the above post, people have already successfully used it.
      As I’ve already mentioned in one of the above replies, be aware that there are SEVERAL FILES in there, all separated by “____________ name of the file __________”.

      Hope this helps,
      Dan

  24. Jack Davis says:

    I ran across this site 3 or 4 days ago and thought that was a very cool project. I put one together with a piece of plexi, an Arduino, and an old robot gear motor set. Works like a champ. Thank you for all your hard work and for willing to share it with us.
    Jack

  25. Al B says:

    Very cool! Thanks for sharing. We built a similar project. However, we installed an Android device on the robot to control its balance. Here you can see the result:

    • trandi says:

      Wow, nice… very well executed your robot !
      Mine looks more hacky and lower level, I’m now working on the V2, still with arduino and MSP6050, but improved motors and control from an Android phone too ! 🙂

      For now I’m struggling with controlling brush-less motors in an appropriate way…

      Also I like that you use a IOIO board, I’m a fan of this board too (as you can see from my several posts on this blog referring to it) and I also know Ytai their creator, who is a really great guy !

      Thanks for sharing,
      Dan

  26. seol says:

    Hello. trandi.
    I am thankful for your project and open source. *^.^*
    But. I am getting this error.
    sketch_aug26a.ino:1:20: fatal error: BButil.h: No such file or directory compilation terminated.
    I used UNO + MPU6050
    What id BButil.h?
    Where can i find BButil.h?
    Can you send to me if you have?

    • trandi says:

      It’s right there in the post. The section with the code contains actually 3 files, separated by “____________” … search for this and you’ll see there each bit in which file has to go (all in the same directory).

      Dan

      • seol says:

        I thank for fast your response.
        It is that I cannot understand your source one. ^^
        I committed the mistake seeing the whole as one program..
        I am once agine thankful for kind your answer.

  27. mantaj says:

    i am new in ardino working on ardino uno with m6050. but your code is not working please send me the correct code for it

  28. Oz says:

    Hi trandi,
    first of all, thank you for sharing your project. This is a very nice small self balancing robot.
    I have a question your code, do you think you have a typo on this line?

    if (fifoCount >= packetSize && fifoCount >= packetSize) { …

    Did you mean to have this instead? if (fifoCount >= packetSize) { …

    thank you again for sharing this nice project.

  29. angga says:

    could not if using arduino uno?

  30. Arunava Das says:

    I get this error…..please help me out.. 😦

    In file included from SelfBalancingRobot.ino:1:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h: In member function ‘float Quaternion::getMagnitude()’:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:74: error: ‘sqrt’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h: At global scope:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:94: error: ‘int16_t’ does not name a type
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:95: error: ‘int16_t’ does not name a type
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:96: error: ‘int16_t’ does not name a type
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:104: error: expected `)’ before ‘nx’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h: In constructor ‘VectorInt16::VectorInt16()’:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:99: error: ‘x’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:100: error: ‘y’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:101: error: ‘z’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h: In member function ‘float VectorInt16::getMagnitude()’:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:111: error: ‘x’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:111: error: ‘y’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:111: error: ‘z’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:111: error: ‘sqrt’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h: In member function ‘void VectorInt16::normalize()’:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:116: error: ‘x’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:117: error: ‘y’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:118: error: ‘z’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h: In member function ‘VectorInt16 VectorInt16::getNormalized()’:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:122: error: ‘x’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:122: error: ‘y’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:122: error: ‘z’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h: In member function ‘void VectorInt16::rotate(Quaternion*)’:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:138: error: ‘x’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:138: error: ‘y’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:138: error: ‘z’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h: In member function ‘VectorInt16 VectorInt16::getRotated(Quaternion*)’:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:153: error: ‘x’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:153: error: ‘y’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:153: error: ‘z’ was not declared in this scope
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h: In member function ‘float VectorFloat::getMagnitude()’:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/helper_3dmath.h:178: error: ‘sqrt’ was not declared in this scope
    In file included from SelfBalancingRobot.ino:3:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h: At global scope:
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:325: error: no ‘uint8_t MPU6050::dmpInitialize()’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:550: error: no ‘bool MPU6050::dmpPacketAvailable()’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:577: error: no ‘uint8_t MPU6050::dmpGetAccel(int32_t*, const uint8_t*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:585: error: no ‘uint8_t MPU6050::dmpGetAccel(int16_t*, const uint8_t*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:593: error: no ‘uint8_t MPU6050::dmpGetAccel(VectorInt16*, const uint8_t*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:601: error: no ‘uint8_t MPU6050::dmpGetQuaternion(int32_t*, const uint8_t*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:610: error: no ‘uint8_t MPU6050::dmpGetQuaternion(int16_t*, const uint8_t*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:619: error: no ‘uint8_t MPU6050::dmpGetQuaternion(Quaternion*, const uint8_t*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:634: error: no ‘uint8_t MPU6050::dmpGetGyro(int32_t*, const uint8_t*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:642: error: no ‘uint8_t MPU6050::dmpGetGyro(int16_t*, const uint8_t*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:652: error: no ‘uint8_t MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:660: error: no ‘uint8_t MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:672: error: no ‘uint8_t MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:683: error: no ‘uint8_t MPU6050::dmpGetEuler(float*, Quaternion*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:689: error: no ‘uint8_t MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:702: error: no ‘uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:712: error: no ‘uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t, uint8_t*)’ member function declared in class ‘MPU6050’
    C:\Users\Arunava\Documents\Arduino\libraries\MPU6050/MPU6050_6Axis_MotionApps20.h:737: error: no ‘uint16_t MPU6050::dmpGetFIFOPacketSize()’ member function declared in class ‘MPU6050’
    MPU6050.ino: In function ‘bool mpu_setup()’:
    MPU6050:40: error: ‘class MPU6050’ has no member named ‘dmpInitialize’
    MPU6050:48: error: ‘class MPU6050’ has no member named ‘dmpGetFIFOPacketSize’
    MPU6050.ino: In function ‘int8_t mpu_getData(AngleGyroData*)’:
    MPU6050:83: error: ‘class MPU6050’ has no member named ‘dmpGetQuaternion’
    MPU6050:84: error: ‘class MPU6050’ has no member named ‘dmpGetQuaternion’
    MPU6050:85: error: ‘class MPU6050’ has no member named ‘dmpGetGravity’
    MPU6050:86: error: ‘class MPU6050’ has no member named ‘dmpGetYawPitchRoll’
    MPU6050:87: error: ‘class MPU6050’ has no member named ‘dmpGetGyro’

    • trandi says:

      Sorry this probably has more to do with the MPU6050 library itself, maybe check on their forum…

      Dan

      • Arunava Das says:

        Finally the code compiled…. 🙂 🙂 Thanks for d tutorial 🙂 By mistake I copied the MSP430’s I@C dev library instead of Arduino’s…will post u d video when my bot is complete 🙂

      • trandi says:

        Great, glad to hear that, I can’t wait to see your video !

        On 11 May 2014 22:29, Robotics / Electronics / Physical Computing wrote:

        >

      • tayyab says:

        hi , my project is “2 wheeled self balancing robot” i m searching forward , backward movement code by using mpu6050 sensor and arduino as a controller. please help me to search out this example code.

    • tayyab says:

      hi , i have also same errors 😦 can you please tell me how to remove it .
      you tells about same kind of tutorial ? please share it to me .

  31. Max says:

    hello trandi,

    I have used your code on my SBR. Problem is now bot moves backward and forward rapidly without balancing. I tried to adjust few parameters but didn’t help. Could you please guide me how to stabilize ie adjust the parameters. To be honest I have not understood how you have implemented PID.

    Hope you will find sometime to reply, Thanks in advance.

    VU2IIA

    • trandi says:

      It’s hard to say for sure without seeing the exact behaviour / setup, BUT it looks like you have the forward / reverse inversed.
      You have several options:
      – change the wiring of your motor
      – change the position of the IMU by 180deg around the z axis
      – change the code. In the following lines ”
      // 2. figure out which DIRECTION to go
      if(speed > 0){” replace with “speed < 0" which would have the exact same effect as wiring your motor the other way around.

      Hope this helps,
      Dan

      • Max says:

        After modifying code slightly to suit my HW , I tired to do some fine tunning. I adjusted “1200” and ” 90″ in your original code to 2000 and 10 respectively. It made some difference. Can you please look at the video/photo and suggest changes required.

        https://www.dropbox.com/sh/5x93e7szyuwltwi/zuhzFP3s8K

        I am bit confused because as there is an overlapping area where its difficult to understand whether problem lies in s/w PID adjustment or hardware efficiency like motor torque, height, weight etc. I am using plastic DC motors 300rpm/ 6v type, which suffers from back slash and I hope its not the culprit. i am not using bluetooth to avoid timing issues, but just to upload sketch.

        Hope you will find time to reply, Thanks in advance.

        VU2IIA

      • trandi says:

        Hi Max,

        I’ve finally had some time to look at your pictures/video… nice little robot, I like the aluminium frame.

        From what I can see in the video, the setup and wiring looks all right, and the motors fast and powerful enough, I think it’s simply a matter of fine tuning the PID.

        It “feels” that the D coefficient is too big, as the robot feels to “aggressive” in correcting its position. If you google “tuning PID” you’ll find advice on how to do it. One idea is to turn the I and D coefficients to 0, and play with P until you get the best result. THEN play with D to improve on that. THen I, which I think is less important is this concrete application.

        Hope this helps, Dan

        On 6 May 2014 09:03, Robotics / Electronics / Physical Computing wrote:

        >

  32. Prabodh says:

    hii i am getting this error
    can u please help me

    “In file included from balance.cpp:1:0:
    /home/chinna/sketchbook/libraries/BButil_h/BButil.h:20:21: fatal error: EGL/egl.h: No such file or directory
    compilation terminated.”

    • trandi says:

      Hi,

      Sorry I don’t know what you do in your balance.cpp or what EGL is, so can’t really help.

      Dan

      • seol says:

        Hello. trandi.
        I am thankful for your project and open source. *^.^*
        But. I am getting this error.
        sketch_aug26a.ino:1:20: fatal error: BButil.h: No such file or directory compilation terminated.
        I used UNO + MPU6050
        What id BButil.h?
        Where can i find BButil.h?
        Can you send to me if you have?

      • Muhamad Andi says:

        Hi trandi, i get same error

        /home/chinna/sketchbook/libraries/BButil_h/BButil.h:20:21: fatal error: EGL/egl.h: No such file or directory
        compilation terminated.”

        where is BButil.h library? please help..

      • trandi says:

        BBUtil.h is one of the 3 files that you have in the code I posted. There are 3, not 1 files in there, you’ll see them separated by “——-“.
        Hope this helps.
        Dan

      • Muhamad Andi says:

        thanks for fast repon, yes I’ve seen there are three pieces of code there .. and how to make it 3 pieces of code into hex file? I try to compile bbutil with arduino to appear hex file, but still the error …

      • trandi says:

        You just put the 3 files (2 named “.ino” and one “.h”) in the same directory named the same as the main file (Arduino standard) you open the “main file” in Arduino IDE, and burn that to your board. The Arduino IDE will deal with .hex files and the rest, you don’t need to care.

        It’s the typical Arduino project with more than 1 files. The fact that 1 out of 3, is “.h” rather than “.ino” doesn’t change anything…

        Dan

        On 1 February 2015 at 12:24, Robotics / Electronics / Physical Computing wrote:

        >

      • 182admin says:

        hello friend, I’ve tried to unify the 3 files into one folder like this screenshot (http://prntscr.com/60n5cc).

        and has added a library I2Cdev.h and MPU6050 like this screenshot (http://prntscr.com/60n5dc) … but why when I compile it with arduino IDE is an error message like this:

        Mainfile.ino: 6: 20: error: ‘AngleGyroData’ was not declared in this scope
        Mainfile.ino: 6: 35: error: ‘data’ was not declared in this scope
        Mainfile.ino: 7: 1: error: expected unqualified-id before ‘else’
        Mainfile.ino: 1: 1: error: ‘____________’ does not name a type
        Mainfile.ino: 13: 1: error: ‘AngleGyroData’ does not name a type
        Mainfile.ino: In function ‘void setup ()’:
        Mainfile.ino: 29: 24: error: ‘_angleData’ was not declared in this scope
        Mainfile.ino: 29: 34: error: ‘mpu_getData’ can not be used as a function
        Mainfile.ino: 30: 18: error: ‘_angleData’ was not declared in this scope
        Mainfile.ino: In function ‘void loop ()’:
        Mainfile.ino: 41: 35: error: ‘_angleData’ was not declared in this scope
        Mainfile.ino: 41: 45: error: ‘mpu_getData’ can not be used as a function
        Mpu6050.ino: 1: 1: error: ‘___________’ was not declared in this scope
        Mpu6050.ino: 1: 13: error: expected ‘;’ before ‘Tiny’
        Mpu6050.ino: 107: 1: error: expected ‘}’ at end of input

        then I have to do? What should I fix it? please help …

      • trandi says:

        These errors “Mainfile.ino: 1: 1: error: ‘____________’ does not name a type” look dodgy… it seems that you’ve left the “___________ xxx __________” comments in the files and you shouldn’t…

        Dan

  33. guiraud says:

    Hi
    I ‘m a just a programmer beginner in arduino and when i compile, i have the message
    anglegyrodata not declared in scope?
    Can you give me a tip?
    Best regards
    Michel

    • trandi says:

      You need the BButil.h file in the same directory as the main one.
      Beware, in my code pasted in the post, there are 3 different files (one of which is this BBUtil) all of which have to be in he same directory.

      Hope this helps,
      Dan

  34. Frank B. says:

    I see something odd in my Arduino IDE. I have three tabs, one for the first part of the program called “balance”, the next tab is BBUtil.h, the last is MPU6050.ino file, but there is a ‘$’ looking symbol at the end of the tab name. Is that something?
    Frank

    • trandi says:

      Isn’t that simply when you haven’t saved your changes ? Press Ctrl + S and check. If it doesn’t disappear, then it’s not normal…

      dan

      On 24 March 2014 13:44, Robotics / Electronics / Physical Computing wrote:

      >

    • Frank B. says:

      so i went step by step and only when i connect the dc motor (with no load) the serial screen freezes.

      • trandi says:

        CAPACITOR problem ! Or alternatively your power source doesn’t have enough power…

        You haven’t answered my question if you had a capacitor to filter out the noise !? Also what power source exactly are you using ?

        On 24 March 2014 14:27, Robotics / Electronics / Physical Computing wrote:

        >

  35. Steve says:

    I am not sure if this helps…

    I had the same issue as frank.. Then I connected the interrupt signal from the gy521

    to my arduino..

    • trandi says:

      Thanks Steve!
      It’s true you need that for the sample MPU programs.
      In my program however, I poll the MPU in every loop and do NOT use interrupts.
      BUT, this makes me think that Frank you might have forgotten to connect pin 2 with pin 8 on the GY521 (as per the image here https://trandi.files.wordpress.com/2014/01/img071.jpg) which is mandatory.

      Dan

      • Frank says:

        Pin 2 is connected 8 on the GY521. All the individual components work separately. It is only when I connect to l293d to gy521 things fail.
        Thanks for all your help guys!
        Frank

    • Frank says:

      Steve what pin on the arduino did you hook up the INT from gy521?
      I wish I could post pictures.
      Thanks, Steve!

      • SteveH says:

        Frank,

        I have been tinkering with the stock code form
        i2cdevlib, where the interrupt is used.. so I thought maybe
        it needed to be used here..

        trandi’s code seems to not use interrupts as he indicated,
        so the INT pin of the gy521 doesnt need to be connected to the arduino.

        Looks like he did set the AD0 of the GY521 high
        , so the I2c address is 0x69, as he noted in his source code..

        So his schematic seems to match his drawing as far as the
        sensor is concerned…

        SteveH

      • SteveH says:

        If you isolate the l293d from the arduino can you get the motor to spin
        in each direction by changing the logical values of enable and direction pins ?

        Also where do you connect the Vmotor connection? That need to be something other
        than then outuut of the 5v regulator .. or the motor will most likely hog all the current and cause the arduino to reset itself lots.. and thing work work..

        trandi, where did you attach the l293 motor voltage to?

        SteveH

      • trandi says:

        Directly to the battery, BEFORE the regulator and the Arduino.
        Thanks Steve for coming with suggestions and helping Frank out.
        I’d really love to see other people able to replicate the little build… don’t forget to send my pictures or a link…:)

        Dan

  36. Frank B. says:

    Ok Dan,
    So here’s where I stand. If I wire everything up and start my serial monitor it freezes up and this is the data I get as the motor runs high speed:

    Init I2C IDInit I2C ID52
    Test conns
    Conn success
    Init DMP
    Enable DMP
    Set INTrrpts
    -0.08 / -1 @ -131
    -0.08 / -1 @ -141
    -0.08 / -1 @ -151
    -0.08 / -1 @ -161
    -0.08 / -1 @ -171
    -0.08 / -1 @ -181
    -0.08 / -1 @ -191
    -0.08 / -1 @ -201
    -0.08 / -1 @ -211
    0.00 / -1 @ -130
    -0.08 / -1 @ -224
    -0.08 / -1 @ -234
    -0.08 / -1 @ -244
    -0.08 / -515 @ 255
    -0.08 / -515 @ 255
    -0.08 / -1 @ -255
    -0.08 / -1 @ -255
    -0.08 / -1 @ -255
    -0.08 / -1029 @ 255
    -0.08 / -1029 @ 255 <-Data stops at this point and serial screen freezes.

    So if I disconnect L293D and run the program and move the GY-521 around this is what I get without the serial freezing and continuous good data:

    Init I2C ID52
    Test conns
    Conn success
    Init DMP
    Enable DMP
    Set INTrrpts
    -0.07 / 169 @ -255
    -0.11 / 168 @ -255
    -0.16 / 175 @ -255
    -0.20 / 191 @ -255
    -0.25 / 209 @ -255
    -0.31 / 226 @ -255
    -0.37 / 240 @ -255
    -0.43 / 248 @ -255
    -0.49 / 247 @ -255
    -0.56 / 235 @ -255
    -0.61 / 213 @ -255
    -0.67 / 186 @ -255
    -0.72 / 160 @ -255
    -0.76 / 139 @ -255
    -0.80 / 126 @ -255
    -0.84 / 115 @ -255
    -0.87 / 102 @ -255
    -0.90 / 87 @ -255
    -0.92 / 71 @ -255
    -0.94 / 57 @ -255
    -0.96 / 44 @ -255
    -0.97 / 37 @ -255
    -0.98 / 27 @ -255
    -0.98 / 7 @ -255
    -0.97 / -19 @ -255
    -0.95 / -44 @ -255
    -0.93 / -64 @ -255
    -0.91 / -70 @ -255
    -0.88 / -70 @ -255
    -0.86 / -73 @ -255
    -0.83 / -82 @ -255
    -0.80 / -96 @ -255
    -0.76 / -114 @ -255
    -0.73 / -133 @ -255
    -0.69 / -150 @ -255
    -0.64 / -165 @ -255
    -0.60 / -177 @ -255
    -0.55 / -192 @ -255
    -0.50 / -215 @ -255
    -0.44 / -234 @ -255
    -0.38 / -238 @ -255
    -0.33 / -229 @ -255
    -0.28 / -215 @ -255
    -0.23 / -201 @ -255
    -0.19 / -191 @ -255
    -0.15 / -184 @ -255
    -0.10 / -183 @ -255
    -0.06 / -184 @ -255
    -0.02 / -187 @ -255
    0.02 / -185 @ -255
    0.07 / -172 @ -255
    0.10 / -150 @ -255
    0.13 / -122 @ -255
    0.16 / -90 @ -255
    0.18 / -66 @ -255
    0.19 / -55 @ -255
    0.20 / -55 @ -255
    0.22 / -60 @ -255
    0.23 / -65 @ -255
    0.25 / -69 @ -255
    0.27 / -73 @ -255
    0.29 / -80 @ -255
    0.31 / -87 @ -255
    0.33 / -87 @ -223
    0.35 / -80 @ -183
    0.37 / -67 @ -153
    0.38 / -54 @ -125
    0.39 / -45 @ -92
    0.41 / -39 @ -56
    0.42 / -31 @ -22
    0.43 / -25 @ 13
    0.43 / -22 @ 53
    0.44 / -18 @ 93
    0.45 / -5 @ 117
    0.45 / 11 @ 134
    0.45 / 25 @ 150
    0.45 / 36 @ 168
    0.44 / 44 @ 187
    0.44 / 53 @ 204
    0.43 / 62 @ 217
    0.42 / 68 @ 232
    0.41 / 70 @ 252
    0.40 / 71 @ 255
    0.39 / 73 @ 255
    0.38 / 79 @ 255
    0.36 / 92 @ 255
    0.34 / 114 @ 255
    0.32 / 140 @ 227
    0.29 / 165 @ 179
    0.26 / 180 @ 138
    0.22 / 184 @ 106
    0.18 / 181 @ 81
    0.14 / 172 @ 63
    0.11 / 157 @ 52
    0.07 / 134 @ 53
    0.04 / 112 @ 54
    0.02 / 106 @ 31
    -0.01 / 115 @ -18
    -0.04 / 128 @ -80
    -0.08 / 136 @ -139
    -0.11 / 145 @ -205
    -0.15 / 161 @ -255
    -0.19 / 188 @ -255
    -0.24 / 216 @ -255
    -0.30 / 231 @ -255
    -0.35 / 230 @ -255
    -0.41 / 215 @ -255
    -0.46 / 193 @ -255
    -0.50 / 170 @ -255
    -0.55 / 147 @ -255
    -0.58 / 120 @ -255
    -0.61 / 92 @ -255
    -0.64 / 71 @ -255
    -0.66 / 56 @ -255
    -0.68 / 49 @ -255
    -0.70 / 50 @ -255
    -0.71 / 49 @ -255
    -0.72 / 37 @ -255
    -0.72 / 12 @ -255

    Question: Why is it as soon as I power up the L293D, I freeze up?

    I feel like I'm close or this just might be one big April Fools Day joke ;(

    Yep I saw your Donate Button…I promise will when I get this to work. Thanks for all your help.

    Frank B.
    Cleveland, Ohio

    • trandi says:

      Hi Frank,

      No worries, I know how frustrating it can be… it’s very hard to debug remotely like this, without even seeing your circuit directly… besides, with a 2nd baby that has only just arrived, it’s really hard to find even a few minutes free !

      It sounds like there’s a problem with the power source or the noise on the circuit. Have you added a capacitor on the power lines as per my schematic ? What do you use to power the circuit ? If the motors draw too much current or introduce too much noise on the circuit this could be the problem…

      Don’t give up, I’m sure you’ll eventually find the problem ! Dan

      P.S. don’t worry about the “donate” button, it’s been there forever and nobody has ever donated anything! I’m doing this for fun …

      On 22 March 2014 22:58, Robotics / Electronics / Physical Computing wrote:

      >

      • Frank B. says:

        Dan,
        I’m pretty sure it’s not a problem on the hardware end. So I thinking it might be Wire.h, I2Cdev.h, or MPU6050_6Axis_MotionApps20.h library. Do I have to tweak those files like “uncomment” certain lines so they work properly?
        Thanks,
        Frank

      • trandi says:

        How comes you’re so sure ? If the data you see is so different between having the motor driver connected or not, it seems to me that’s obviously hardware related !?

        I can’t remember if I did any modification to the libs you mention, but I don’t think so… In any case, you should be able to open one of the examples that come with the MP6050 lib and see if it works ok. This should confirm that the 3 of them work ok ! (also from the logs you sent me, I can see that the I2c bus seems to be working ok, so the WIre.h lib is definitely not the problem)

        Dan

        On 23 March 2014 15:57, Robotics / Electronics / Physical Computing wrote:

        >

      • Frank B. says:

        I ran the mp6050 test code.

        Initializing I2C devices…
        Testing device connections…
        MPU6050 connection successful

        Send any character to begin DMP programming and demo:
        Initializing DMP…
        Enabling DMP…
        Enabling interrupt detection (Arduino external interrupt 0)…
        DMP ready! Waiting for first interrupt…

        I move the board around and nothing happens. Does this got something too do with it?

      • trandi says:

        I would think so ! You should see data coming through… So MAYBE your MPU6050 has a problem. This still would NOT explain the difference in the serial output when you disconnect the motor driver. In my mind that can only be explained by a hardware different, NOT software.

        Where did you buy your MPU6050 from ?

        Dan

        On 23 March 2014 16:52, Robotics / Electronics / Physical Computing wrote:

        >

  37. freemaster says:

    it’s neat and easy to understand. good job bro. but there is a problem for me. what is BBUtil.h? and where can i get it? what’s in it anyway?

    • trandi says:

      Hi,

      Thanks.
      BBUtil.h is a C header file that simply contains the AngleGyroData struct.
      You can find it at the end of the source code in the post.
      That source code is actually composed of 3 files, so you copy/paste in them with the relevant names.
      The main Arduino sketch will import the BBUtil.h file and use the structure defined therein.

      Hope this helps, let me know if you build the same, I’d be curious to see it…
      Dan

    • Frank says:

      Just copy/paste the BBUTil.h code into a new tab in arduino IDE and name it BBUtil.h.

  38. for me the sensor does not give any data back…what to do?

    • trandi says:

      I don’t understand, can you please explain your problem ?

      • i am also facing the same problems as FRANK…i am getting something like this
        ” The motor just goes to its highest speed and continues to run. My serial data looks like this:

        Init I2C ID52
        Test conns
        Conn success
        Init DMP
        Enable DMP
        Set INTrrpts
        -0.10 / -1 @ -158
        -0.10 / -1 @ -169
        -0.10 / -1 @ -181
        -0.10 / -1 @ -193
        -0.10 / -1 @ -205
        -0.10 / -1 @ -217
        -0.10 / -1 @ -229
        -0.10 / -1 @ -241
        -0.10 / -1 @ -253
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        0.08 / 0 @ -146
        -0.10 / -1 @ -255 “

      • Frank B. says:

        If Mohnish Ramani and I face the same problem, then the solution must be simple. Is there anything you can think of that would cause this error? I just want this to work. I’m going insane.
        Thanks,
        Frank
        Cleveland, Ohio

      • trandi says:

        It may be that the orientation of the IMU is wrong.
        2 things then:
        – make sure the row of pins on the IMU is parallel with the wheels axis
        – then try BOTH having the row a the front or back of your robot

        If the 2nd bit is hard to do mechanically, you can simulate that by simply inverting the sign in the code here:


        // 2. figure out which DIRECTION to go
        if(speed > 0){

        replace with “(speed < 0)"

        I really hope this helps you guys, as I know how frustrating it can be !!
        Dan

  39. there is no reading done from the sensor…..what hav u done instead to deal with this???

  40. Vipin Mohan says:

    hey tank you 4 this post , i would realy like to do this as my mini project at college and could you pls upload a better schematic and + how to add the extra header files required for the program

    • trandi says:

      Sorry, don’t have time to sit down and create a better schematic, and besides the circuit is quite simply you should be able to replicate it with what you’ve got.
      All the required files are int here, you have to split the source code provided into the 3 relevant files!

      Dan

  41. Pingback: Self balancing robot | fablab | Scoop.it

  42. Frank says:

    Great Project!!! Amazing!!!
    Do you have any wiring schematics available? I would love to build this. I already have the Nano and the GY-521. I would be happy to even just have a scribble on a napkin 😉
    Thanks from Cleveland, Ohio,
    Frank

    • trandi says:

      Thanks.
      Done, I have scanned and added a basic schematic at the end of the post.

      Hope this helps, I’d be curious to see what you come up with…
      Dan

      • Frank says:

        Dan,
        I would first like to thank you for posting this project, it is an great adventure trying to get it to work. I am running into a problem i just can’t work out and I hope you can steer me in the right direction. Thank you for any help you can give me.
        Frank B.
        Cleveland, Ohio

        Here are the facts:

        1. I broke up the code into 3 separate parts and gave them each their own tabs in the Arduino IDE. My Library contains: BButil, I2Cdev, MPU6050, and i tried the set up with and without Wire. Wire seems to cause a problem when its in the library i get this error when it is in the library:

        /Users/Documents/Arduino/libraries/I2Cdev/I2Cdev.cpp: In static member function ‘static int8_t I2Cdev::readBytes(uint8_t, uint8_t, uint8_t, uint8_t*, uint16_t)’:
        /Users/Documents/Arduino/libraries/I2Cdev/I2Cdev.cpp:278: error: ‘class TwoWire’ has no member named ‘write’
        /Users/Documents/Arduino/libraries/I2Cdev/I2Cdev.cpp:284: error: ‘class TwoWire’ has no member named ‘read’

        2. When I connect MPU6050 by itself and run test code I get good data to my serial monitor.

        3. When I connect L293D by itself and run test code I can control a motor with no problems.

        4. It is when I connect everything together I have a problem. The motor just goes to its highest speed and continues to run. My serial data looks like this:

        Init I2C ID52
        Test conns
        Conn success
        Init DMP
        Enable DMP
        Set INTrrpts
        -0.10 / -1 @ -158
        -0.10 / -1 @ -169
        -0.10 / -1 @ -181
        -0.10 / -1 @ -193
        -0.10 / -1 @ -205
        -0.10 / -1 @ -217
        -0.10 / -1 @ -229
        -0.10 / -1 @ -241
        -0.10 / -1 @ -253
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        -0.10 / -1 @ -255
        0.08 / 0 @ -146
        -0.10 / -1 @ -255

      • trandi says:

        Hi Frank,

        2 things I can think of: – the BBUtil file has to have a “.h” extension (not “.ino” or anything else) – what version of Arduino are you using ? It might be that you’re using a too old one (i’m using 1.0.4)

        Dan

        On 9 February 2014 19:18, Robotics / Electronics / Physical Computing wrote:

        >

  43. Pingback: Auto-equilibrio Robots Wobble, pero no caen - | Noticias de seguridad informática, ¿qué es la seguridad informática?

  44. SuperEngine says:

    Hi trandi
    Nice MVP product ,can you post the schematic ?

  45. SuperEngine says:

    Hi trandi
    Nice MVP project, can you post the schematic ?

    • trandi says:

      Thank, no problem will post the basic connections diagram when I have time to scan it as it’s on a piece of paper right now..

  46. MarkS says:

    In case you’d like to add a kalman filter and integrate the gyro and accel sensor info.
    Here’s one for arduino too 🙂
    https://github.com/TKJElectronics/KalmanFilter

    • trandi says:

      That’s cool, BUT the fact that I don’t use an accelerometer and gyroscope directly, means I don’t need it.
      The MPU-6050 already does some complex filtering (probably Kalman or a version of it) on its own processor.

      Dan

  47. Pingback: Belgaum news | About Belgaum | Belgaum information | Belgaum district | Belgaum city | Belgaum Hotels | Belgaum People | Belgaum tourism | Belgaum entertainment | Belgaum students | Inside facebook | Hack | make use of | technical news | | Self-Balancing

  48. Pingback: Self-Balancing Robots Wobble, But They Don’t Fall Down — Blog of MPRosa

  49. Pingback: Self-Balancing Robots Wobble, But They Don’t Fall Down - RaspberryPiBoards

  50. Pingback: rndm(mod) » Self-Balancing Robots Wobble, But They Don’t Fall Down

  51. Pingback: Self balancing robot | Heron | Scoop.it

  52. Pingback: Self-Balancing Robots Wobble, But They Don’t Fall Down

  53. Nick Spitzer says:

    Nice post, I enjoy stopping by your blog from time to time!

    Your comment about over-designing made me think of Cubli. That is, in case you were wondering what over-designing a self-balancing movement object looks like:

    http://www.idsc.ethz.ch/Research_DAndrea/Cubli

    Greets,
    Nick

    • trandi says:

      Thanks!
      Yeah I saw Cubli featured the other day on Hack a Day… but with that think it’s not over engineering, it’s ART ! 🙂

      • Junjie Raga says:

        I cannot find the words how lucky I am to have found this post, however I have one question -> is it really necessary to use a geared motor or can i hook up the shaft of a DC motor directly to the wheels? will it work? I have all the parts now in my table I’m about to start to build this B.Bot.

      • trandi says:

        Happy that you found my post useful ! 🙂
        No the motor doesn’t have to be geared, it’s just that you have to have both enough speed and torque. Often, most small DC motors turn very fast but with little torque, hence the gearing…

Leave a reply to Huu Phuoc Cancel reply