1.  Arduino:  I used an Uno
2.  7.2v battery
3.  Set of motors:  Parralax's 7.2v motor set  http://www.robotshop.com/parallax-7-2v-motor-bracket-wheel-kit-pair.html
4.  Analog accelerometer http://www.robotshop.com/sfe-3g-tripleaxis-accelerometer-breakout-board-adxl335-2.html
5.  Sabertooth 5X2 motor controller   http://www.robotshop.com/productinfo.aspx?pc=RB-Dim-19&lang=en-US
6.  base board
7.  3/4" threaded rod and nuts for balance
8.  Zip ties
9.  Screws


1.  Drill
2.  3/4" and 1/4" drill bits

Step 1: Instructabot Platform

I used a piece of wood 6" x 12" x 0.5"


Step 2: Electronics

Now for the electronics...  

The brain of the robot is an Arduino UNO which reads the accelerometer and gives commands to the motor controller which in turn powers the motors.  The Arduino takes 10 readings per second from the accelerometer and proportionally changes the motor speed and direction.  The Arduino code has gone through many changes and tests, but you still may have to change some of the values to be compatible with your robot.  To run the robot, hook up all the wires in the correct fashion and upload the code below to the Arduino.  It should start working right there and then.

//Self Balancing Instructabot 2013

int x, r, l, s, f, xa, xb, xc;

//Digital pin 13 is serial transmit pin to sabertooth
#define SABER_TX_PIN  13
//Not used but still initialised, Digital pin 12 is serial receive from Sabertooth
#define SABER_RX_PIN  12
//set baudrate to match sabertooth dip settings
#define SABER_BAUDRATE  9600
SoftwareSerial SaberSerial = SoftwareSerial (SABER_RX_PIN, SABER_TX_PIN );

void initSabertooth (void)  {
  //communicate with sabertooth
SaberSerial.begin( SABER_BAUDRATE );

void setup()                    // run once, when the sketch starts

void set_motor()   {
  x = analogRead(0);       // read analog input pin 0

//x range is about 270-400 and flat is about 330
//smooth x by averaging 3 readings of x
xa = x;
delay (20);
x = analogRead(0);     
xb = x;
delay (20);
x = analogRead(0);      
xc = x;
x= (xa +xb + xc)/3;


//s=slope with less being more aggressive
s = 1.8  ;
//f=fudge factor
f = 5;

//stable x around 330
if ((x > 325) && (x < 335)) {
r = 62;
l = 194;
//drive forward at a steady speed if leaning forward a little 310 > x < 330
if ((x > 310) && (x < 326)) {
r = 45;
l = 167;
//if falling forward more increase speed linearly for 279 > x < 311
if ((x > 279) && (x < 311)) {
//higher values make it faster
r = s * x - 278 + f;
l = s * x - 148 + f;
//if full forward x < 280
if ((x > 250) && (x < 280)) {
r = 6;
l = 133;
// drive backward at a steady speed if leaning back a little 334 > x > 349
if ((x > 334) && (x < 349)) {
r = 78;
l = 208;
//if falling backwords more increase speed linearly for 348 < x < 390
if ((x > 348) && (x < 391)) {
//lower values make it faster
r = s * x - 270 + f;
l = s * x - 140 + f;
//if full backwords 390 < x
if ((x > 390) && (x < 410)) {
r = 122;
l = 250;

//send motor outputs to sabertooth


void loop ()  {
float level = 0;

int u;

} // end loop

Step 3: Making the Instructabot

So now it's time for the artistic part of this make.

1.  Cardboard 
2.  Glue
3.  Robot print

1.  Scissors 

Step 4:

What did you make?
I made a self-balancing, segway-like robot.  The robot works by taking readings from the accelerometer in the x-direction, converting them to digital, then putting them into a formula which turns the motors a specific speed to get it to right itself.   

How did you make it?
I have wanted for some time to make a full size ride-on segway but decided to start out with a smaller version to get some ideas for a full-scale version.  To make it, I used a drill, soldering iron, computer for programming the Arduino, accelerometer, motor controller, screwdriver, and a lot of ingenuity.

Where did you make it?
I made the entire robot at home.  

What did you learn?
Before this project, I hadn't done a lot of stuff with accelerometers so this project gave me a great oppurtunity to learn about them.  Also, sending serial to the motor controller took some thinking and tinkering with the computer program which was challenging.  I was most proud of getting it to balance. The biggest surprise was how hard it was to get the code just right.  
<p>In the video it says &quot;with a leash&quot;. I thought after trying to balance itself for 10-15 seconds it goes 1-2 metres forward, then it comes backwards. Am I wrong?How does it do it in the video?</p><p>Thank you by the way.</p>
Hi. Could you show me which part of the code makes the robot go forward( for a certain distance) then go backward (for a certain distance as shown in the video) please? Thank you.
The code given makes the robot try to stand up straight. When it falls forward it tries to right itself and moves forward in the process.
<p>In the video it says &quot;with a leash&quot;. I thought after trying to balance itself for 10-15 seconds it goes 1-2 metres forward, then it comes backwards. Am I wrong?How does it do it in the video?</p>
<p>Thank you by the way.</p>
<p>great job! Do check out this nano segway :</p><p><a href="http://www.instructables.com/id/Arduino-Nano-Segway/">http://www.instructables.com/id/Arduino-Nano-Segwa...</a></p>
Hi again, Can you tell me the max + and - angle from the vertical you based your code on? I'm still having difficulty in smoothing out the motion. Thanks
<p>Hi there! Can you help me with my masters degree project connected with Segway problem? I want to use neyral networks and fuzzy logic in it. I only have an arduino and a driver for 2 motors based on L298D chip</p>
<p>hello Librav nice robot you have here can you please send me the code and the design for your project to </p><p>ahmedmerzoug7@gmail.com </p>
<p>Wow....that's awsome segway!</p>
<p>Nice job on this. Which wheels sets are you using?</p>
Your bot looks great. The max my accelerometer measured while on the segway was 400 and the minimum was 270 with 330 about flat
<p>it was awesome but the arduino uno is showing errorketch_may27a:21: error: expected unqualified-id before '\x616c'</p><p>sketch_may27a.ino: In function 'void initSabertooth()':</p><p>sketch_may27a:26: error: 'SaberSerial' was not declared in this scope</p><p>sketch_may27a.ino: In function 'void setup()':</p><p>sketch_may27a:29: error: redefinition of 'void setup()'</p><p>sketch_may27a:1: error: 'void setup()' previously defined here</p><p>sketch_may27a.ino: In function 'void set_motor()':</p><p>sketch_may27a:102: error: 'SaberSerial' was not declared in this scope</p><p>sketch_may27a.ino: In function 'void loop()':</p><p>sketch_may27a:107: error: redefinition of 'void loop()'</p><p>sketch_may27a:6: error: 'void loop()' previously defined here</p><p>expected unqualified-id before '\x616c'</p><p>so can you help me for solving it</p>
<p>aesome . but i have got a problem that a have not got the sabertooth motor controller anywhere so can i use l298 p</p>
<p>Awesome. I'm doing segway and trying optimal trajectory problem. I was wondering for your RF control what kind of receiver you used. Or anyone use a specific type of receiver?</p>
<p>is possible with mma7361 or gy-521 acclerometer ?</p>
<p>HELLO i have one question i tried to use your program and i couldn&acute;t do it sorry i&acute;m new in this topic :'( but i would like to do that amaizing robot =D can you help me :( please I&acute;ll be very glad with you for the rest of my life =D</p>
<p>Where is schema of the accellerometer and arduino??</p>
<p>Nice instructable you got there. </p><p>But could you please provide me with little more details about the type of motors you used since the link you provided is no longer valid.</p><p>Thank you.</p>
You could use any brushed small motor and you would just have to adjust the program a little. Hope this helps. <br>
<p>These would probably do the job.</p><p>http://www.parallax.com/product/570-00080</p>
<p>Hi, the project is great but I have a one question.Can I use Accelerometer Gyro module for Arduino (something like 6DOF or MUP-6050) and did you use Serial Controlled Motor Driver Arduino (ROB-09571) or other?</p>
<p>Hello,</p><p> I'm sure your acelerometer/gyro assembly would work fine for this but the program would have to be changed most likely. As for the motor controller I used the Sabertooth 5X2 motor controller, a little pricey but does its job well.</p>
<p>Is there sometype of include file that I need for the saber board?</p><p>I get an error if I just try to upload the sketch?</p>
<p>Update: I got mine working. Turned out that I used a 2x12RC board. The &quot;RC&quot; does not allow serial comm. The nice folks at dimension swapped it out for me &amp; with my minor mod to the code I show below, I have it working. </p>
<p>I should post the error. Also, I just realized that I bought a 2x12RC board. Would that make a difference?</p><p> The following line is highlighted:</p><p>SoftwareSerial SaberSerial = SoftwareSerial (SABER_RX_PIN, SABER_TX_PIN );</p><p>ERROR:</p><p>BalanceBot.ino:4:9: error: #include expects &quot;FILENAME&quot; or &lt;FILENAME&gt;</p><p>BalanceBot:13: error: 'SoftwareSerial' does not name a type</p><p>BalanceBot.ino: In function 'void initSabertooth()':</p><p>BalanceBot:18: error: 'SaberSerial' was not declared in this scope</p><p>BalanceBot.ino: In function 'void set_motor()':</p><p>BalanceBot:94: error: 'SaberSerial' was not declared in this scope</p>
<p>I believe I have figured out the error.</p><p>I changed the the first couple of lines to this: <br>#include &lt;SoftwareSerial.h&gt;<br>int x, r, l, s, f, xa, xb, xc;</p><p>And the errors were gone &amp; code uploaded.</p><p>However, the motors dont seem to be doing anything when I angle the bot foward &amp; backward. Not sure if the changes I made are correct.</p>
<p>I am absolutely new to this. I need the code for the L239D with a Groove 3-axis accelerometer. Could you please help me out asap? </p>
<p>I wonder f,s ? caculate s,f ? thanks you</p>
<p>why i try your code, it happen error #include&lt;filename&gt; , you can help me?</p>
<p>Hi,bro ,i want to know how to change the direction, does it have any switch ?</p>
<p>please expand on ur question. The robot goes both directions to balance and reversing it would make it fall</p>
<p>WOW..sorry ...i got it thanks very much very nich work,,</p>
<p>Hey , Is your machine also move forward and backward in balanced condition, like segway moves ??</p>
Very nice. What you need for stability is a PID control algorithm. You already have the basic idea in your code, but the general solution has been studied for many years. <br> <br>The PID is an acronym for 'Proportional, integral, differential' controller. It goes kind of like this: <br> <br>You measure your angle. Your target angle is '0' degrees, right? So, you take your measured angle and subtract your target angle, this gives you an angular error: <br> <br> e = (a - a0) // a is measured angle, a0 is target angle, e is error <br> <br>So, now you know how far off you are, you need to decide how much energy to put into the wheels. We'll start simple with just the 'P' or 'proportional part: <br> <br>f = k * e; // f is the force to apply to the wheels, e is the error, and k is some constant you make up. <br> <br>If k is too big, it goes unstable. if too small, your control algorithm can't keep up and balance. You determine k empirically by trying different numbers until you get it about right. <br> <br>So... in short you 'P' or proportial control algorithm will look like this: <br> <br>float get_motor_power(float angle, float target_angle, float k) { <br> float error = angle - target_angle; <br> float result = k * error; <br> return result; <br>} <br> <br>That's it! I did it all in float, but you may be able to change to ints for the parameters,but float computations makes things much easier. <br> <br>Once you get your proportional algorithm going, you can easily add the integral and differential parts (slightly more complex) to further improve stability and accuracy. <br> <br>-Caleb <br>
<p>Thanks Caleb, that was very useful piece of information for me. I have few more questions, could help me out, please?-</p><ol><li> Can I calculate constant K with some calculations or the trial and error method is only way?<li>Where does Kalman filter comes into picture, do I also need to write code for Kalman filter considering this application?</ol>
Yes you can calculate k in principle, but you need to know all the equations regarding your system. Easiest to simply go through trial and error.<br><br>Unfortunately, Kalman filtering is beyond my knowledge. It's a filter that's able to work out the equations, even when conditions change. It's an adaptive filter of sorts. More than that though, I can't really help.<br><br>PID is pretty much the most basic kind of filter, but it's all I really understand. The more complicated stuff requires math that's really at the limit (and perhaps beyond the limit) of my math skills. (BTW, I took engineering math for 4 years at college :-/ ) <br><br>Sorry I can't be of more help,<br> -Caleb<br><br>
<p>:-).. no worries Caleb, thanks for taking time out to answer.</p><p>I won't need a Kalman filter; for now I am using Savitzky-Galoy filter. I hope it should do the trick with smoothing Accelerometer values.</p><p>I also found nice theory on PID in Bela G Liptak. </p><p>Cheers! Shreyas</p>
Caleb raises a good point, there is a PID library included with the Ardunio IDE <br>(http://playground.arduino.cc/Code/PIDLibrary), might be worth playing about. <br> <br>For tidier code you might want to refactor (generalise) some of your repetitious code. For example: <br>if ((x &gt; 250) &amp;&amp; (x &lt; 280)) { <br>r = 6; <br>l = 133; <br>} <br> <br>if ((x &gt; 390) &amp;&amp; (x &lt; 410)) { <br>r = 122; <br>l = 250; <br>} <br> <br>these two pieces of code are very similar, you could make a function that performs this conditional statement: <br>void setMotorSpeedBasedOnAngle(int minAngle, int maxAngle, int rightMotorSpeed, int leftMotorSpeed) { <br> if (x &gt; minAngle &amp;&amp; x &lt; maxAngle) <br> r = rightMotorSpeed; <br> l = leftMotorSpeed; <br>} <br> <br>that way you can replace the above two statements respectively as: <br>setMotorSpeedBasedOnAngle(250, 280, 6, 133); <br>setMotorSpeedBasedOnAngle(390, 410, 122, 250); <br> <br>This means should you want to change your conditional code, you only have to change it one place, which is benefit enough to use this style of programming. <br> <br>Cool project, I enjoyed reading about it.
I like how you incorperated the instructables robot
<p>you're welcome! Why did it take you so long to reply?</p>
Can I use L239D motor controller instead of sabertooth ? Will the programming change?
<p>You would have to completely rewrite the code to use those speed controllers.</p>
<p>can i use L293D motor driver circuit.</p>
<p>No sorry only Sabertooth speed controllers will work with the code.</p>
Hi can i do this but using a 2 motor with 1hp each one, and with bigger wheels?? like a real segway??
You could but I'm not sure it would be stable enough to stand on. To do it you would just have to get a bigger speed controller, I believe Sabertooth makes a 25 watt model that would be compatible with my code. <br> <br>Hope this helps
thanks for this instructable

About This Instructable




More by florman:Ultimate Sensing Texting Unit How to Wire a Trailer Self Balancing Segway Instructabot 
Add instructable to: