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...
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...
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
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...
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?