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: GyroLISY300AL \ Learning \ Wiring 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: Arduino Playground - Gyro GyroLISY300AL \ Learning \ Wiring
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;
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.
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).
If you want stable timing don't use delay(), use millis() and test the result:
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.
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]"
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
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.
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
So its drifting down by 1.99 degrees every 220ms. So you can see how this quickly erodes the angle
Heres my 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);
}
}