Pages: [1]   Go Down
 Author Topic: Getting Angle Measurments from LISY300 gyro  (Read 3066 times) 0 Members and 1 Guest are viewing this topic.
0
Offline
Sr. Member
Karma: 0
Posts: 250
Arduino is the brain of the robot.
 « on: February 25, 2011, 02:35:55 pm » Bigger Smaller Reset

Hi,

I recently purchased the LISY300 gyro sensor from Sparkfun.com. I have a project where I need the angle data from the gyro. I have already found out how to get the rotational rate from this tutorial: http://wiring.org.co/learning/basics/gyrolisy300al.html I have tried to get the gyro's angle data through my own programming, but I am not that good. I will post the code that I tried to use to get the angle data from the gyro. The code is a combination of a few different sources: http://arduino.cc/playground/Main/Gyro
http://wiring.org.co/learning/basics/gyrolisy300al.html

If you could please help me interface the LISY300 gyro with Arduino to get the angular data... THANKS

int gyroPin = 0;               //Gyro is connected to analog pin 0
float gyroVoltage = 3.3;         //Gyro is running at 3.3V
float gyroZeroVoltage = 1.65;   //Gyro is zeroed at 1.65V
float gyroSensitivity = .0033;  //Our example gyro is mV/deg/sec
float rotationThreshold = 1;   //Minimum deg/sec to keep track of - helps with gyro drifting
int pinPowerDown = 2;  // digital pin for Power Down mode
// LOW = Normal, HIGH = Power down
float currentAngle = 0;          //Keep track of our current angle

void setup() {
pinMode(pinPowerDown, OUTPUT);
digitalWrite(pinPowerDown, LOW);  // set gyroscope to Normal
Serial.begin (9600);
}

void loop() {
//This line converts the 0-1023 signal to 0-5V
float gyroRate = (analogRead(gyroPin) * gyroVoltage) / 1023;

//This line finds the voltage offset from sitting still
gyroRate -= gyroZeroVoltage;

//This line divides the voltage we found by the gyro's sensitivity
gyroRate /= gyroSensitivity;

//Ignore the gyro if our angular velocity does not meet our threshold
if (gyroRate >= rotationThreshold || gyroRate <= -rotationThreshold) {
//This line divides the value by 100 since we are running in a 10ms loop (1000ms/10ms)
gyroRate /= 10;
currentAngle += gyroRate;
}

//Keep our angle between 0-359 degrees
if (currentAngle < 0)
currentAngle += 360;
else if (currentAngle > 359)
currentAngle -= 360;

//
Serial.println(currentAngle, DEC);

delay(10);
}

 Logged

New Hampshire
Offline
God Member
Karma: 17
Posts: 781
There are 10 kinds of people, those who know binary, and those who don't.
 « Reply #1 on: February 25, 2011, 03:11:00 pm » Bigger Smaller Reset

Quote
since we are running in a 10ms loop

That is an incorrect statement.  You have a 10ms delay in your loop, but you also have a lot more going on.  In particular, a Serial output at 9600 baud.  Even outputing a single float, that's going to take around 10ms itself, so you aren't running anywhere near a 10ms loop.
 Logged

New York
Offline
Edison Member
Karma: 1
Posts: 1023
E != m*c^2
 « Reply #2 on: February 25, 2011, 03:51:38 pm » Bigger Smaller Reset

Aside from the above, programming integration with sensors like standard gyros (what you're doing) isn't going to give you great results and, in fact, is likely to exhibit drift over an extended run time (depending on how well you implemented the integration, the extended run time might be only a few seconds).  It's usually best to "fuse" together information from multiple sensors to get a better "estimate" of what you're looking for. Your best bet would be using an accelerometer in conjunction with your gyro and implementing a Kalman filter. But that would only work for roll and pitch.

If you want to measure yaw (you were ambiguous in your post about what the orientation of your sensor is), then your best off with a digital compass, perhaps with internal tilt compensation (usually not cheap!) and some additional filtering from your gyro (just in case the compass gives off error, the gyro could be used in a Kalman filter implementation in this case as well).
 Logged

0
Online
Shannon Member
Karma: 199
Posts: 11670
Arduino rocks
 « Reply #3 on: February 25, 2011, 05:40:52 pm » Bigger Smaller Reset

If you want stable timing don't use delay(), use millis() and test the result:
Code:
int next_time = 0 ;

void loop ()
{
if (millis () - next_time >= 0)
{
next_time += 10 ;
... do some stuff ....
}
}

This way the jitter in your code won't accumulate.

I've used a trick or two to allow next_time to be an int not a long (the way the comparison is coded matters).  Use a long if you aren't worried about the extra overheads.
 Logged

[ I won't respond to messages, use the forum please ]

0
Offline
Sr. Member
Karma: 0
Posts: 250
Arduino is the brain of the robot.
 « Reply #4 on: February 25, 2011, 11:03:19 pm » Bigger Smaller Reset

I'm sorry to comment twice, but I found some new information. In this instrucatable (step 3) it shows how to get angle from angular rate. But I do not know what these variables stand for... Can someone help me out?

"Because the gyro give us the angular rate, so a simple way to get the angle is have the angular rate multiplied by the time [angle = angle + w * dt]"

http://www.instructables.com/id/Angle-measurement-using-gyro-accelerometer-and-Ar/step3/Some-extra-information-before-we-proceed/

 Logged

UK
Offline
Faraday Member
Karma: 17
Posts: 2884
Gorm deficient
 « Reply #5 on: February 26, 2011, 04:42:45 am » Bigger Smaller Reset

angle - the angle turned so far
w - the angulare rate read from the gyro
dt - delta time, the time between gyro readings

so the total angle turned is the the angle so far plus (the turn rate times the sample period)
 Logged

Per Arduino ad Astra

0
Offline
Sr. Member
Karma: 0
Posts: 250
Arduino is the brain of the robot.
 « Reply #6 on: February 26, 2011, 10:06:08 pm » Bigger Smaller Reset

The goal is to get the tilt angle in degrees˚ as seen in this video. Can anyone help? I know that a gyro outputs only a rotational rate, but I know it is possible to get the angle in degrees --->
Thanks

 Logged

Global Moderator
UK
Offline
Brattain Member
Karma: 289
Posts: 25697
I don't think you connected the grounds, Dave.
 « Reply #7 on: February 28, 2011, 05:41:58 am » Bigger Smaller Reset

Quote
I know that a gyro outputs only a rotational rate, but I know it is possible to get the angle in degrees
The "rate" is simply "degrees per second" or "radians per second" - just take the "per second" out of the expression, and you're left with the angular rotation since some datum.
 Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline
Newbie
Karma: 0
Posts: 44
 « Reply #8 on: October 01, 2011, 01:52:12 am » Bigger Smaller Reset

Can someone please help me understand where I am going wrong. I am using the above code and have added the timer using millis into the main loop. Its meant to give me the current angle of the gyro but it cycles down very quickly. I expect a bit of drift but this is massive. Heres my output

11670 83.21
11680 83.12
11690 83.02
11700 82.93
11710 82.84
11720 82.75
11730 82.66
11740 82.57
11750 82.48
11760 82.39
11770 82.30
11780 82.21
11790 82.12
11800 82.03
11810 81.94
11820 81.85
11830 81.76
11840 81.67
11850 81.58
11860 81.49
11870 81.40
11880 81.31
11890 81.22

So its drifting down by 1.99 degrees every 220ms. So you can see how this quickly erodes the angle

Heres my code

Code:
int gyroPin = 4;                 //Gyro is connected to analog pin 4
float gyroVoltage = 3.3;         //Gyro is running at 3.3V
float gyroZeroVoltage = 1.36;    //Gyro is zeroed at 1.36V
float gyroSensitivity = .002;    //Our example gyro is 2mV/deg/sec
float rotationThreshold = 5;     //Minimum deg/sec to keep track of - helps with gyro drifting

float currentAngle = 0;          //Keep track of our current angle
int timer = 0 ;                  //Keep rack of time

void setup() {
Serial.begin (115200);
analogReference(EXTERNAL);
}

void loop()
{
if (millis () - timer >= 0)
{
timer += 10 ;
float gyroRate = (analogRead(gyroPin) * gyroVoltage) / 1023;

//This line finds the voltage offset from sitting still
gyroRate -= gyroZeroVoltage;

//This line divides the voltage we found by the gyro's sensitivity
gyroRate /= gyroSensitivity;

//Ignore the gyro if our angular velocity does not meet our threshold
if (gyroRate >= rotationThreshold || gyroRate <= -rotationThreshold)
{
//This line divides the value by 100 since the timer gives a 10ms loop (1000ms/10ms)
gyroRate /= 100;
currentAngle += gyroRate;
}

//Keep our angle between 0-359 degrees
if (currentAngle < 0)
currentAngle += 90;
else
if (currentAngle > 89)
currentAngle -= 90;

//DEBUG
Serial.print(timer);
Serial.print(" ");
Serial.println(currentAngle);
}
}

Thanks in advance
 Logged

Physics is an elephant, you just have to go fast enough.

0
Online
Shannon Member
Karma: 199
Posts: 11670
Arduino rocks
 « Reply #9 on: October 01, 2011, 07:17:47 pm » Bigger Smaller Reset

Can you post the exact code?  Using the # button?
 Logged

[ I won't respond to messages, use the forum please ]

Offline
Newbie
Karma: 0
Posts: 44
 « Reply #10 on: October 02, 2011, 01:54:44 am » Bigger Smaller Reset

Im a bit confused Mark. The code I am having problems with was as the bottom of the last post.
 Logged

Physics is an elephant, you just have to go fast enough.

 Pages: [1]   Go Up
Jump to: