obtaining correct IMU values

Question:

I am reading data from an AHRS / IMU sensor via USB with Python 2.7. To obtain the acceleration the manufacturer specifies according to the image below:

supplier’s description IMU

My code in python is this, but when the acceleration is negative the values are wrong.
I believe I need to check the first bit of the MSB (In this case, the AxH field), if 1 is negative, if 0 is positive.

    #....
    #data = serial.read(size=11)
    #....
    #

    #Acceleration
    elif data[1] == b'x51':
        AxL=int(data[2:3].encode('hex'), 16)
        AxH=int(data[3:4].encode('hex'), 16)
        AyL=int(data[4:5].encode('hex'), 16)
        AyH=int(data[5:6].encode('hex'), 16)
        AzL=int(data[6:7].encode('hex'), 16)
        AzH=int(data[7:8].encode('hex'), 16)

        x = (AxH<<8|AxL)/32768.0*16.0
        y = (AyH<<8|AyL)/32768.0*16.0
        z = (AzH<<8|AzL)/32768.0*16.0

Anyone have any suggestions?

The complete IMU sensor manual is this:
http://wiki.wit-motion.com/english/lib/exe/fetch.php?media=module:wt901:docs:jy901usermanualv4.pdf

Asked By: Mateus Guilherme

||

Answers:

Using struct

The axes data are stored as a little-endian signed short (2 byte) integers, so we can use struct to unpack the data. The struct module will take care of the correct interpretation of the bytes as short integers.

import struct

g = 9.81
conv = 16.0 / 32768.0 * g

# ...

    elif data[1] == b'x51':
        axes = struct.unpack("<hhh", data[2:8])
        x, y, z = [a*conv for a in axes]

Conversion by hand

If you want to do the conversion yourself, I’d assume that the representation of the signed number is two’s complement:

def twos_complement(x, bytes=2):
    maxnum = 2**(bytes*8) - 1
    msb = 1 << (bytes*8 - 1) 
    return -((x^maxnum) + 1) if x&msb else x

AxL = data[2]
AxH = data[3]
Ax_unsigned = AxH << 8 | AxL
Ax = twos_complement(Ax_unsigned, 2)

A little bit late, but still may help someone.

We also should check out the length of the data received and check if the sum is correct. It is a good practice to make sure that the signal is received entirely.

As it is mentioned in the documentation, Checksum: Sum=0x55+0x51+AxH+AxL+AyH+AyL+AzH+AzL+TH+TL. It should be equal to the last value in data. So, do not forget to check it: (sum(data) - data[10]) & 0xFF).

Answered By: user12628549
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.