trying to get to work lisy gyro... float issues etc...

hi there

I'm trying to use a lisy gyro to integrate the heading of my robot. please look at my code.
would you say this is the way to go? and then I have an issue with float values. I'll explain
that in code...

int gyroPin = 0;
float gyroData;

float gyroDefault;
float rotationSpeed; // degrees/sec
float rotationSpeedAvg;
boolean sampleGyro;

unsigned long currentTime;
unsigned long pastTime;

float sampleCount;
float gyroHeading;

void readGyro(){

  if(sampleGyro == false){

    Serial.println("warming up...");
    delay(5000);

    for(int i = 0; i < 10; i++){
      gyroData = analogRead(gyroPin);
      gyroDefault = gyroDefault + gyroData;
      delay(50);
    } 

    gyroDefault = gyroDefault/10.0;
    Serial.print("GyroDefault: ");
    Serial.println(gyroData);
    sampleGyro = true;

  }

  gyroData = analogRead(gyroPin);

  if(gyroData < gyroDefault){
    rotationSpeed = (gyroDefault - gyroData)*(1023.0/600.0); // maximum of the gyro is 300°/sec in both directions
  }

  else{
    rotationSpeed = -(gyroData - gyroDefault)*(1023.0/600.0);
  }

///
OK, until here the code runs fine. I can print out the rotationSpeed and it gives me the degrees/sec. problems start in the next part...
///
  currentTime = millis();

  if(currentTime < pastTime + 100){
    rotationSpeedAvg = rotationSpeedAvg + rotationSpeed; ///HERE: all types are float, but adding the values just results in 0.00. why is that?
    sampleCount++;
  }
  else{

    rotationSpeedAvg = rotationSpeedAvg/sampleCount;
    gyroHeading = gyroHeading + rotationSpeedAvg/10.0; // before I sampled every second, so I didn't need float. I wanted to increase response/accuracy by sampling every 10th of a second... 


    pastTime = millis();
    sampleCount = 0;
    rotationSpeedAvg = 0;

  }

  //Serial.print("heading: ");
  //Serial.println(gyroHeading);
}

thanks for your help. this is the first time I work with gyros.
just using ints gives me more or less exact results, but depending
alot on how fast I turn the gyro. help is appreciated as always...

greetings
yves

I'd venture a guess that perhaps you're overflowing the float somewhere along the way. is there a reason you can't use an int multiplied up until you're ready to output a number? just my 2 cents

thanks for your reply, I didn't think of that, but maybe that's really the issue...
I guess I'll try to avoid floats in the future :).

can anyone comment on how I'm handling the gyro integration? I really don't have
any experience with gyros. I don't really know if I did understand everything right,
and I'm not sure if the lack of precision is part of my code or just the way gyros work...

thanks
yves

I can say gyros wont be precise. Especially not the cheap ones. If you run a moving avg or a median filter over the data you might get slightly more accurate (more resistant to change) number but that's a lot for the micro to handle

Where is the time integration?

I'm taking samples every 1 seconds right now, and then integrate.
because it's the average of all the samples taken during second
*1 second you don't see the integration. at least that's how I
understand how this should work. maybe I'm wrong?

I'm glad for any advice in this...

(I'll also use a magnetometer for heading calculation, I hope
that'll help to get more precise heading information)

I just went over my code and I think it runs pretty well already...
I realized I did it far too complicated, and also, I had a delay in
the main loop which of course destroyed my results. As I said it
runs pretty good already, I'm just not so sure about some values...

here you go:

  if (millis() >= pastTime + 50){ // every 50 milliseconds
    gyroData = analogRead(gyroPin);
    pastTime = millis();

    if(gyroData < gyroDefault){
      rotationSpeed = (gyroDefault - gyroData);
    }

    else{
      rotationSpeed = -(gyroData - gyroDefault);
    }

    if(rotationSpeed > 3 || rotationSpeed < -3){ //threshold
      rotationSpeedAvg = rotationSpeedAvg + rotationSpeed;
    }

ok, about this part I'm not so sure. I divide the added values by 20, because I sampled
every 50 milliseconds (or 20 samples/second). the main issue I have is the scale factor.
I assume the following: there are 1024 possible values, the sensor outputs a maximum
of 300 degrees/sec in positive and negative direction. that leads to a total possible degrees
of 601 degrees. dividing 1024 by 601 gives me the degree/sec/analog value. correct?

    gyroHeading = (rotationSpeedAvg/20)*(1024/601); //2*300 degrees + 0 degrees

    Serial.print("heading: ");
    Serial.println(gyroHeading);
  }