Self Balancing Robot - Bang Bang Control

by JimRD in Circuits > Robots

5615 Views, 13 Favorites, 0 Comments

Self Balancing Robot - Bang Bang Control

Self Balancing Robot - Bang Bang Control - Mini Segway
SBR1.JPG
SBR2.JPG
SBR4.JPG
SBR3.JPG

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.begin(9600);

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

}