Self Balancing Robot - Bang Bang Control




Introduction: Self Balancing Robot - Bang Bang Control

About: I am an American teaching English at Shangluo University, Shaanxi. I like making machines that do interesting but fairly useless things - I call them Quixotic Machines.

Made a simple self-balancing robot using two servos, a tilt meter (VTI SCA610 chip), and Arduino Uno. This is different than most self-balancing robots in that it uses only a single sensor (no gryo) and the program is essentially two IF statements. If the robot leans one way, apply full power to the wheels forward, if leaning in the other direction, reverse the wheels. I use a 10k potentiometer to set SETPOINT or normal balance point. Bang bang control is simple full power on or off, no PID or proportional control.

It is generally assumed that you need motors of 200rpm or more but my two servos are continuous turning and 60rpm. As a result, I had to use abnormally large diameter wheels to get enough speed to stop a fall or hard hit. The wheels are plastic fruit baskets. One way to cheat a little if your motors are not fast enough or have enough torque, put some weights below the axle line so the motors don't have to work so hard.

I have 3s lipo powering the Arduino and 4 AA batteries powering two standard size servos (not micro servos).

Yes, my bot only balances as it currently stands, but scale it up and you have a segway - just get off when you want to go in a new direction.

Here is the code:

#include servo.h

Servo myservo1; // create servo object to control a servo

Servo myservo2;

int potpin = 0; // analog pin used to connect the potentiometer

int val; // variable to read the value from the analog pin

int gyroPin = 5;

int gyroVal = 0;

int gyroAvg = 0;

void setup() { myservo1.attach(11); // attaches the servo on pin 9 to the servo object

myservo2.attach(9); // other wheel

myservo1.writeMicroseconds(1500); delay(15); myservo2.writeMicroseconds(1500); delay(15);


Serial.println("Program begin..."); }

void loop() {

val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)

val = map(val, 0, 1023, 0, 1000); // scale it to use it with the servo (value between 0 and 1000)

gyroVal = analogRead(gyroPin);

//gyroVal = map(gyroVal, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)

gyroAvg = analogRead(gyroPin) + analogRead(gyroPin) + analogRead(gyroPin) ;

gyroVal = gyroAvg / 3;

if (gyroVal > (0) and gyroVal < (val )) {

myservo1.write(180); myservo2.write(0); } //both wheels forward

else if (gyroVal > ( val ) and (gyroVal < 800)) {

myservo1.write(0); myservo2.write(180); } //both wheels backward

Serial.print(" pot: ");Serial.print(val);Serial.print(" angle: ");Serial.println(gyroVal);

//myservo.write(val); // sets the servo position according to the scaled value

delay(10); //


Be the First to Share


    • Reclaimed Materials Contest

      Reclaimed Materials Contest
    • Laser Challenge

      Laser Challenge
    • Paint Challenge

      Paint Challenge



    7 years ago on Introduction

    Hey, very nice ideas! Love that you used a basket for the wheels, and the weight below the axle is a brilliant trick.

    You can add code to your project in the editor. Click the paragraph symbol, and then "code" and this will give you a box where you can enter your code without any reformatting taking place. Just a tip! :)


    Reply 7 years ago on Introduction

    Thank you. And thank you for the formatting tip. I felt bad dissing INSTRUCTABLES about that but was so upset I had to go in there and redo the formatting. Will take that snide comment out.