Self Balancing Robot - Bang Bang Control
5615 Views, 13 Favorites, 0 Comments
Self Balancing Robot - Bang Bang Control
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); //
}