Guide to gyro and accelerometer with Arduino including Kalman filtering

The only suggestions, I can give is to try using my code instead, as it is confirmed to work! :slight_smile:

I found some interesting functions for the calculation of angles between 0 and 360°. They work almost perfect. perhaps you can help me to improve them :wink:

alpha = atan( Ax /(sqrt( Ay^2 + Az^2 ) ) )
beta = atan( Ay /(sqrt( AX^2 + Az^2 ) ) )

Ai = Accelero data

alpha = roll
beta = pitch

i´m doing stuff in scilab, so i cant give you c-code ]:smiley:

a short pdf about this stuff:

http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00268887.pdf

It's the same as the original one. It's only 180 degrees of resolution too :confused:

did you use atan2 insteadt of atan? in scilab atan = atan2 ... sry to confuse you

Yes I used atan (or arctan) as the document says at page 13 :slight_smile:

@ Lauszus Im trying to use your code with an I2c gyro and accelerometer but the sensitivity is given in lowest significant bit, would you know how to apply this?
Im using
gyro ITG 3200 with sensitivity 14.375 LSB/(º/s)
accelerometer BMA180 the sensitivity varies with the G but at 1 g is 8192 LSB/g

@cristo829
Hi
You should have a look at the dialog I had with "Kashif" starting at this link: Guide to gyro and accelerometer with Arduino including Kalman filtering - #111 by system - Sensors - Arduino Forum. He is using the same gyro as you (ITG3200), but not the same accelerometer though (ADXL345). This is the IMU: SparkFun 6 Degrees of Freedom IMU Digital Combo Board - ITG3200/ADXL345 - SEN-10121 - SparkFun Electronics.

If you follow the dialog, I think you will get it working. Just remember to change the values for the accelerometer!

Alternative send him a PM and ask for his code..

If you need more help, just send another reply and I will try to help you as best I can :smiley:

Great thanks :slight_smile:

I'm using this sensor combination (FreeIMU 0.3.5MS) also - you can just feed the raw values from the BMA accelerometer into the filter. There's no need to scale the sensitivity, although it makes no difference if you do. Also, if you're using up to 4G sensitivity, there's no need to calibrate (ie subtracting the offsets). The BMA seems to have a fairly accurate calibration I've found.

So you changed this:
gyroX = analogRead(gX);
gyroXrate = (gyroX-gyroZeroX)/1.0323;//(gyroX-gryoZeroX)/Sensitivity Sensitivity = 0.00333/3.31023=1.0323
gyroXangle += gyroXrate
dtime/1000;

to this?

(read x value on i2c gyro)
gyroXrate = (gyroX-gyroZeroX)
gyroXangle += gyroXrate*dtime/1000;

Im building a qudcopter, how many Gs do you think is a good idea to use on the BMA? Also, have you programmed the Magnetometer on your IMU im having some trouble with the tilt compensation, my measurement varies within 10 degrees when i tilt it which is finw for me, except when i tilt it to one specific side when i tilt it that way it varies something like 40 degrees is this normal?
Thanks for your help

I'm using 3G for my quad, this seems to be a good compromise between pitch/roll accuracy and sensitivity to noise. If you try 1.5G, you might find it too sensitive to vibrations.

I have used the mag, I have to calibrate it by working out the offsets. The best accuracy I've got has been a calibration with the sensor in place and all four motors running (without props on obviously). I get pretty good stable results with the MARG algorithm as part as the FreeIMU library, but I haven't recently tried tilt compensation calculations with my current offsets so can't really comment on how well this works.

Your gyro code looks ok to me.

cristo829:
So you changed this:
gyroX = analogRead(gX);
gyroXrate = (gyroX-gyroZeroX)/1.0323;//(gyroX-gryoZeroX)/Sensitivity Sensitivity = 0.00333/3.31023=1.0323
gyroXangle += gyroXrate
dtime/1000;

to this?

(read x value on i2c gyro)
gyroXrate = (gyroX-gyroZeroX)
gyroXangle += gyroXrate*dtime/1000;

Im building a qudcopter, how many Gs do you think is a good idea to use on the BMA? Also, have you programmed the Magnetometer on your IMU im having some trouble with the tilt compensation, my measurement varies within 10 degrees when i tilt it which is finw for me, except when i tilt it to one specific side when i tilt it that way it varies something like 40 degrees is this normal?
Thanks for your help

Thanks AntR ill try that

Hello everyone --

I'm really glad to find this thread so active. I'm currently working on a project that involved tracking the orientation and position of an object.

I've got an ADXL345 accelerometer, ITG-3200 gyro and an HMC5883L magnetometer.

I've gotten Fabio Varesano's awesome code working which is giving me great position information.

But I'm hoping someone on this thread can point me to some code that I can use to get a good measurement of velocity so I can calculate position.

Thanks in advance.

I would be possible using the accelerometers and then multiply it with one g and the delta time. But you have to do some math to compensate for rotation. Please post the code if you get it working :slight_smile:

Hey,

I'm using this LISY300AL Gyro: http://www.sparkfun.com/datasheets/Sensors/LISY300AL.pdf
But i cant get a precise data..

Here is my calculation:

    sensitivity = 0.716454545;
    gyroAdc = analogRead(0);
    if(abs(gyroAdc - gyroZero) <= Threshold)
      gyroAdc = gyroZero;
    gyroRate = (gyroAdc-gyroZero)/sensitivity;
    gyroRotation=gyroRotation+gyroRate*dtime1/1000;
    gyroAngle = abs((gyroRotation - 360 * ceil(gyroRotation / 360))); // Round up between 0-360
    dtime = millis() - stime;
    stime = millis();

I dont get a precise angle, i move my object 90 degrees but the gyro drifts too much so it showes something else...
Maybe i'm doing something wrong ? or i should just add an Accelerometer to make it more precise ?

First of all, how did you calculate your sensitivity?
If you use either 3.3 or 5 volt as reference, it's either:
0.0033/3.31023=1.023
or
0.0033/5
1023=0.67518
As the sensor has a sensitivity of 3.3 mV/ °/s
Or do you use a different reference? As i can calculate you use 4.711952801 volt as reference (0.0033/4.711952801*1023=0.716454545).

Why do you need this line:

gyroAngle = abs((gyroRotation - 360 * ceil(gyroRotation / 360))); // Round up between 0-360

What you call "gyroRotation", is actually the angle :slight_smile:

For more precision use integration.
Something like this would work:

#define OFFSET 0.0005

gyroRaw = analogRead(0);
gOffset = OFFSET * gyroRaw + (1-OFFSET) * gOffset;
gyroSpeed = (gyroRaw - gOffset)/sensitivity;

gyroAngle += gyroSpeed*dtime/1000;

See this page for more information: http://www.hitechnic.com/blog/gyro-sensor/htway/

Regards
Lauszus

Lauszus:
First of all, how did you calculate your sensitivity?
If you use either 3.3 or 5 volt as reference, it's either:
0.0033/3.31023=1.023
or
0.0033/5
1023=0.67518
As the sensor has a sensitivity of 3.3 mV/ °/s
Or do you use a different reference? As i can calculate you use 4.711952801 volt as reference (0.0033/4.711952801*1023=0.716454545).

Why do you need this line:

gyroAngle = abs((gyroRotation - 360 * ceil(gyroRotation / 360))); // Round up between 0-360

What you call "gyroRotation", is actually the angle :slight_smile:

For more precision use integration.
Something like this would work:

#define OFFSET 0.0005

gyroRaw = analogRead(0);
gOffset = OFFSET * gyroRaw + (1-OFFSET) * gOffset;
gyroSpeed = (gyroRaw - gOffset)/sensitivity;

gyroAngle += gyroSpeed*dtime/1000;




See this page for more information: http://www.hitechnic.com/blog/gyro-sensor/htway/

Regards
Lauszus

Hey, thanks for the replay.

I'm using 3.3v so i changed the sensitivity to 1.023, now the numbers are even less precise.
the gyroZero after calibration is around 325, and the gyro goes about -+300.

I removed the gyroAngle = abs((gyroRotation - 360 * ceil(gyroRotation / 360))); // Round up between 0-360

When i use this:

#define OFFSET 0.0005

gyroRaw = analogRead(0);
gOffset = OFFSET * gyroRaw + (1-OFFSET) * gOffset;
gyroSpeed = (gyroRaw - gOffset)/sensitivity;

gyroAngle += gyroSpeed*dtime/1000;

The numbers goes crazy and keep going up even when the gyro doesn't move.

Bottom line:
Sensitivity = 1.023 - When i move my object 90 Degrees, the gyro showes 50-55 Degrees.
Sensitivity = 0.716454545 - When i move my object 90 Degrees, the gyro showes 83-88 Degrees.

Those drifts just getting worse every move so after few movements the gyro isn't helpfull.

Any ideas ?

Have you remembered to connect 3.3 Volt to the VREF pin on the Arduino? :slight_smile:

Regards
Lauszus

Lauszus:
Have you remembered to connect 3.3 Volt to the VREF pin on the Arduino? :slight_smile:

Regards
Lauszus

I used this guide: GyroLISY300AL \ Learning \ Wiring
I connected the VCC on the gyro to the Arduino 3.3v pin.

Is that what you ment ?

No you have to connect 3.3V to the VREF/AREF pin on the Arduino.

Regards
Lauszus