### ArduIMU V3 all axes output wrong values!

I cannot believe that I'm the only one who noticed that!  I would write it off as a faulty device but I've got two brand new once here that produce identical output with the same unmodified firmware (V1.9)

Here is the description of the problem:

1. Initialize IMU level
2. Slowly turn 90 in roll
4. Slowly turn -90 in roll
6. Repeat for pitch and yaw (yaw rotate 360 in 90 deg increments)

Each axis output should correspond to the number of degrees turned.  Instead I get the following:

Roll reading: actual roll: - 90 deg -> RLL output: - 120
+  90 deg -> RLL output: + 120
Pitch reading: actual pitch: -90 deg -> PCH output: -50 (goes from 0 to -89 and then decreases to -50)
+90 deg -> PCH output: +50 (goes from 0 to 89 and then decreases to 50)
Yaw reading: actual yaw:  0 deg -> YAW output: 180
90 deg -> YAW output: 108
180 deg -> YAW output: 45
270 deg -> YAW output: -40
360 deg -> YAW output: -180

#### Replies

• I am not sure about the unit you are speaking . Gyro provides three values : roll, pitch and yaw each in degrees. Shift the body by a known angle(eg 90 degrees) and identify change in angle (eg yaw). The actual chnage should be 90. The difference is the error. If u r performing experiment to obtain some other information out of gyros( other then angular change in roll,pitch, yaw) then i am unaware to that

Thanks,

Himanshu

• Keep the object stationary and observe the readings. This will help u to determine error introduced in each set of observation. subtract the error to obtain true values.
• the tan,sin,cos are multiplied by 1.9--- delete this 1.9 so in the last part in DCM
void Euler_angles(void)
{
#if (OUTPUTMODE==2) // Only accelerometer info (debugging purposes)
roll = atan2(Accel_Vector,Accel_Vector); // atan2(acc_y,acc_z)
pitch = asin((Accel_Vector)/(double)GRAVITY); // asin(acc_x)
yaw = 0;
#else
pitch = asin(DCM_Matrix);
roll = atan2(DCM_Matrix,DCM_Matrix);
yaw = atan2(DCM_Matrix,DCM_Matrix);
#endif
}

• Hey,
I am not using DCM algo for arduIMU v3 cause it is not giving me correct anglular orientation.
I have used only MPU6000 for orientation calculation.
The function for used for calculation gyro angle is as below:

void Get_Gyro_Rates(unsigned long dt)
{
gyroXRaw = ((byte_H<<8)| byte_L) - GYRO_XOUT_OFFSET;
gyroYRaw = ((byte_H<<8)| byte_L) - GYRO_YOUT_OFFSET;
gyroZRaw = ((byte_H<<8)| byte_L) - GYRO_ZOUT_OFFSET;

gyroXRate = (float)gyroXRaw/gyro_xsensitivity*dt*0.001;
gyroYRate = (float)gyroYRaw/gyro_ysensitivity*dt*0.001;
gyroZRate = (float)gyroZRaw/gyro_zsensitivity*dt*0.001;
//if(abs(gyroXRaw)>1)
GYRO_XANGLE += gyroXRate;
//if(abs(gyroYRaw)>1)
GYRO_YANGLE += gyroYRate;
//  if(abs(gyroZRaw)>1)
GYRO_ZANGLE += gyroZRate;
Serial.print(GYRO_XANGLE);
Serial.print(" ");
Serial.println(GYRO_ZANGLE);
}

here, I am am continuously getting increments or decrements in each angle..
If you can help please suggest me the best way to use arduIMU v3..?

• Artem,

I just wanted to confirm that the two simple changes (GRAVITY=8192 and the two gain changes) are all that is required for you an ArduIMU 1.9.8 (neglecting YAW improvements - I don't use a GPS). I will retest my measurements - do you go all the way near 90 deg or just to maybe 45 deg.

Do you have any expectations of whether it will drift much as long as the rotation rates are low?

I appreciate your expertise in this - don't you think that whoever is responsible for the code should make your changes and release it.

• It is Nov 20, 2012 and I am testing a V3 board. I added Artem's two fixes in the ArduIMU.pde :

1)

#if BOARD_VERSION == 3
#define SERIAL_MUX_PIN 7
#define RED_LED_PIN 5
#define BLUE_LED_PIN 6
#define YELLOW_LED_PIN 5   // Yellow led is not used on ArduIMU v3
// MPU6000 4g range => g = 4096
#define GRAVITY 8192

...

2)

// WAS  #define Kp_ROLLPITCH 0.015
// WAS  #define Ki_ROLLPITCH 0.000010
#define Kp_ROLLPITCH 1.515/GRAVITY
#define Ki_ROLLPITCH 0.00101/GRAVITY

and the roll/pitch seem smooth but I still get wrong values. At roll = 30, I get about 45 on printout and for pitch = 30, I get about 40 deg on the Serial Monitor printout. Anybody else get the same? I know I am actually compiling the new source just by changing the Version printout text slightly e.g. "1.9X" I started with the 1.9.8 download.

• I have to say, I'm really disappointed in my purchase of this board. I wish the product pages where it's purchasable indicated that the software doesn't work out of the box (so to speak) with v3. Why is the official code not compatible with v3?

Using the gimbal code at https://code.google.com/p/gimbal-controler/ I am able to get mostly good data out of my IMU. I can't, however, get anything worth using out of the real software, even with the fixes mentioned in this thread. The best I have gotten so far is to have roll approach 120 and pitch to go up rather unintuitively while I'm performing pure roll movements. I also get a pile of binary data spew with some occasional new lines thrown into good data.

For example, just sitting on my desk, I got the following output:

http://pastebin.com/GhuM2nFy

I am using a v3 with MPU6000_REV_D8 as reported by gimbal-controller.

• Hi!

Recently we have bought an arduimu with an GPS (Mediatek), I have downloaded the last version of firmware (1.9.8) and what I get from the device are random values, they change even when the device is stationary, I think is the same problem described here but I'm not sure.

Could someone confirm if this is the same problem.

• Hi Guys,

What if I want to use ArduIMU v3 without GPS (as AHI for OSD) and there is no ground speed. And by this:

{
Accel_Vector += Accel_Scale((GPS.ground_speed/100)*Omega);  // Centrifugal force on Acc_y = GPS ground speed (m/s) * GyroZ
Accel_Vector -= Accel_Scale((GPS.ground_speed/100)*Omega);  // Centrifugal force on Acc_z = GPS ground speed (m/s) * GyroY
}

there is wrong calculation then? How can we fight the centrifugal force without knowing speed?
Now ArduIMU v3 has main issue: drift while making turn. Seems the centrifugal force is making drift roll axis very bad. Now it shows the G force vector.

Any input would be great!
Thanks.

Regards,
Virgis

• OK here is the problem description and the solution:

Problem #1:

As mentioned above the accelerometer calibration value was incorrect and should be 8192

// MPU6000 4g range => g = 8192
#define GRAVITY 8192  // This equivalent to 1G in the raw data coming from the accelerometer

Problem #2:  DCM algorithm is implemented incorrectly for MPU-6000

With the previous accelerometer the output for 1G (9.8m/s2) was around 101 so roughly 10 times the raw ADC output.  So in order to accelerate the computations Kp and Ki were adjusted accordingly (divided by 10) and then all calculations were done with the raw ADC data.  Not a pretty way to write code but it worked and marginally accelerated computations.

However when you raw output was changed by a factor 83.51 for MPU6000 this approach would not work anymore.  It didn't work with the old accelerometer calibration value (4096) and the new value only made matters worse.

For example:  if the old accelerometer would output value of 1.03 the software would assume it to be 0.1m/s2 now when the new chipset would output the same value of 1.03 the software still infers the value of 0.1m/s2 however actual value measured is 0.0012m/s2.  (the output for 0.1m/s2 from MPU6000 would be 83.51).

To write it correctly you would have to change  the following lines in the DCM code:

To  Accel_Scale(read_adc(x)) version and adjust the weight parameters accordingly.  This way it will work fine with any other accelerometer chip and makes the code much easier to read.

Alternative solution, which I implemented, which still utilizes the marginal acceleration of manipulating the raw ADC values is to adjust the values of Kp and Ki by the factor of 9.81/ACC_MAX_SCALE (10 to make it compatible with the existing algorithm), so by 83.51.

So the solution would be to change to lines in the initialization code to:

#define Kp_ROLLPITCH 1.515/GRAVITY
#define Ki_ROLLPITCH 0.00101/GRAVITY

This is tested and verified to work correctly.

Problem #3:

I just noticed this one while browsing through the code and haven't done anything about it yet:

#define Accel_Scale(x) x*(GRAVITY/9.81)//Scaling the raw data of the accel to actual acceleration in meters for seconds square

Can anybody see an issue here?  I'll give you a clue, look and the units.  Does that formula provide a result in m/s2 ?  ...I think not! :)

Luckily this piece of code doesn't affect anything unless you using GPS and then GPS speed is used to compensate for centrifugal force.  Which I don't have hooked up right now and cannot test.  However if this is an issue for your application I suggest you change it to the correct value and follow it through in the code.