1

I'm using an XL335B accelerometer in a GY-61 breakout board. I'm powering the device using the UNO's built-in 3.3V power supply. The following code should convert the readings to m/s² (SI); however, it returns (-0.43|-0.52|-5.83) instead of the expected (0|0|-9.81) when lying untouched.

Code:

const float CYCLE_LENGHT_MILLIS = 1000;

// REFERENCE_VOLTAGE 5 & STEP_COUNT 1024
// => VOLTAGE_STEP 0.0048828125
// MAX_ACC_VOLTAGE 3.3
// => MAX_ACC_VOLTAGE_STEP 675.84
// MIN_ACC_VOLTAGE 1.65 = 0.5 MAX_ACC_VOLTAGE
// => MIN_ACC_VOLTAGE_STEP 337.92
// MAX_ACC_MEASUREMENT 29.43 = 3g

// acceleration = (read()-MIN_ACC_VOLTAGE_STEP) * MAX_ACC_MEASUREMENT/(MAX_ACC_VOLTAGE_STEP-MIN_ACC_VOLTAGE_STEP)
//This can be simplified to: acceleration = read()*j - k
// => j = MAX_ACC_MEASUREMENT / (MAX_ACC_VOLTAGE_STEP-MIN_ACC_VOLTAGE_STEP)
// => k = MIN_ACC_VOLTAGE_STEP * j

const float j = 29.43/(675.84-337.92);
const float k = 337.92*j;

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

void loop(){
  Serial.print("(");
  Serial.print(analogRead(0) * j - k);  //X-AXIS
  Serial.print("|");
  Serial.print(analogRead(1) * j - k);  //Y-AXIS
  Serial.print("|");
  Serial.print(analogRead(2) * j - k);  //Z-AXIS
  Serial.println(")");
  delay(CYCLE_LENGHT_MILLIS);
}
7
  • Shouldn't it be (analogRead(0) - k) * j?
    – Gerben
    Aug 2 '15 at 15:29
  • Not as far as I know. Tested it anyways, it returns (26.53|26.44|21.04). Aug 2 '15 at 15:37
  • I've edited my post to add what j and k are. I won't post the reasoning that brought me to acc = read()*j - k here because I would be throwing readability out the window. I'll look into posting it somewhere else in a more organized fashion. Aug 2 '15 at 15:45
  • You are assuming here that 3g will result in the maximum voltage of 3.3v. This is not correct. The datasheet says it's 0.3v/g so; 0g-voltage + 3 x 0.3v => 1.65 + 3*0.3 = 2.55volt. Try (analogRead(0)-337.92)/61.44 (337.92 is the 0g voltage in steps; 61.44 is 0.3V is steps)
    – Gerben
    Aug 2 '15 at 16:01
  • Now it's returning (-0.06|-0.10|-1.09). What am I missing? Aug 2 '15 at 16:07
1

You are assuming here that 3g will result in the maximum voltage of 3.3v. This is not correct. The datasheet says it's 0.3v/g so; 0g-voltage + 3 x 0.3v => 1.65 + 3*0.3 = 2.55volt.

To get the g value use (analogRead(0)-337.92)/61.44 (337.92 is the 0g voltage in steps; 61.44 is 0.3V is steps).

To get the acceleration is m/s² just multiply by 9.81; so (analogRead(0)-337.92)/61.44*9.81

Like you stated in the comments, the result isn't that accurate. Just have a look at the datasheet. e.g. Volt per G is typically 300, but can be anything from 270 to 330. Same thing goes for the 0g voltage; 1.35V to 1.65V. So quite a bit of difference can occur between one chip and the next. Even between the 3 axis inside one chip.

So the best thing is to calibrate all 3 axis. For the Z axis; just lay the sensor flat, and get the analogRead value (-1g value). Flip the sensor upside down and get the analogRead value (+1g value). Optionally place the sensor on it's side to get 0g value or just calculate the value in the middle of the above two value. The steps-per-g will be the difference between the two divided by 2 (+1g - -1g = 2g). Put this value and the 0g step-value into the formula. Repeat the procedure for the other 2 axis.

0

An effective but yet simple calibration is explained in https://chionophilous.wordpress.com/2011/08/26/accelerometer-calibration-ii-simple-methods/

We need to find the 0G mark and the sensitivity on each axis. Call them m_x, delta_x, m_y, delta_y, m_z, and delta_z (e.g. m_z is the zero-G mark or the “middle” on the z-axis, delta_z is the sensitivity on the z-axis). That makes 6 numbers, so we should expect to need at least 6 measurements.

Check also the more accurate setup: https://chionophilous.wordpress.com/2011/08/26/accelerometer-calibration-iii-improving-accuracy-with-least-squares-and-the-gauss-newton-method/

Least-Squares

Here is the idea. We’ve been assuming that there are just six numbers we need to find to get a good calibration: m_x, m_y, m_z, delta_x, delta_y, and delta_z. Now matter how we place our sensor before we take readings, we assume it is still and is detecting exactly 1G of acceleration in some direction.

So if we read value x on the X-pin, y on the Y-pin, and z on the Z-pin we can look at the acceleration vector

If our measurements have no noise and our parameters are correct, the length of this vector should be exactly 1 no matter which way it is pointing

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.