jremington:

The gyroscope measures rate of change of angle, not angle, and not particularly accurately.

To estimate the total change in angle, you need to numerically integrate the gyroscope data, which introduces additional inaccuracy.

You can use an accelerometer to measure tilt angles and with great care, those measurements can be accurate to better than 1 degree.

Thanks for the reply.

That’s exactly what I do, integrating the angular velocity over time to obtain the angle. However, the numbers I get are erroneous. A friend of mine said the gyroscope sensor are only good to sense the rotation not the quantity of it. I wonder if she’s correct and if there is a tricky part I am missing when doing the calculations.

To help you better see what I do, I put the codes here:

#include <TinkerKit.h> // header for gyroscope library

TKGyro gyro(I0, I1, TK_X1); // gyroscope object with X connected to I0 and Y connected to I1, with 1x sensitivity

// Timing variables

unsigned long time;

int sampleTime = 10; // The sampling period of the gyro

//Gyroscope variables

int rollRate, pitchRate;

int prev_rollRate = 0, prev_pitchRate = 0;

long rollAngle = 0, pitchAngle = 0;

int rotationThreshold = 2; //Minimum deg/sec to keep track of, helps with gyro drifting

void setup()

{

Serial.begin(9600);

Serial.println(“Calibration…”);

gyro.calibrate();

Serial.print(“TinkerKit! Gyroscope Test Example\n\n”);

time = millis();

}

void loop()

{

// Every 10 ms take a sample from the gyro

if(millis() - time > sampleTime)

{

time = millis(); // update the time to get the next sample

// get the gyro’s angular velocity

rollRate = gyro.readYAxisRate(); // by calling the readXAxisRate() method

pitchRate = gyro.readXAxisRate(); // and the readYAxisRate() method

// Integrate the angular veloity to obtain angular position (or inclination)

// Using the trapeziod method for numerical integration.

// (previous_Rate + current_Rate) * sampleTime

// Angle = ----------------------------------------------

// 2 * 1000

// because the sampleTime is expressed in millisecndos and rate in degree

// per seconds we also need to divide by 1000 ms/s to obtain the correct units.

// Ignore the gyro if our angular velocity does not meet our threshold

if(rollRate >= rotationThreshold || rollRate <= -rotationThreshold)

rollAngle += ((long)(prev_rollRate + rollRate) * sampleTime) / 2000;

// Ignore the gyro if our angular velocity does not meet our threshold

if(pitchRate >= rotationThreshold || pitchRate <= -rotationThreshold)

pitchAngle += ((long)(prev_pitchRate + pitchRate) * sampleTime) / 2000;

// remember the current speed for the next loop rate integration.

prev_rollRate = rollRate;

prev_pitchRate = pitchRate;

// Keep our angle between 0-359 degrees

if (rollAngle < 0)

rollAngle += 360;

else if (rollAngle > 359)

rollAngle -= 360;

if (pitchAngle < 0)

pitchAngle += 360;

else if (pitchAngle > 359)

pitchAngle -= 360;

// Pint the obtained values on the serial monitor.

Serial.print("Roll_Rate: “);

Serial.print(rollRate);

Serial.print(”\tRoll_Angle: “);

Serial.print(rollAngle);

Serial.print(”\tPitch_Rate: “);

Serial.print(pitchRate);

Serial.print(”\tPitch_Angle: ");

Serial.println(pitchAngle);

}

}