loading
After getting so much frustrated over PID tuning of quadcopter, I decided to master PID first on some basic project. Self-balancing robot seems an idle choice. Since it’s not new and still challenging, I decided to go for it.
I never thought it will be easy and I am not disappointed. I learned a lot from it and decided to share it with others.

EDIT - Some people were getting NaN values in their PID readings.The reason was EEPROM use. PID values were loaded from the EEPROM on initialisation. If values haven't already been stored in EEPROM,it will return NaN. People who don't need EEPROM can find a separate version in GITHUB.

Step 1: Concept/Theory

What is Self-balancing robot?

Self-Balance Robot is somewhat which balances itself and automatically corrects its position on disturbance.

How it works?

It will be prevented from falling by giving acceleration to the wheels according to its inclination from the vertical. If the bot gets tilts by an angle, than in the frame of the wheels, the center of mass of the bot will experience a pseudo force which will apply a torque opposite to the direction of tilt.

That’s the technical answer. If you want to know in simple terms, recall the stick balancing game which you used to play in your childhood.Yeah, the one in which you balance stick in your hand. If stick falls forward, you move your hand forward and vice-versa. Now consider the stick your robot and the 2 tire’s as your hands. The same technique you used to balance stick will now be used to balance robot.

Step 2: Materials

First we need some materials to build our chassis. I choose Acrylic sheet. Some screws will be needed according to design which we will discuss shortly plus 2 tires.

For remaining Electronics part, here’s the list

1x Arduino UNO

1x HC-05 Bluetooth Module

1x MPU 6050

1x L293D

1x IC7805

1x Battery

2x 500 rpm Motors

2x Motor clamps with screws

Some jumper wires and breadboard/PCB

We will talk about the choices of these components later

Step 3: Chassis

I designed my chassis using acrylic sheet (just to save trouble of drilling holes). However, it can be designed using Wooden plank, plastic sheet etc. too. In my opinion, wooden plank will be good choice if you want to build a stable chassis and plan to mount something on it. Anyways, I cut sheet to form 3 levels/floors. It’s not mandatory, but is a good practice. No. of levels can be increased if desired. After markings, holes has to be made for screws. For making holes, I simply use Solder iron. (Here acrylic sheet comes to rescue. After making holes, I realized that I made mistakes which I corrected easily) If you are using, wood, double check your markings.

Choice of tires should be ones with good grip (rubber, if available) and large surface area.

Assemble the whole chassis and we are ready to move to electronics part.

Step 4: Connections

Now why these components?

MPU-6050 is used due to its DMP capability. It can process the Raw Accelerometer & Gyro values to give the Yaw, Pitch, and Roll. It greatly decreases the computation overhead.

HC-05 Bluetooth module is used for communication between Bot and Android app.

L293d motor driver is used for controlling motor.

IC7805 voltage Regulator is used for providing 5V power supply to Arduino. However, using this IC is not necessary and battery can be directly plugged to Arduino. This is just used for Safety Purposes

A fritizing file is attached to show the connections. Connect all as shown.

Now as everything set, we can dive into the code for our robot.

Step 5: Software

Arduino is known for its friendly coding environment and large open source user libraries which makes the prototyping really easy.

I first started with separate Accelerometer and Gyroscope. But as things progressed, I find it difficult to balance with computational overhead of calculating pitch & roll (using kalman/Complementary filter).When I switched to MPU-6050, it drastically improved the balancing.

To use the DMP of MPU, I used Jeff Rowberg’sI2CDev libraries. To calibrate the mpu, I used Luis Rodenas’ssketch.

Now, we can determine the angle of bot with vertical. But how can we calculate the amount of force needed to push bot back to vertical when it is unbalanced by some uncertain degrees from vertical. This is where PID kicks in.PID will specify this force which will change according to time and angle by which bot is unbalanced.

I will not go into technical details. Brett Beauregard wrote a nice PID library with explanation if you want.

To further speed up the motor response, I used digitalIOPerformance library for fast writing of pins.

Finally for storing PID values in EEPROM of Arduino, EEPROMex library for efficiency and clean code.

Complete code can be found on the GITHUB.

Step 6: APP

Re-uploading code every time to change PID values is very tiresome. So I decided to attach Bluetooth and change values from my Android phone. I saw many people using MIT App Inventor for building apps for such purposes. I never used it before. So I thought, I must give it a shot. After watching some tutorials and some apps from other people regarding Bluetooth connection, I was all set. I must admit,App inventor revolutionize the app creation by letting you make apps in a way even non-programmers can make it without concerning what is happening behind the scenes.

MIT app inventor was fun except I have to deal large graphical blocks even for simpler tasks. Arrangements of these blocks was tiresome and reading it was pain.

You can find my app and Sample code from here.

Note-Although Multi-scene was introduced in App inventor 2, it treats every scene as separate app.For ex-you started some Bluetooth activity in scene1 and paired a device and then switched to scene2.scene2 will be completely unaware of the the pairing and tries to pair (& obviously fails) a device. A good way of handling it is build a single scene app and hide/show elements just like single page websites.

Step 7: PID Tuning

Frankly, this is the most difficult part of the process and also the most crucial. You will spend many days working on it and yelling “WTH am I supposed to do?” How much frustrating it may be but there is no escaping it? Control engineers set the PID parameters by experience. It’s an art learnt through experience.

There are various methods out there for PID tuning.

The best simple & easy method for PID tuning is-

  • · Set I and D term to 0, and adjust P so that the robot starts to oscillate (move back and forth) about the balance position. P should be large enough for the robot to move but not too large otherwise the movement would not be smooth.
  • · With P set, increase I so that the robot accelerates faster when off balance. With P and I properly tuned, the robot should be able to self-balance for at least a few seconds.
  • · Finally, increase D so that the robot would move about its balanced position more gentle, and there shouldn’t be any significant overshoots.
  • · If first attempt doesn’t give the satisfying results, reset PID values and start over again with different value of P.
  • · Repeat the steps until you find a certain PID value which gives the satisfactory results.
  • · A fine tuning can be done to further increase the performance of PID system.
  • · In fine tuning, PID values are restricted to neighboring values and effects are observed in practical situations.

Important Points

  • · There is no clear boundary for taking P, I or D values and is mostly taken based on experience.
  • · Theoretically, ID values depends on the state of the system.Ex. Mechanical Structure, Physical properties, Electrical properties (if any) etc.
  • · But practically, it also depends on the external conditions.Ex. Atmospheric conditions etc.
  • · PID values and method of choosing PID values depends largely on the characteristics of system. A method producing good result for a system may not work at all for another system with different characteristics.

What P, I & D values means practically?

In case of Self-Balancing Robot-

  • P-P determines the force with which the robot will correct itself. A lower P shows robot’s inability to balance itself and a higher P will shows the violent behavior.
  • I-I determines the response time of robot for correcting itself. Higher the P, Faster it will response.
  • D- D determines the sensitivity of robot to the error in its state. It is used to smoothen/depress the robot oscillations. A lower D is unable to remove oscillations and a higher D will cause violent vibrations.

Depending on your PID tuning, the bot will be able balance itself now.

Congratulation!!! On your first self-balancing robot. Maybe you can name it now, I called mine Chappie.

Step 8: What’s Next?

Well, now you have a self-balancing robot which you can control by Bluetooth. Maybe you can upgrade it to Wi-Fi or use it as replacement to your 4 wheel robot.

You can upgrade the Arduino to Raspberry pi to harness the power of mini-computer e.g. Image processing etc.

You can also use decoder motor or stepper motors.it will also significantly increases the performance. However, you will need to update the code accordingly.

<p><strong>UPDATE:</strong></p><p>digitalIOPerformance library doesn't work on Arduino 1.6. Use Arduino 1.5 for compiling the program.</p>
<p>bro can u send me full coding of your project ???????plz</p>
thanx a lot...manpreet bro....i ve made...bt i found that the motor connection to l293d is wrong in the ckt diagram....secondly your app is not working....so I did the PID tuning by connecting to pc....every time I give a command through the app it shows &quot;broken pipe&quot;....I hope you would reply soon...once again thanx a lot!
<p>Can u please send me the correct circuit diagram to sharmabasket13@gmai.com. I am working on same project</p>
Bro can u send me the correct circuit diagram. I have made the connections. In serial port I a getting Nan as output and the motor driver IC is not driving the motors. Plz help me out. I have a deadline to complete this. Thank u <br>
Can you send mo the codes? Thanks dude. johnpaulpagobayan@yahoo.com
<p>nice project</p><p>plese send me code</p><p>aporizga1313@gmail.com</p>
Nice project. Can you send me the codes for this? johnpaulpagobayan@yahoo.com thanks!
<p>can you please send me the code ...</p><p>souad.saidi.95@gmail.com</p>
<p>can you plz send me the code ... </p><p>abhi.bassan@gmail.com</p>
<p>Hello </p><p>I am getting an error in the code that &quot;MPU6050 does not name a type&quot;</p><p>please email me to rohan.kurella123@gmail.com</p>
<p>Dude. Nice code. </p><p>Cheers</p>
<p>Love the name did you name him after the movie? One of my favourite movies.</p><p>Martin.</p>
<p>sir,</p><p> i have done the circuit as given above. can you please send me the arduino program for arduino 1.5 and also for arduino 1.6</p><p>can you please send it at the earliest.....</p><p> thank you</p>
<p>my email</p><p>sudeep21sapnil@gmail.com</p><p>please don't send the link, send the whole program............................</p>
<p>Hi Manpreet,</p><p>I am using your code without EEPROM. The wheel seems to be moving in only one direction no matter what I do. I tried to calibrate by starting with a value of p and i and d to zero. The wheel still keeps on moving in same direction. oscillation is not happening. Am I missing something here ? Will be helpful if you can give some direction.</p><p>Email if sku3331@gmail.com</p><p>Thanks</p>
<p>HELLO!</p><p>Thanks for the tutorial!</p><p>I used your code (SelfBalance_robot0_66_withoutEEPROM) on the Arduino IDE 1.5.8, with the MPU 6050 calibrated and in the horizontal, and the engines started work forward and didn't stop, i needed shut off the Arduino for the process stop. Then i used the app RC Blue, and i hadn't sucess to control the engines.</p><p>I'm using the all the conections which you put in your project, and i don't using any type of structure for test the project, all the pieces are on the my table in the horizontal. What i can do to do the system work the right way?? And i need use the sample code of RC Blue (which is in folder of rc blue) to work the right away??</p><p>I apologize for the written in english, i have a low level in the this language...but i hope you understand the problem which happened.</p>
<p>Hello,</p><p>Love your work! </p><p>Can you explain more about how to code the robot, so it can &quot;maintain balanced while moving, or other directions&quot;. I've looked up your code, but still can not figure out the relationship between the remote direction control and the output pwm.</p><p>Thanks:) </p>
<p>Is it just simply change the set point and break the balance condition, so the robot would lean on one particular side?</p>
Yeah.just change the set point by a little bit. eg. if you change yaw,it will move left and right to correct it.For the balance point slightly in that direction.If its too low the bot will not move.If too big,the bot will slide too fast and may lost it balance.
<p>Thanks a lot! What if I want to make it turn right and left?</p>
<p>hi ! if i use the arduino leonardo the code will stay the same?or will i have to change it?</p>
<p>Hi bro, Thanks for the wonderful tutorial. when bot is place in normal position where for few sec its stable and suddenly there will be some garbage value running and ll come back to normal. Its hard for me to calibrate the PID. motors are running too fast, how to control them. </p>
<p>All the connection are perfectly done, but its not working!!!</p><p>HELP ME!!!</p><p>email solankimithilesh12@gmail.com</p>
<p><a href="https://www.instructables.com/member/manpreetsingh80/" rel="nofollow">manpreetsingh80</a>, thank you for a great tutorial.</p><p>I have a question about your arduino code (with EEPROM). The function save_pid seems to write to the first 3 addresses both the pid and rot values, depending on the function variable. don't they overwrite each other? I would expect addressFloat to start with sizeof(float)*3 for the rot branch.</p>
<blockquote>IC7805 voltage Regulator is used for providing 5V power supply to Arduino. However, using this IC is not necessary and battery can be directly plugged to Arduino. This is just used for Safety Purposes</blockquote><p>Not only is it &quot;not necessary&quot;, it's a bloody stupid thing to do. By using that you are starving the Arduino of power by under-powering it. The minimum voltage for the barrel jack input is 6V with a recommended minimum of 7V. Providing it with 5V means the internal regulator would then not be regulating and just dropping the voltage by its drop-out voltage of around a volt, so the Arduino will only be getting 4V. At 4V you are right on the lower voltage limit for running at 16MHz. Any slight variation (which there may well be since you don't precisely know the dropout of the 1117 is 1V, in fact it's nearer 1.2V) will put the Arduino into an unguaranteed state where you are running at too low a voltage for the frequency, and stability issues may well occur, making you self-balancing robot run over your pet hamster.</p><p>You only need the external regulator if you want to bypass the on-board regulator and feed the power direct into the 5V pin, which you aren't doing, and since the 1117 is marginally more modern (by about 30 years) than the ancient 7805 (which few designers actively use in current designs unless they started using it back in the dark ages), why would you want to do that? If it's for increasing current availability then you don't want a linear LDO in any case - you need a buck regulator.</p><p>Also your choice of battery tells me you don't have much practical knowledge. 9V PP3 batteries aren't suitable for powering much more than a smoke detector or small transistor radio. They lack the current and power capacity to do anything useful. Whoever first publicised using them with an Arduino needs shooting. They are the worst choice ever for doing anything that isn't highly optimized for low current consumption. At little more than 150mAh you can expect maybe an hour of use out of it - if it can even provide enough current to drive the motors under load, especially with the current hungry Bluetooth module in the mix. You really need <em>at least</em> 7.2V worth of AA batteries (6S NiMh are good) or a 2S Lithium-Ion battery pack. </p>
<p>Thanks for the upload. everythings connected but the motors r working on their own. can you please help.</p>
<p>How much torque do the motors need to provide? </p>
<p>MY MOTORS ARE NOT WORKING ALTHOUGH ALL CONNECTIONS ARE SAME AS GIVEN ABOVE N THERE IS NO ERROR IN UPLOADING CODE, HELP ME </p><p>EMAIL.ID -TARITDASGREAT@GMAIL.COM</p>
<p>MY MOTORS ARE NOT WORKING ALTHOUGH ALL CONNECTIONS ARE SAME AS GIVEN ABOVE N THERE IS NO ERROR IN UPLOADING CODE, HELP ME </p><p>EMAIL.ID -TARITDASGREAT@GMAIL.COM</p>
<p>Arduino: 1.5.8 (Windows 8), Board: &quot;Arduino Uno&quot;</p><p>SelfBalance_robot0_66_withoutEEPROM.cpp.o: In function `setup':</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:107: undefined reference to `PID::SetMode(int)'</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:108: undefined reference to `PID::SetOutputLimits(double, double)'</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:109: undefined reference to `PID::SetSampleTime(int)'</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:110: undefined reference to `PID::SetMode(int)'</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:111: undefined reference to `PID::SetOutputLimits(double, double)'</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:112: undefined reference to `PID::SetSampleTime(int)'</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:137: undefined reference to `PID::SetTunings(double, double, double)'</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:138: undefined reference to `PID::SetTunings(double, double, double)'</p><p>SelfBalance_robot0_66_withoutEEPROM.cpp.o: In function `new_pid()':</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:387: undefined reference to `PID::Compute()'</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:388: undefined reference to `PID::Compute()'</p><p>SelfBalance_robot0_66_withoutEEPROM.cpp.o: In function `__static_initialization_and_destruction_0':</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:84: undefined reference to `PID::PID(double*, double*, double*, double, double, double, int)'</p><p>/Arduino/SelfBalance_robot0_66_withoutEEPROM.ino:85: undefined reference to `PID::PID(double*, double*, double*, double, double, double, int)'</p><p>collect2: error: ld returned 1 exit status</p><p>Error compiling.</p><p> This report would have more information with</p><p> &quot;Show verbose output during compilation&quot;</p><p> enabled in File &gt; Preferences.</p>
<p>It seems like you haven't installed the PID library.Please install the library from the links provided above or from my GITHUB.</p>
<p>Bro i have made all the connections as given and i have also installed your rc blue app , but after giving the power supply nothing happens . before installing the component on the chasis i thought of checking it but the wheel is not moving whatever i do.</p><p>1.there is no problem with the coding.</p><p>2.i have checked every component so no problem with components either.</p><p>3.i have made the circuit from your schematics.</p><p>please help if you can , i will be really thankful if you can give some of your precious time.</p><p>gmail - imtb777@gmail.com</p>
same problem here <br>if you get the solution <br>can you please tell me too<br>kartavya.kothari24@gmail.com
<p>Do you even know what you are doing?</p><p>Have you read the whole instructable and understood the code?</p>
<p>everything made. but Engines do not move . please help me</p>
same problem here <br>if you get the solution <br>can you please tell me too<br>kartavya.kothari24@gmail.com
Thanks bro your code work perfectly for me and i got a A+ in my project
<p>hey bro,</p><p>i m 14 but i love robotic i had maded sevral robots and now thinking for made a robot with a self balancing feature i m also not that expert in programing i have learnt the concept of pid &lt;thanks 2 u&gt; but i m facing some problem regarding coading can u pls. tell me briefly about how can i upload the program in my arduino and can u also tell me from where 2 download the app &lt;rc blue&gt; and can u also controll its movement via bluetooth i mean can u move it in all 4 directions using ur app ????</p>
<p>It's good to hear you have interest in robotics at such an early age.For learning Arduino,you can refer any book or tutorials on internet.One example is:-</p><p><a href="http://electronics2work.com/tutorials/arduino.html" rel="nofollow">http://electronics2work.com/tutorials/arduino.html</a></p><p>The link to download app is given in the tutorial above and yes you can move it in all the four directions.</p>
<p>Not getting the right PID value.... The motors are moving in opposite direction is it correct?</p>
<p>Try reversing the motor connections.Tell me if the problem still exist.</p>
<p>how did your motor start moving?</p>
<p>hey. thanks for your project, its awesome. I started tu buil one. i do everything as it is needed, everything it's pluged corectly, there is just one thing. DC motors wont work at any PID values. i took voltage meter and figured out, that its no metter what are PID values, the voltage always is 0.6V. how can i solve it? :( thanks..</p>
<p>try the without_EEPROM version of code.</p>
<p>the program you have to enter the value of pid<br>pid.SetTunings(bal_kp, bal_ki, bal_kd); //change PID values</p><p>rot.SetTunings (bal_kp, bal_ki, bal_kd)</p><p>find that function and write</p><p>pid.SetTunings(15,0,0);</p><p>rot.SetTunings (15,0,0);</p>
<p>Hello Sir, You have made an awesome instructable, this was the only one who's code i could understand alot but i didnt understand what the PID rot is for. i see its to compensate the slack as u mentioned in the code </p><p>Output = Output + MOTORSLACK_A - yOutput;</p><p>but what does this do. i see you add the MOTORSLACK_A to Output to get your pwm values for the motors to move. but why do u=you subtract yOutput which is yout.</p><p>and what are you calculating for yout through pid?.</p><p>if you can't understand what i mean please ask. As i am bad at explaining things :p</p>
<p>There are two PID's running.One for preventing it from falling(Balance pid) -&gt;output</p><p>other for changing directon i.e rotating left and right(rotation pid) -&gt; youtput</p><p>That's why on final motor output,both out and yout is used.</p>
<p>basically what is rotation pid and what is it used for?</p>
<p>but why do you* subtract YOutput which is yout</p>

About This Instructable

76,558views

323favorites

License:

Bio: If you like my work,Please visit my Website for more awesome things
More by manpreetsingh80:Chappie- Self-Balancing Robot 
Add instructable to: