# Converting Acceleration of ADXL335 data into displacement

I'm currently using a ADXL335 chip two measure acceleration then converting it into a displacement. I'm wanting to measure the vetical (-z direction) displacement range of maximum 10cm, so quite small. I have read the data from the ADXL335 and converted it into "g's". I then numerical integrate (trapezoidal) it twice in order to convert the g's into displacement. I only want to measure the vertical displacement in the -Z direction.

Sample rate == 100Hz; using a 12 bit ADC; Vref == 3.3volts;

here is my CVI/c code:

//every sample (0.01 seconds)

acceleration = (((((adc - 2420)*3.3)/4096)/0.3)*-9.8);//subtracting 2420 to account for the acceleration due to gravity.

acceleration_1 = acceleration;

velocity = velocity_1 + (((acceleration+acceleration_1)/2)*0.01);

velocity_1 = velocity;

displacement = displacement_1 + (((velocity+velocity_1)/2)*0.01);

displacement_1 = displacement;


....//then I output the displacement data and have a condition to reset the values of the velocity and displacement to zero (when the acceleration goes positive as only need the vertically down direction).

My problem is that I'm getting incorrect values of displacement and my observation so far is that the faster the accelerometer moves the higher the displacement will be.

Would appreciate all the help i can get, been stuck on this problem for a while and not able to make sense of it.

I also tried using a High pass filter to remove the dc offset of the acceleration with no luck (The subtract works?). I also tried implementing another button to control when I integrate. For example integrate when the button is push and set the data values to zero when not pressed.

Hope my problem is clear, In essence my displacement output depends on the rate of acceleration and not the total distance.

• It's called double integration. And yes, integrating errors makes it drift. – Brian Drummond Dec 2 '17 at 13:46
• You might want to get rid of floating point numbers, so that floating point inaccuracy does not add to the error. This looks like simple arithmetic, there's no apparent need for floats. – Lundin Dec 4 '17 at 14:57
• Realised today that i was assigning the variables for the (n-1) directly after assigning the (n) variable, thus making the (n-(n-1))/2 redundant. still not fixed my problem however. – Bobby McGlone Dec 6 '17 at 17:26
• also @Lundin not sure what you mean by removing the floats? won't using int cause round off errors? – Bobby McGlone Dec 6 '17 at 17:27
• @BobbyMcGlone No, integers are 100% accurate, unlike floating point, floating point tutorial here. You can use integers instead of floats in many cases, but you have to multiply and divide no avoid loss of precision. For example (adc - 2420)*3.3 could be rewritten as (adc*33u - 2420u*33u)/10u. This is usually one of the first things we have to teach PC programmers when they decide to start microcontroller programming. – Lundin Dec 7 '17 at 9:19

Converting an Analog Accelerometer data into the distance is fairly difficult because of the offset involved in double integration causes drift as already told. Check this interesting presentation sensor fusion for further details.
As far as I know, this drift can be avoided by using Digital Accelerometers (with high sampling rates) and the double integration has to be performed using electronic integrators with appropriate filters at every stage to remove the offset as well as the low-frequency noise. Your ADC sampling rate looks very low! Use higher sampling rate and if you can design appropriate signal conditioning circuit at each stage, you might be successful with decent results!

Hope this gives little more insight into your problem:)

PS: I myself have investigated ADXL335 for using it for vibration measurement and have failed miserably. I had to standardize my values with optical vibration measurement.

Note that getting displacement from acceleration requires two integrations. That means errors accumulate over time. After the first integration, and fixed offset in the original acceleration causes linearly increasing error. After the second, the error increases quadratically.

What you are trying to do it inertial navigation. To do that over meaningful time spans requires accelerometers much more accurate than cheap MEMs devices.

I once worked on a project that measured a golfer's head motion during a golf swing. It used MEMs accelerometers and gyros. The position data wasn't much good after a couple of seconds. Basically it was just good enough for the duration of the golf swing. Fortunately that's all we needed, so it worked. We were also looking for specific trends and signatures in the swing, and exact position wasn't quite so important.

Do the error calculation. Look at what the acceleration error is. Double integrate that to get displacement error as a function of time. It won't be pretty, especially if you want to know displacement more than a few seconds from a known start.