Determine if correct value [Accel]

Hello dear members,

Have been sitting for days now trying to solve my problem with these sensors. First, it appears that it works with one sensor, but then i encounter several problems when trying to implement several sensors together.
The values ??are, in other words totally crap, turns out that all the values ??are the same hehe.

Anyway, I have possibly solved it by using the wiring library instead (used I2Cdevlib before). The values ??I get now may be possibly correct, I am, however, skeptical of their accuracy and therefore I turn here to get it confirmed.

I will upload two photos, and also a part of the codes/settings im using.

First the code and settings:

///////////////////////////////////////////
///////////////ACCELEROMETER//////////////
/////////////////////////////////////////

void ADXL345_init(){
Read_I2C(ADXL345_ADDR, ADXL345_WHO_AM_I, buffer, 1); // READS THE DEVICE_ID
DEV_ID = buffer[0];

if(DEV_ID = 229){
Serial.print("ADXL345: CONNECTED ");
Write_I2C(ADXL345_ADDR, ADXL345_POWER_CTL, 0x00); // Sensor OFF
Write_I2C(ADXL345_ADDR, ADXL345_POWER_CTL, 0x08); // 0001 1000 Measuring ON, checks inactivity each 0.125s (f = 8hz) and autosleep enabled
Write_I2C(ADXL345_ADDR, ADXL345_DATA_FORMAT, 0x03); // 0000 0011 Sensitivity +-16g

}

}

void ADXL345_read(){
Read_I2C_Val(ADXL345_ADDR, ADXL345_OUT_X_L, buffer, 6);

ADXL345_x = (word(buffer[1], buffer[0]));
ADXL345_y = (word(buffer[3], buffer[2]));
ADXL345_z = (word(buffer[5], buffer[4]));

// int pitch = (((atan2(accx,accz))*180)/PI);
// int roll = (((atan2(accy,accz))*180)/PI);

}

///////////////////////////////////////////
///////////////GYROSCOPE//////////////////
/////////////////////////////////////////

void L3G4200D_init(){
Read_I2C(ADXL345_ADDR, ADXL345_WHO_AM_I, buffer, 1); // READS THE DEVICE_ID
DEV_ID = buffer[0];

if(DEV_ID = 211){
Serial.println("L3G4200D: CONNECTED");
Write_I2C(L3G4200D_ADDR, L3G4200D_CTRL_REG1, 0x00); // Power off sensor
Write_I2C(L3G4200D_ADDR, L3G4200D_CTRL_REG1, 0x0F); // 0000 1111(f = 100hz, B = 12.5) Sensor and all axis ON
Write_I2C(L3G4200D_ADDR, L3G4200D_CTRL_REG2, 0x00); // 0010 0000 Normal mode on
Write_I2C(L3G4200D_ADDR, L3G4200D_CTRL_REG3, 0x08); // FIFO and interrupts off
Write_I2C(L3G4200D_ADDR, L3G4200D_CTRL_REG4, 0x30); // 0011 000 (2000 DPS)
Write_I2C(L3G4200D_ADDR, L3G4200D_CTRL_REG5, 0x00); // 0000 0000 FIFO and highpass-filter OFF
}
}

void L3G4200D_read(){
Read_I2C_Val(L3G4200D_ADDR, L3G4200D_OUT_X_L, buffer, 6);

L3G4200D_x = (word(buffer[1], buffer[0]));
L3G4200D_y = (word(buffer[3], buffer[2]));
L3G4200D_z = (word(buffer[5], buffer[4]));

}

And here is the part where the I2C Communication occurs:

void Write_I2C(int ADDRESS, byte POINTER, byte NEW){
Wire.beginTransmission(ADDRESS);
Wire.write(POINTER);
Wire.write(NEW);
Wire.endTransmission();

}

void Read_I2C_Val(int ADDRESS, byte POINTER, byte READ[], int AMOUNT){

Wire.beginTransmission(ADDRESS);
Wire.write(POINTER | (1 << 7));
Wire.endTransmission();

Wire.requestFrom(ADDRESS,AMOUNT);
for(int x = 0; x < AMOUNT; x++){
READ[x] = Wire.read();
}
}

(NOTE: THESE ARE RAW VALUES)
Sensor laying flat (Components looking upwards) - accel
So to simply make these values into g's you just multiplicate it with 32/2^10 ~= 0.031. Results should be x = 0, y = 0, z = +1

Sensor laying upsidedown (Components looking down) - accel

Rotating sensor - gyroscope

I hope Ive provided enough information!

Cheers :slight_smile:

Edit:
ADXL345 +-16g
L3G4200D +-2000DPS

The accelerometer data looks fairly reasonable. The Z axis shows a change of about 1.891G from facing up to facing down. That's fairly close to 2G.

Your Z-axis has some sensitivity error and a zero offset of about 89.5 counts (2.9G). Your chip might be out of spec. Check the datasheet to see how much offset is normal.

Thanks for the quick reply,

But what makes me confused is why I don't get x = 0, y = 0 and z = 1 (g) when the sensor is flat.

According to the data sheet (offset/bias values):
Xactual = Xmeas- X(0g)
Yactual = Ymeas - Y(0g)
Z (0g) = Z (+1g) - S(Z)
Zactual = ZMEAS - Z(0g)

Where S (Z) is:

Because the z-axis measurement was done in a +1 g field, a no-turn
or single-point calibration scheme assumes an ideal sensitivity,
SZ for the z-axis. This is subtracted from Z +1 g to Attain the z-axis
offset, Which is then subtracted from Future measured values ??to
Obtain the actual value

Where can I find this S (Z)? On page 3, I find this

0 g Output for ZOUT = -250 (min) and +250 (max).

Could it possibly be S(Z)?

You could also use the offset register to calibrate, but Id rather start doing it manually.

Edit:
Datasheet can be found here: http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf

How can I tell if the offset is normal or not? I've read the datasheet a couple of times, but some parts still doesn't make any sense to me. Be reading to much on the internet, and there are lots of ways to go which also makes be confused.

Help is really appreciated!
Cheers

Your readings look out of tolerance to me. You've set the +/- 8g range with 10-bit resolution, in which the sensitivity is about 31.2 lsb per g. Maximum zero-g offset is quoted as +/- 150mG for the X and Y axes, and +/- 250mG for the Z axis. So with the sensor horizontal and the right way up, I think the X and Y readings should be between -5 and +5, and the Z reading should be between 23 and 40. With the sensor upside down, the Z reading should be between -23 and -40. Your figures are way outside theses ranges. However, the Z sensitivity looks about right, because you get a change of 61 or 62 when you flip the device, which is about twice 31.2 as expected.

I believe you mean +-16g instead of +-8g.

However, just let me see if we are on the same page.
Because Im using a g range of +-16g the sensitivity is 31.2mg/LSB.
And the 0 g Output for XOUT, YOUT = +-150mg and to convert these back to raw values it's the same as +-150/31.2 = +-4,8. So this is where you got the fact that the x and y axis should be +-5? Correct me if Im wrong.

And for the Z-axis, when I make the same as above, it doesn't result of +-23 and +-40 for the Z-axis.

Do you mind explaining how you came up to this?

Id also like to point another issue, maybe this will make it more easier for you guys to help me.
When I put the range to +-2g, the Z-axis outputs 511 (Seen other ppl having the same issue, but never seen a solution to this), doesn't it mean that the z-axis is having a force on it more than 2g's?

Cheers

freak174:
I believe you mean +-16g instead of +-8g.

My mistake.

freak174:
However, just let me see if we are on the same page.
Because Im using a g range of +-16g the sensitivity is 31.2mg/LSB.
And the 0 g Output for XOUT, YOUT = +-150mg and to convert these back to raw values it's the same as +-150/31.2 = +-4,8. So this is where you got the fact that the x and y axis should be +-5? Correct me if Im wrong.

Correct.

freak174:
And for the Z-axis, when I make the same as above, it doesn't result of +-23 and +-40 for the Z-axis.

Do you mind explaining how you came up to this?

The Z axis should read 1G, which is 31.2, +/- 8 for a +/- 250mG error.

freak174:
Id also like to point another issue, maybe this will make it more easier for you guys to help me.
When I put the range to +-2g, the Z-axis outputs 511 (Seen other ppl having the same issue, but never seen a solution to this), doesn't it mean that the z-axis is having a force on it more than 2g's?

Your device appears to have a z-axis offset of about 2.8G. So it's trying to output 3.8G, which would be a value of about 973, but the maximum signed value that will fit in 10 bits is 511.

PS - where did you get the device from?

Thanks for the replies, it has really given me alot more understanding of the accelerometer.

I've managed to calibrate it properly now, it was just the variable S (z) which was unknown to me. This value depends on the g-range you have. In my case, I had +-16g, which correspond 32LSB / g. Then you just use the following calibration equationsthat are written some posts up.

I will upload a couple of photos that demonstrates my results.
However, there is a problem that occurs, I believe that it's due to the quadrants, but I'll take it a little further down.

Sensor laying flat, positive:

Sensor laying flat upside down:

Sensor x axis (pitch):

Now for the last picture, the sensor is almost still in the same position as the picture above. Im just rotation the y-axis a lil bit and look what occurs:

Could this be because there are four different quadrants, and that I must take them into account?

Thanks

I'll give this thread one more bump :slight_smile:

Why do you think there is a problem? Please explain. Is the roll figure in the table an output from one of the gyros, or are you calculating it?

dc42:
Why do you think there is a problem? Please explain. Is the roll figure in the table an output from one of the gyros, or are you calculating it?

I removed the readings from the gyroscope. Easier to focus on one thing at a time instead hehe.
The degrees are being calculated by simply using

arctan(x/z)and arctan(y/z)

Now, if you look at the last two pictures, you will see that the

  • first one of these two pictures outputs a pitch of about -90 degrees and roll about 0 degrees.
  • second picture: I just have to rotate it for a very small amount in the roll direction -> will then go from 0 degrees to -135 degrees (roll)

Something is not right, and I believe I've missed something but dunno what.

I would also like to point out that I've read alot on the net and not just posting here to get simple answers. I always keep the forum as a last option.
Cheers!

If you want help, you need to post the code you use to correct for the zero offset, calculate the pith and roll, and print the readings. If you are using the atan2 function to calculate the angles, then the 4 quadrants should be handled for you.