Self Balancing Gyroscope V3 Using Arduino and Pot for Tilt Sensor

by JimRD in Circuits > Robots

7985 Views, 41 Favorites, 0 Comments

Self Balancing Gyroscope V3 Using Arduino and Pot for Tilt Sensor

Version 3 b.JPG
Version 3 a.JPG
Gyro Version 2 b.JPG
gyro balancing on tips.jpg
Here is the continuing saga of my gyroscope - in this version I use an Arduino Uno and a potentiometer to swing a counter weight to balance a precessing gyroscope so that it will balance indefinitely on two chopsticks.
Now that it is balancing itself I guess I will add back the wheels and take it for a spin.

Photo 1: shows the Arduino Uno connected to pc and to servo and to a 10k potentiometer which measures the tilt of the gyroscope rotor. The program tries to keep the rotor level which will in turn keep the gyro balancing on the two chopsticks.
Note: for a gyroscope to balance on the chopsticks the Center of Mass (COM) must be about a centimeter above the rotor - a point that took me a while to discover.
Photo 2:  shows a closeup of the potentiometer connected to the gimbal axis of the gyroscope. It works very well and is an accurate indicator of the angle of the rotor.
Photo 3:  is a closeup of the servo counter weight mechanism.
Photo 4:  is a university gyro that gave me an idea of how to make mine.

Here is the full program:
Servo signal is connected to pin 9 and the pot middle terminal is connected to A2. Also you must connect servo power and ground and the two outer pot pins to 5volt and grnd on the Arduino. 
The gyro motor is powered separately to prevent interference with the Arduino though it could probably be powered by the PWM of the Arduino.
//******************************************************************************************************
#include
Servo servo1;
int servangle = 0; // servo angle variable
int potPin = 2;    // select the input pin for the potentiometer
int ledPin = 13;   // select the pin for the LED
int val = 0;       // variable to store the value coming from the sensor
int valInc = 4;
int currAngle = 0;
int newAngle = 0;
int delayTime = 0;

void myServo(int curAngle,int newAngle,int angleInc,int incDelay) {
  if (curAngle < newAngle) {
   for(int angle=curAngle;angle < newAngle;angle += angleInc) {
         servo1.write(angle);
        delay(incDelay);   }
   }
   else if (curAngle > newAngle) {
      for(int angle=curAngle;angle > newAngle;angle -= angleInc) {
         servo1.write(angle);
        delay(incDelay);   }
   }
}
void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);  // declare the ledPin as an OUTPUT
servo1.attach(9);
servo1.write(90);
}

void loop() {
  val = analogRead(potPin);    // read the value from the pot sensor
  delayTime = 10;
 
  if (val >= 420 && val <= 435)   digitalWrite(ledPin, HIGH);  // turn the ledPin on
  else digitalWrite(ledPin, LOW);   // turn the ledPin off
 
  if (val >= 420 && val <= 435)     { newAngle = 90; delayTime = 40;}
  else if (val >= 300 && val < 410) { newAngle = 50; delayTime = 1000; }//force back down
  else if (val > 445 && val < 500) { newAngle = 130; delayTime = 1000;}// force front up
  //Serial.print(val); Serial.print(" ang: "); Serial.println(newAngle);
  if (newAngle != currAngle) {
     myServo(currAngle,newAngle,1,10);
     Serial.print(val); Serial.print(" ang: "); Serial.println(newAngle);
     currAngle = newAngle;
     delay(delayTime);
           }
  }
//******************************************************************************************************