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

About these ads

69 Responses to Self balancing robot

  1. 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.

  2. 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

  3. 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.

  4. angga says:

    could not if using arduino uno?

  5. 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 .

  6. 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:

        >

  7. 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?

  8. 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

  9. 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:

        >

  10. 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 http://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

  11. 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:

        >

  12. 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.

  13. 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

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

  15. 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

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

  17. 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:

        >

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

  19. SuperEngine says:

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

  20. 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..

  21. 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

  22. 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

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

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

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

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

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

  28. 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 ! :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 139 other followers

%d bloggers like this: