3
\$\begingroup\$

I am trying to read acceleration values from a ADXL345 via I2C. I've successfully configured the accelerometer with a resolution of 16G.

Test 1: 180° rotation along the y axis in 16G resolution. The acceleration along the Z axis is shown below:

enter image description here

Using a 16g configuration, the resolution is too low. I changed it to 2g in order to get a more accurate value of gravity and performed the same test.

Test 2: 180° rotation along the y axis in 2G resolution. The acceleration along the Z axis is shown below:

enter image description here

As you can see, the is a roll over effect probably caused by the number of bits used in the register to save the value. With 16g mode the module uses a 13 bit register, with 2/4/8g mode it uses a 10bit register.

Which approach do you suggest to reconstruct the acceleration value?

In this question @davidcary mentioned the roll over effect.

EDIT

I am reading two bytes, it is the same code I used for the 16g mode

def read_word(self,adr):
     high = self.bus.read_byte_data(self.address, adr)
     low = self.bus.read_byte_data(self.address, adr+1)
     val = (high << 8) + low
     return val

def read_word_2c(self,adr):
     val = self.read_word(adr)
    if (val >= 0x8000):
       return -((65535 - val) + 1)
    else:
       return val
[...]

accel_zout = adx.read_word_2c(0x36)

Here is a screenshot of the registers containing the Zaxis values

enter image description here

Note

Here is another problem, I will open another question for this but it is worth pointing out the following problem. Please focus on the Z axis only

Test: tilt from 0° to 180° and back to 0° twice, then from 0° to -180° and back to 0° twice.

Figure 1: Raw data

enter image description here

As you can see, the shift is not costant. The average shift is around 58.000 but sometimes it is smaller than this. If we apply the same correction to all shify occurence we will end up with this:

Figure 2: Unwrapped data

enter image description here

If the threshold after which the correction should be applied is not correctly defined, the resulting data won't be accurate. In Figure 2 the acceleration along the Z axis after the test is different from the initial zero value which means disaster...

\$\endgroup\$
3
\$\begingroup\$

The reconstruction you are looking for is called unwrapping. I have implemented this in C++ with good results last year when measuring the total revolution of a car wheel. In matlab: link

Q = unwrap(P,tol)

The "roll over" observed (actually, a wrapping) is not caused by register overflow, but by the signal change of measured gravity acceleration. The tolerance tol should be half the peak-to-peak amplitude observed.

In C, it would be something like this (haven't tested this, but the idea is here):

void unwrap(int *P, int tol, int len)
{
    for (int index = 1; index < len; index++)
    {
        // Upwards wrapping
        while (P[index-1] - P[index] > tol)
        {
            P[index] += 2*tol;
        }
        // Downwards wrapping
        while (P[index] - P[index-1] > tol)
        {
            P[index] -= 2*tol;
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ Thank you Vicente! Exhaustive answer! I correct the title \$\endgroup\$ – UserK Mar 24 '16 at 16:54
  • \$\begingroup\$ How do you handle noise in conjunction with unwrapping? \$\endgroup\$ – UserK Mar 24 '16 at 17:37
  • \$\begingroup\$ Maybe a median filter with a 3 samples window will do the job \$\endgroup\$ – UserK Mar 24 '16 at 17:42
  • 1
    \$\begingroup\$ @UserK In my application I had designed and implemented a FIR that filtered data input before unwrapping. It was pretty efficient in C++ using deque containers. You could determine window length and coefficients to your needs using matlab toolboxes. The maths behind FIR implementation is as simple as a dot product, the design is the tricky bit. \$\endgroup\$ – Vicente Cunha Mar 24 '16 at 17:49

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.