Introduction: Self Balancing Segway Instructabot


Supplies:

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

Tools:

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
//Ferris

#include
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
pinMode ( SABER_TX_PIN, OUTPUT );
SaberSerial.begin( SABER_BAUDRATE );
}

void setup()                    // run once, when the sketch starts
{
  initSabertooth();
    //analogINPUTS
    Serial.begin(9600);  
}

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;

         
//SABER_right_FULL_FORWARD 127
//SABER_right_FULL_REVERSE 1
//SABER_left_FULL_FORWARD 255
//SABER_left_FULL_REVERSE 128

//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
SaberSerial.write(byte(r));
SaberSerial.write(byte(l));

}

void loop ()  {
 
float level = 0;

int u;

  set_motor();
 
} // end loop

Step 3: Making the Instructabot

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

Supplies:
1.  Cardboard 
2.  Glue
3.  Robot print

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

Comments

author
ZoeD17 made it!(author)2017-05-24

could this hold the weight of a person that weights 100-110 pounds

author
Robot55 made it!(author)2016-10-06

In the video it says "with a leash". 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?

Thank you by the way.

author
Robot55 made it!(author)2016-10-02

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.

author
florman made it!(author)2016-10-02

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.

author
Robot55 made it!(author)2016-10-03

In the video it says "with a leash". 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?

author
Robot55 made it!(author)2016-10-03

Thank you by the way.

author
Technovation made it!(author)2016-05-24

great job! Do check out this nano segway :

https://www.instructables.com/id/Arduino-Nano-Segwa...

author
Librav made it!(author)2013-06-17

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

SBR12.JPGSBR11.JPGSBR10.JPG
author
antonkornilkov made it!(author)2016-04-04

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

author
alojds made it!(author)2016-02-03

hello Librav nice robot you have here can you please send me the code and the design for your project to

ahmedmerzoug7@gmail.com

author
gunnlaugursig made it!(author)2014-08-16

Wow....that's awsome segway!

author
jwalter007 made it!(author)2014-03-09

Nice job on this. Which wheels sets are you using?

author
florman made it!(author)2013-12-03

Your bot looks great. The max my accelerometer measured while on the segway was 400 and the minimum was 270 with 330 about flat

author
rock.kuldeep.1 made it!(author)2015-05-27

it was awesome but the arduino uno is showing errorketch_may27a:21: error: expected unqualified-id before '\x616c'

sketch_may27a.ino: In function 'void initSabertooth()':

sketch_may27a:26: error: 'SaberSerial' was not declared in this scope

sketch_may27a.ino: In function 'void setup()':

sketch_may27a:29: error: redefinition of 'void setup()'

sketch_may27a:1: error: 'void setup()' previously defined here

sketch_may27a.ino: In function 'void set_motor()':

sketch_may27a:102: error: 'SaberSerial' was not declared in this scope

sketch_may27a.ino: In function 'void loop()':

sketch_may27a:107: error: redefinition of 'void loop()'

sketch_may27a:6: error: 'void loop()' previously defined here

expected unqualified-id before '\x616c'

so can you help me for solving it

author
rock.kuldeep.1 made it!(author)2015-05-21

aesome . but i have got a problem that a have not got the sabertooth motor controller anywhere so can i use l298 p

author
hwarang1231 made it!(author)2015-04-02

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?

author
diegocaetano1988 made it!(author)2015-03-12

is possible with mma7361 or gy-521 acclerometer ?

author
AlejandroRivera06 made it!(author)2015-02-17

HELLO i have one question i tried to use your program and i couldn´t do it sorry i´m new in this topic :'( but i would like to do that amaizing robot =D can you help me :( please I´ll be very glad with you for the rest of my life =D

author
Espasio made it!(author)2014-11-03

Where is schema of the accellerometer and arduino??

author
gunnlaugursig made it!(author)2014-08-15

Nice instructable you got there.

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.

Thank you.

author
florman made it!(author)2014-08-15

You could use any brushed small motor and you would just have to adjust the program a little. Hope this helps.

author
gunnlaugursig made it!(author)2014-08-16

These would probably do the job.

http://www.parallax.com/product/570-00080

author
Marta015 made it!(author)2014-07-11

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?

author
florman made it!(author)2014-07-11

Hello,

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.

author
jwalter007 made it!(author)2014-03-22

Is there sometype of include file that I need for the saber board?

I get an error if I just try to upload the sketch?

author
jwalter007 made it!(author)2014-04-09

Update: I got mine working. Turned out that I used a 2x12RC board. The "RC" does not allow serial comm. The nice folks at dimension swapped it out for me & with my minor mod to the code I show below, I have it working.

author
jwalter007 made it!(author)2014-03-22

I should post the error. Also, I just realized that I bought a 2x12RC board. Would that make a difference?

The following line is highlighted:

SoftwareSerial SaberSerial = SoftwareSerial (SABER_RX_PIN, SABER_TX_PIN );

ERROR:

BalanceBot.ino:4:9: error: #include expects "FILENAME" or <FILENAME>

BalanceBot:13: error: 'SoftwareSerial' does not name a type

BalanceBot.ino: In function 'void initSabertooth()':

BalanceBot:18: error: 'SaberSerial' was not declared in this scope

BalanceBot.ino: In function 'void set_motor()':

BalanceBot:94: error: 'SaberSerial' was not declared in this scope

author
jwalter007 made it!(author)2014-03-23

I believe I have figured out the error.

I changed the the first couple of lines to this:
#include <SoftwareSerial.h>
int x, r, l, s, f, xa, xb, xc;

And the errors were gone & code uploaded.

However, the motors dont seem to be doing anything when I angle the bot foward & backward. Not sure if the changes I made are correct.

author
mushfiq1996 made it!(author)2014-04-05

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?

author
monkeybuiluan made it!(author)2014-03-03

I wonder f,s ? caculate s,f ? thanks you

author
monkeybuiluan made it!(author)2014-03-03

why i try your code, it happen error #include<filename> , you can help me?

author
chenjian made it!(author)2014-03-02

Hi,bro ,i want to know how to change the direction, does it have any switch ?

author
florman made it!(author)2014-03-02

please expand on ur question. The robot goes both directions to balance and reversing it would make it fall

author
chenjian made it!(author)2014-03-02

WOW..sorry ...i got it thanks very much very nich work,,

author
ssamaiya made it!(author)2014-02-25

Hey , Is your machine also move forward and backward in balanced condition, like segway moves ??

author
ccrome made it!(author)2013-04-18

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.

The PID is an acronym for 'Proportional, integral, differential' controller. It goes kind of like this:

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:

e = (a - a0) // a is measured angle, a0 is target angle, e is error

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:

f = k * e; // f is the force to apply to the wheels, e is the error, and k is some constant you make up.

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.

So... in short you 'P' or proportial control algorithm will look like this:

float get_motor_power(float angle, float target_angle, float k) {
float error = angle - target_angle;
float result = k * error;
return result;
}

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.

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.

-Caleb

author
KalkiV made it!(author)2014-02-24

Thanks Caleb, that was very useful piece of information for me. I have few more questions, could help me out, please?-

  1. Can I calculate constant K with some calculations or the trial and error method is only way?
  2. Where does Kalman filter comes into picture, do I also need to write code for Kalman filter considering this application?
author
ccrome made it!(author)2014-02-24

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.

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.

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 :-/ )

Sorry I can't be of more help,
-Caleb

author
KalkiV made it!(author)2014-02-25

:-).. no worries Caleb, thanks for taking time out to answer.

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.

I also found nice theory on PID in Bela G Liptak.

Cheers! Shreyas

author
rocker9455 made it!(author)2013-04-19

Caleb raises a good point, there is a PID library included with the Ardunio IDE
(http://playground.arduino.cc/Code/PIDLibrary), might be worth playing about.

For tidier code you might want to refactor (generalise) some of your repetitious code. For example:
if ((x > 250) && (x < 280)) {
r = 6;
l = 133;
}

if ((x > 390) && (x < 410)) {
r = 122;
l = 250;
}

these two pieces of code are very similar, you could make a function that performs this conditional statement:
void setMotorSpeedBasedOnAngle(int minAngle, int maxAngle, int rightMotorSpeed, int leftMotorSpeed) {
if (x > minAngle && x < maxAngle)
r = rightMotorSpeed;
l = leftMotorSpeed;
}

that way you can replace the above two statements respectively as:
setMotorSpeedBasedOnAngle(250, 280, 6, 133);
setMotorSpeedBasedOnAngle(390, 410, 122, 250);

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.

Cool project, I enjoyed reading about it.

author
nerd7473 made it!(author)2013-06-13

I like how you incorperated the instructables robot

author
florman made it!(author)2014-01-31

thanks

author
nerd7473 made it!(author)2014-01-31

you're welcome! Why did it take you so long to reply?

author
nihit30 made it!(author)2013-10-11

Can I use L239D motor controller instead of sabertooth ? Will the programming change?

author
florman made it!(author)2014-01-31

You would have to completely rewrite the code to use those speed controllers.

author
siddhu99199 made it!(author)2014-01-29

can i use L293D motor driver circuit.

author
florman made it!(author)2014-01-31

No sorry only Sabertooth speed controllers will work with the code.

author
Gabosanram made it!(author)2013-12-03

Hi can i do this but using a 2 motor with 1hp each one, and with bigger wheels?? like a real segway??

author
florman made it!(author)2013-12-03

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.

Hope this helps

author
Mic100 made it!(author)2013-11-03

thanks for this instructable

About This Instructable

122,978views

367favorites

License:

More by florman:Ultimate Sensing Texting UnitHow to Wire a TrailerSelf Balancing Segway Instructabot
Add instructable to: