XL335B accelerometer reports false readings 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 &amp; STEP_COUNT 1024
// =&gt; VOLTAGE_STEP 0.0048828125
// MAX_ACC_VOLTAGE 3.3
// =&gt; MAX_ACC_VOLTAGE_STEP 675.84
// MIN_ACC_VOLTAGE 1.65 = 0.5 MAX_ACC_VOLTAGE
// =&gt; 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
// =&gt; j = MAX_ACC_MEASUREMENT / (MAX_ACC_VOLTAGE_STEP-MIN_ACC_VOLTAGE_STEP)
// =&gt; 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);
}
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.