How to convert data with 4g/8g mode with the MMA8452Q

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to convert data with 4g/8g mode with the MMA8452Q

Jump to solution
1,542 Views
Xenoshell
Contributor II

Hello, im using a raspberry pi 4, the MMA8452Q with I2C and im using the pigpio python library.

I already have some code which produces sensible output but it only works with 2g mode. Now i have some problems with implementing 4g and 8g mode. The output just doesnt make sense. 

I will show the relevant parts of my working code and my code for 2g/4g/8g mode. It would be very nice if someone could give me some pointers how to improve my working code or fix the bug in the other code.

My Code:

def twos_comp(val, bits):
        """compute the 2's compliment of int value val"""
        if (val & (1 << (bits - 1))) != 0: # if sign bit is set e.g., 8bit: 128-255
            val = val - (1 << bits)        # compute negative value
        return val
    
    def readACCx():
        comp_acc_x2 = pi.i2c_read_byte_data(acc_sensor, OUT_X_MSB)
        comp_acc_x1 = pi.i2c_read_byte_data(acc_sensor, OUT_X_LSB)
        acc_combined = ((comp_acc_x2 << <li-emoji id="lia_smiling-face-with-sunglasses" src="" class="lia-unicode-emoji" title=":smiling_face_with_sunglasses:"></li-emoji> | comp_acc_x1) >>4
        acc_combined = twos_comp(acc_combined, 12)
        return acc_combined
    
    def readACCy():
        comp_acc_y2 = pi.i2c_read_byte_data(acc_sensor, OUT_Y_MSB)
        comp_acc_y1 = pi.i2c_read_byte_data(acc_sensor, OUT_Y_LSB)
        acc_combined = ((comp_acc_y2 << <li-emoji id="lia_smiling-face-with-sunglasses" src="" class="lia-unicode-emoji" title=":smiling_face_with_sunglasses:"></li-emoji> | comp_acc_y1) >>4
        acc_combined = twos_comp(acc_combined, 12)
        return acc_combined
        

    def readACCz():
        comp_acc_z2 = pi.i2c_read_byte_data(acc_sensor, OUT_Z_MSB)
        comp_acc_z1 = pi.i2c_read_byte_data(acc_sensor, OUT_Z_LSB)
        acc_combined = ((comp_acc_z2 << <li-emoji id="lia_smiling-face-with-sunglasses" src="" class="lia-unicode-emoji" title=":smiling_face_with_sunglasses:"></li-emoji> | comp_acc_z1) >>4
        acc_combined = twos_comp(acc_combined, 12)
        return acc_combined

while (time.time()-start_time) < RUNTIME:
        try:
            xAccl = readACCx()
            yAccl = readACCy()
            zAccl = readACCz()

            # Output data to screen
            print("Acceleration in X-Axis : ", xAccl/1000)
            print("Acceleration in Y-Axis : ", yAccl/1000)
            print("Acceleration in Z-Axis : ", zAccl/1000)
            time.sleep(1)
        except pigpio.error as e:
            print("error: %s", e)
            time.sleep(1)

The other code:

def readACCx():
        comp_acc_x2 = pi.i2c_read_byte_data(acc_sensor, OUT_X_MSB)
        comp_acc_x1 = pi.i2c_read_byte_data(acc_sensor, OUT_X_LSB)
        acc_combined = ((comp_acc_x2 << <li-emoji id="lia_smiling-face-with-sunglasses" src="" class="lia-unicode-emoji" title=":smiling_face_with_sunglasses:"></li-emoji> | comp_acc_x1) >>4
        if (comp_acc_x2 > 0x7F):
            acc_combined = ~acc_combined +1
            acc_combined *= -1
        return acc_combined
    
    def readACCy():
        comp_acc_y2 = pi.i2c_read_byte_data(acc_sensor, OUT_Y_MSB)
        comp_acc_y1 = pi.i2c_read_byte_data(acc_sensor, OUT_Y_LSB)
        acc_combined = ((comp_acc_y2 << <li-emoji id="lia_smiling-face-with-sunglasses" src="" class="lia-unicode-emoji" title=":smiling_face_with_sunglasses:"></li-emoji> | comp_acc_y1) >>4
        if (comp_acc_y2 > 0x7F):
            acc_combined = ~acc_combined +1
            acc_combined *= -1
        return acc_combined
        

    def readACCz():
        comp_acc_z2 = pi.i2c_read_byte_data(acc_sensor, OUT_Z_MSB)
        comp_acc_z1 = pi.i2c_read_byte_data(acc_sensor, OUT_Z_LSB)
        acc_combined = ((comp_acc_z2 << <li-emoji id="lia_smiling-face-with-sunglasses" src="" class="lia-unicode-emoji" title=":smiling_face_with_sunglasses:"></li-emoji> | comp_acc_z1) >>4
        if (comp_acc_z2 > 0x7F):
            acc_combined = ~acc_combined +1
            acc_combined *= -1
        return acc_combined

while (time.time()-start_time) < RUNTIME:
        try:
            xAccl = readACCx()
            yAccl = readACCy()
            zAccl = readACCz()
            
            cx = float(xAccl)/float(1<<12)/(2*SCALE) #SCALE = 2
            cy = float(yAccl)/float(1<<12)/(2*SCALE)
            cz = float(zAccl)/float(1<<12)/(2*SCALE) 

            # Output data to screen
            print("Acceleration in X-Axis : ", cx)
            print("Acceleration in Y-Axis : ", cy)
            print("Acceleration in Z-Axis : ", cz)
            time.sleep(1)
        except pigpio.error as e:
            print("error: %s", e)
            time.sleep(1)

 

0 Kudos
Reply
1 Solution
1,525 Views
Xenoshell
Contributor II

Ok i managed to solve the problem. The Scale numbers were (hidden) at on of the last pages of the sensor datasheet as mg values. Even if i use 4G mode the output stays the same if the sensor lays flat. Sadly i cant really swing my arm at 4G to test the sensor

SCALE_2G = 1/1000
SCALE_4G = 2/1000
SCALE_8G = 3.9/1000

def readACCx():
        comp_acc_x2 = pi.i2c_read_byte_data(acc_sensor, OUT_X_MSB)
        comp_acc_x1 = pi.i2c_read_byte_data(acc_sensor, OUT_X_LSB)
        acc_combined = ((comp_acc_x2 <<  | comp_acc_x1) >>4
        return acc_combined  if acc_combined < 2048 else acc_combined - 4096

pi.i2c_write_byte_data(acc_sensor, XYZ_DATA_CFG, 0b00000001) # Set to 4g scale

while (time.time()-start_time) < RUNTIME:
        try:
            xAccl = readACCx()
            yAccl = readACCy()
            zAccl = readACCz()
            
            #Calculations are here
            xAccl = xAccl * SCALE_4G
            yAccl = yAccl * SCALE_4G
            zAccl = zAccl * SCALE_4G
            # Output data to screen
            print("Acceleration in X-Axis : ", xAccl)
            print("Acceleration in Y-Axis : ", yAccl)
            print("Acceleration in Z-Axis : ", zAccl)
            time.sleep(1)
        except pigpio.error as e:
            print("error: %s", e)
            time.sleep(1)

 

View solution in original post

0 Kudos
Reply
3 Replies
1,526 Views
Xenoshell
Contributor II

Ok i managed to solve the problem. The Scale numbers were (hidden) at on of the last pages of the sensor datasheet as mg values. Even if i use 4G mode the output stays the same if the sensor lays flat. Sadly i cant really swing my arm at 4G to test the sensor

SCALE_2G = 1/1000
SCALE_4G = 2/1000
SCALE_8G = 3.9/1000

def readACCx():
        comp_acc_x2 = pi.i2c_read_byte_data(acc_sensor, OUT_X_MSB)
        comp_acc_x1 = pi.i2c_read_byte_data(acc_sensor, OUT_X_LSB)
        acc_combined = ((comp_acc_x2 <<  | comp_acc_x1) >>4
        return acc_combined  if acc_combined < 2048 else acc_combined - 4096

pi.i2c_write_byte_data(acc_sensor, XYZ_DATA_CFG, 0b00000001) # Set to 4g scale

while (time.time()-start_time) < RUNTIME:
        try:
            xAccl = readACCx()
            yAccl = readACCy()
            zAccl = readACCz()
            
            #Calculations are here
            xAccl = xAccl * SCALE_4G
            yAccl = yAccl * SCALE_4G
            zAccl = zAccl * SCALE_4G
            # Output data to screen
            print("Acceleration in X-Axis : ", xAccl)
            print("Acceleration in Y-Axis : ", yAccl)
            print("Acceleration in Z-Axis : ", zAccl)
            time.sleep(1)
        except pigpio.error as e:
            print("error: %s", e)
            time.sleep(1)

 

0 Kudos
Reply
1,538 Views
diazmarin09
NXP TechSupport
NXP TechSupport

Hello,

I hope all is great with you.

First, please note that the MMA8452Q device is obsolete (End of life). You may consider it for further design.

In this case, I would like to recommend the example code below. You may use it as a reference for your design. please review the device configuration and compare it with you code.

MMA8451Q - Bare metal example project

I hope this information helps.

Regards,

David

1,535 Views
Xenoshell
Contributor II

Hey thanks for your reply. I noticed too that this sensor is at End of Life but im a little bit under time pressure and cant wait for something else to arrive.

This code is very good, the only question i would have is what the SENSITIVITY_2G variable is since it isnt declared in the code and is very important for the conversion. Do you know this?

0 Kudos
Reply