Pages: 1 ... 4 5 [6] 7 8 ... 35   Go Down
Author Topic: Guide to gyro and accelerometer with Arduino including Kalman filtering  (Read 241045 times)
0 Members and 3 Guests are viewing this topic.
Torino, Italy
Offline Offline
Sr. Member
****
Karma: 2
Posts: 312
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Supposing that the algorithm you have here is correct, the problem you are experiencing may be related to the axis of your sensors as not being aligned. Check your sensors datasheet for pictures of the sensors axis and check that your IMU has them aligned. If they are not, you can align them later in software by swapping X and Y and/or signs.
Logged

0
Offline Offline
Newbie
*
Karma: 1
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You were right, everything is working perfectly now smiley

Thanks for your comments.
Logged

Torino, Italy
Offline Offline
Sr. Member
****
Karma: 2
Posts: 312
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Awesome! Plasure to be helpful.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I am trying to use this code/setup to look at the forces acting on snowboarders while going through a turn. I have setup the 6DOF chip from Sparkfun, just as the tutorial describes. But when I load the code and open up processing the graph only shows a flat red line. It does not react to moving the Razor. I have also tried looking at the serial output of the Arduino code and that shows simply all 0's. I am pretty experienced with Arduinos but I have not played much with accelerometers and gyros before so I may be over looking something simple.

Thanks in advance for any help! And for all of the great info!
-Builditnow
Logged

Denmark
Offline Offline
Sr. Member
****
Karma: 8
Posts: 282
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello
It sounds like, its not sending anything. Are you sure, that you are getting the data? Or even getting the data? Have you uncomment this line:
Code:
processing();
? smiley
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are talking about the "processing()" at the end of the IMU6DOFVer2, than yes that is uncommented. As far as I can tell it was never commented out. Thanks for the patience!
Logged

Denmark
Offline Offline
Sr. Member
****
Karma: 8
Posts: 282
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you connected the IMU the right way, please double check smiley It sounds like your not getting the data for some reason..
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I am getting data now! I took the razor off of the proto-shield I was using and just set it up on a breadboard. Except now my graph looks very erratic. It will react to movement but it will not react as predictably as the graph appears to in the video. Any advice?

Thanks
-builditnow  
Logged

Denmark
Offline Offline
Sr. Member
****
Karma: 8
Posts: 282
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Are you sure, that you are sending the right data, you might have swopped some of the data? You have to troubleshoot it yourself, or give me some more information, as I will gladly help you out smiley-wink
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Lauszus,

First - thank you for sharing your work!

I picked up a 6DOF razor and thought I'd try your code before I dug into it...

I'm getting nothing from the serial port running IMU6DOF2.  (Arduino 022, 168-based board)

I confirmed connections are correct.  processing(); is _not_ commented out.  It compiles and uploads fine, then sits like a bump on a log.

So I stripped it down to the essentials.  I get some data, but I'm not sure it's sensible.  Here's "the essentials" and the datastream I get:

Code:
//made by Kristian Lauszus - see http://arduino.cc/forum/index.php/topic,58048.0.html for information
#define gX A0
#define gY A1
#define gZ A2

#define aX A3
#define aY A4
#define aZ A5

#define RAD_TO_DEG 57.295779513082320876798154814105

//gyros
int gyroZeroX;//x-axis
float gyroXadc;
float gyroXrate;
float gyroXangle;

int gyroZeroY;//y-axis
float gyroYadc;
float gyroYrate;
float gyroYangle;

int gyroZeroZ;//z-axis
float gyroZadc;
float gyroZrate;
float gyroZangle;


//accelerometers
int accZeroX;//x-axis
float accXadc;
float accXval;
float accXangle;

int accZeroY;//y-axis
float accYadc;
float accYval;
float accYangle;

int accZeroZ;//z-axis
float accZadc;
float accZval;
float accZangle;

//Results
float xAngle;
float yAngle;
float compAngleX;
float compAngleY;

float R;//force vector
//Used for timing
unsigned long timer=0;
unsigned long dtime=0;

void setup()
{
  analogReference(EXTERNAL); //3.3V
  Serial.begin(115200);
  delay(100);//wait for the sensor to get ready
  timer=millis();//start timing
}
void loop()
{
  gyroXadc = analogRead(gX);
  gyroXrate = (gyroXadc-gyroZeroX)/1.0323;//(gyroXadc-gryoZeroX)/Sensitivity - in quids              Sensitivity = 0.00333/3.3*1023=1.0323
  gyroXangle=gyroXangle+gyroXrate*dtime/1000;//Without any filter
 
  gyroYadc = analogRead(gY);
  gyroYrate = (gyroYadc-gyroZeroY)/1.0323;//(gyroYadc-gryoZeroX)/Sensitivity - in quids              Sensitivity = 0.00333/3.3*1023=1.0323
  gyroYangle=gyroYangle+gyroYrate*dtime/1000;//Without any filter
 
  gyroZadc = analogRead(gZ);
  gyroZrate = (gyroZadc-gyroZeroZ)/1.0323;//(gyroZadc-gryoZeroX)/Sensitivity - in quids              Sensitivity = 0.00333/3.3*1023=1.0323
  //gyroZangle=gyroZangle+gyroZrate*dtime/1000;//Without any filter
 
  accXadc = analogRead(aX);
  accXval = (accXadc-accZeroX)/102,3;//(accXadc-accZeroX)/Sensitivity - in quids              Sensitivity = 0.33/3.3*1023=102,3
 
  accYadc = analogRead(aY);
  accYval = (accYadc-accZeroY)/102,3;//(accXadc-accZeroX)/Sensitivity - in quids              Sensitivity = 0.33/3.3*1023=102,3
 
  accZadc = analogRead(aZ);
  accZval = (accZadc-accZeroZ)/102,3;//(accXadc-accZeroX)/Sensitivity - in quids              Sensitivity = 0.33/3.3*1023=102,3
  accZval++;//1g in horizontal position
 
  R = sqrt(pow(accXval,2)+pow(accYval,2)+pow(accZval,2));//the force vector
  accXangle = acos(accXval/R)*RAD_TO_DEG-90;
  accYangle = acos(accYval/R)*RAD_TO_DEG-90;
  //accZangle = acos(accZval/R)*RAD_TO_DEG;
 
  //used for debugging
  Serial.print(gyroXrate,0);Serial.print("\t");
  Serial.print(gyroYrate,0);Serial.print("\t");
  Serial.print(gyroZrate,0);Serial.print("\t");

  Serial.print(gyroXangle,0);Serial.print("\t");
  Serial.print(gyroYangle,0);Serial.print("\t");
  Serial.print(gyroZangle,0);Serial.print("\t");

  Serial.print(accXval,2);Serial.print("\t");
  Serial.print(accYval,2);Serial.print("\t");
  Serial.print(accZval,2);Serial.print("\t");

  Serial.print(accXangle,0);Serial.print("\t");
  Serial.print(accYangle,0);Serial.print("\t");
  //Serial.print(accZangle,0);Serial.print("\t");

  Serial.print("\n");
 
  dtime = millis()-timer;
  timer = millis();



Here's a sample of the data sitting on my desk:

Code:
159 363 382 9184 9231 0 5.70 5.04 6.60 -34 -30
157 368 378 9185 9234 0 5.72 5.01 6.59 -35 -30
161 375 374 9186 9236 0 5.68 4.98 6.61 -34 -30
167 384 367 9187 9239 0 5.61 5.00 6.66 -34 -30
170 396 359 9188 9241 0 5.57 5.06 6.68 -34 -30
170 410 354 9189 9244 0 5.58 5.08 6.61 -34 -30
175 418 351 9190 9246 0 5.63 5.09 6.49 -34 -31
181 422 351 9192 9249 0 5.68 5.11 6.45 -35 -31
187 425 354 9193 9252 0 5.71 5.14 6.40 -35 -31
192 426 358 9194 9254 0 5.75 5.16 6.32 -35 -31

I mention that I'm not sure it's sensible (and that may just be due to a lack of calibration?) because, if we look at the last line:

gyroXrate: 192
gyroYrate: 426
gyroZrate: 358
gyroXangle: 9194  [!!!]
gyroYangle: 9254
gyroZangle: 0
AccX: 5.75
AccY: 5.16
AccZ: 6.32
AccXAngle: -35
AccYAngle: -31

Clearly that looks "a little funny"...

If you'd like to compare the project I'm running (entirely unchanged), I pushed the zip file here:
http://www.jlrdesigns.com/IMU6DOFVer2.zip

Thanks for any advice!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Now that I read what I wrote...

Does this really work?

accXval = (accXadc-accZeroX)/102,3;//(accXadc-accZeroX)/Sensitivity - in quids              Sensitivity = 0.33/3.3*1023=102,3

I know that's used as a decimal outside of the US, but ANSI C would puke on that for sure...  And why do you use a decimal elsewhere, but a comma decimal separator in those?

Code:
gyroZrate = (gyroZadc-gyroZeroZ)/1.0323;//(gyroZadc-gryoZeroX)/Sensitivity - in quids              Sensitivity = 0.00333/3.3*1023=1.0323

  
  accXadc = analogRead(aX);
  accXval = (accXadc-accZeroX)/102,3;//(accXadc-accZeroX)/Sensitivity - in quids              Sensitivity = 0.33/3.3*1023=102,3
  
  accYadc = analogRead(aY);
  accYval = (accYadc-accZeroY)/102,3;//(accXadc-accZeroX)/Sensitivity - in quids              Sensitivity = 0.33/3.3*1023=102,3

Thanks!

[edit]  Ok - that doesn't work, as I expected.

Code:
float test1;
float test2;
float test3;

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

void loop()
{
  test1=2.4;
  test2=5,75;
test3 = test1*test2;

Serial.print(test3);Serial.print("\n");
}

Output = 12.0 == 2.4*5.0 != 2.4*5.75

2.4 * 5.75 = 13.8

Am I missing something?  Have you gotten the code you uploaded running?  Would you decompress and verify that it does run?  Thanks again!
« Last Edit: July 30, 2011, 01:20:13 am by lara » Logged

Denmark
Offline Offline
Sr. Member
****
Karma: 8
Posts: 282
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You have to include this in the setup() function:
Code:
  //calibrate all sensors in horizontal position
  gyroZeroX = calibrateGyroX();
  gyroZeroY = calibrateGyroY(); 
  gyroZeroZ = calibrateGyroZ();
 
  accZeroX = calibrateAccX();
  accZeroY = calibrateAccY();
  accZeroZ = calibrateAccZ();
If you look in the original code it is there!
Also it would be a good idea to change:
Code:
int gyroZeroX;//x-axis
int gyroZeroY;//y-axis
int gyroZeroZ;//z-axis
int accZeroX;//x-axis
int accZeroY;//y-axis
int accZeroZ;//z-axis
To float values, as this will give higher precision.

I do not know why the code you linked to does not work. Try downloading the original software again from my post, as this works! Then when you have it up and running modify the code for your needs smiley
« Last Edit: July 30, 2011, 03:54:02 am by Lauszus » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am using your original code.  As linked in the zip file I linked to.

The upshot is:

Using a comma for a decimal doesn't work.  Returns the wrong values.

Calling any two calibrates work fine.  The instant we call a third calibrate, it goes away and never comes back.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This works:

Code:
  //calibrate all sensors in horizontal position
  Serial.print("DEBUG: Calling Calibration \n");
  gyroZeroX = calibrateGyroX();
  gyroZeroY = calibrateGyroY(); 
//  gyroZeroZ = calibrateGyroZ();
 
//  accZeroX = calibrateAccX();
//  accZeroY = calibrateAccY();
//  accZeroZ = calibrateAccZ();
 Serial.print("DEBUG: Return from Calibrations");
  timer=millis();//start timing

This works:

Code:
  //calibrate all sensors in horizontal position
  Serial.print("DEBUG: Calling Calibration \n");
//  gyroZeroX = calibrateGyroX();
  gyroZeroY = calibrateGyroY(); 
  gyroZeroZ = calibrateGyroZ();
 
//  accZeroX = calibrateAccX();
//  accZeroY = calibrateAccY();
//  accZeroZ = calibrateAccZ();
 Serial.print("DEBUG: Return from Calibrations");

This never makes it to the second Debug, just goes away and never comes back.

Code:
  //calibrate all sensors in horizontal position
  Serial.print("DEBUG: Calling Calibration \n");
  gyroZeroX = calibrateGyroX();
  gyroZeroY = calibrateGyroY(); 
  gyroZeroZ = calibrateGyroZ();
 
//  accZeroX = calibrateAccX();
//  accZeroY = calibrateAccY();
//  accZeroZ = calibrateAccZ();
 Serial.print("DEBUG: Return from Calibrations");
  timer=millis();//start timing

Doesn't matter which third one we add in, I've cycled all of them in every combination.  Any two work, any three (or more) fail to ever come back.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yup, back again using:

http://www.jlrdesigns.com/IMU6DOFVer2.zip

which is my local copy of:

https://rapidshare.com/files/1073395588/IMU6DOFVer2.zip

which is the same as:

http://www.instructables.com/files/orig/FYG/4OVJ/GN77W1DR/FYG4OVJGN77W1DR.zip

Never makes it through calibration.  Just goes away forever and never comes back.

I'll try your version 1 and see if it makes it.

[edit to note:]

IMU6DOF has the same problem(s) as IMU6DOF2. 
« Last Edit: July 30, 2011, 04:54:30 am by lara » Logged

Pages: 1 ... 4 5 [6] 7 8 ... 35   Go Up
Jump to: