How to compute acceleration from accelerometer raw data

I'm working on a project based on NXP accelerometer MMA8653.

This is a I2C, 3-axial accelerometer with 10-bit resolution.

Actually I can read the accelerometer registers and I'm able to configure it. I configured the accelerometer with full scale equal to 2G and the sensitivity associated to this full scale is 256 conts/g

Reading the register I obtain three 16bit signed variables that correspond to each axis.

Which is the formula to compute the acceleration on the three axis?

My MCU has not a floating point unit, so I want to avoid divisions. It's possible to obtain acceleration in mg (millig - 1^10-3 g)?

Thanks for the help!

As far as I understand, you will get the acceleration in [g] on each axis by dividing each of the 3 values you obtained by 256 (because your sensitivity is 256 counts/g).

To avoid any problems with the division of integer numbers, I suggest you to do in this order, for each value:

• Convert the number into a signed long, to avoid any overflow in the future
• Multiply the value by 1000
• Divide the value by 256: you will then obtain the acceleration value in milli-g, rounded to the lowest mg.

Tip: if you want to round it to the nearest mg (instead of the lowest), you can add 128 (half the number of count / mg) before you divide the value, but after you multiplied it by 1000.

Tip 2: as you mentioned in your comment, you can use a bitshift of 8 instead of the division by 256 to improve the efficiency of the calculation (there is a chance that your compiler would optimise the code by automatically doing it anyway)

• Thanks Edesign! Your solution is perfect. I made the division with a byte shift of 8 positions. The tip is very useful! – Federico Oct 4 '16 at 10:05
• Good idea for the bit shift. I add it to the answer, to make it more complete. – Edesign Oct 4 '16 at 10:25

You can usually figure out conversions like these by examining the units. If you divide the ADC reading with units of counts by the sensitivity with units of counts/g then the units of counts in the numerator and denominator of the division will cancel each other out leaving you with g, your desired result.

So you need to divide the ADC count by the sensitivity to convert to acceleration but in this case you also have to account for the offset. This accelerometer measures both positive and negative acceleration but the ADC count is unsigned. This is possible because the ADC count value of zero doesn't correspond to zero g, rather it corresponds to the most negative acceleration. And the midpoint of the ADC value range corresponds to zero acceleration.

So you have an ADC count range of 0-1023 counts with a sensitivity of 256 counts/g. And the acceleration range of -2 to +2 g (technically +1.996 g) means that you have an offset of -2 g.

acceleration = (ADC count value / sensitivity) + offset

examples:

• 256 counts / (256 counts / g) - 2 g = -1 g
• 1023 counts / (256 counts / g) - 2 g = +1.996 g

Shifting right 8 bits is the same as dividing by 256. But in this case you have to be careful that you don't lose too much resolution when you shift. For example if you shift the 10 bit ADC reading right by 8 bits then you'll be left with only 2 bits corresponding to only 4 possible readings (-2, -1, 0, and 1 g).

Multiplying the count value by 1000 mg/g before shifting right by 8 bits will save that resolution and provide the acceleration in units of mg rather than g.

It looks like the MMA8653 provides the 10-bit ADC value in the most significant 10 bits of the 16-bit register. In other words the ADC value is shifted left by 6 bits (or multiplied by 64). You'll need to account for this too, perhaps by shifting right 6 before multiplying by 1000. And once you multiply by 1000 the value won't fit in 16 bits anymore so you'll have to move to a 32 bit value.