Goodmornig,
This is my main code:
##############################"
xOffset = -0.400 # m/s^2
yOffset = 0.200 # m/s^2
zOffset = 9.400 # m/s^2
while True:
while sensor.Motion():
x, y, z = sensor.acceleration
time_now = datetime.datetime.now()
Calcx = -xOffset
Calcy = -yOffset
Calcz = -zOffset
X = x + Calcx
Y = y + Calcy
Z = z + Calcz
sensor.MotionRegister()
print('Time={0} X={1:0.3f} m/s^2 Y:{2:0.3f} m/s^2 Z:{3:0.3f} m/s^2'.format(time_now, X, Y, Z))
time.sleep(0)
IntSourceMFF = sensor.MotionRegister()
#####################"
And I have setup my MMA8451 into a class like this:
###################""
def Motion (self): #, IntSourceSystem,IntSourceMFF):
reg1 = self._read_u8(_MMA8451_REG_CTRL_REG1)
reg1 &= 0xFE #clear active bit (standby)
self._write_u8(_MMA8451_REG_CTRL_REG1, reg1)
self._write_u8(REG_FF_MT_CONFIG, 0x48) #Moto detection X axe after the debounce time (100)ms is reached
self._write_u8(REG_FF_MT_THS, 0x10) #threshold 1g: es 1g/0.063g = 16 counts = 10 (hexadecimal)
self._write_u8(REG_FF_MT_COUNT, 0x0A) #Debounce counter, set at 12.5ms timer for 800 output data rate
self._write_u8(_MMA8451_REG_CTRL_REG4, 0x04)
self._write_u8(_MMA8451_REG_CTRL_REG5, 0x04)
# self._write_u8(_MMA8451_REG_CTRL_REG3, 0x04)
reg1 = self._read_u8(_MMA8451_REG_CTRL_REG1)
self._write_u8(_MMA8451_REG_CTRL_REG1, reg1 | 0x01) #activated
print("It will work")
IntSourceSystem = self._read_u8(_MMA8451_INT_SOURCE)
if ((IntSourceSystem & 0x04) == 0x04):
print("You are into if")
return True
else:
print("You are into else")
return False
def MotionRegister (self):
return self._read_u8(REG_MT_SRC)
##################"
Something strange happens, it works properly only if I print something in my setup module (in this case "It will work").
Why it does it? I don't want that print.
Maybe it is a problem with the Count register setup..I didn't well realized how to use it, I want to use a 100ms timer for 800 ODR but with 0x50 didn't works..
Can someone help me pls?
Hey Tomas,
Firstly best wishes!!
I still have the same problem with the autocalibration..
But I want to change my question:
If the device is stationary on a "flat" desktop, and the measures are
X= 0.201 m/s2
Y= 0.220 m/s2
Z= 9.409 m/s2
Which is the best way to gain:
X= 0 m/s2
Y= 0 m/s2
Z= 9.81 m/s2 ?
I'm also available to use the simple method calibration, but how can I be able to delete the noise?
Am I forced to use the High pass filter or can I use the offset registers?
What do you think? And can you suggest me how to do it?
Thank you, best regards.
Hi Luigi,
First off... Happy New Year and sorry for my late response.
Everything you described in your post from Dec 21st is correct for 8g mode.
In order to reduce noise, our recommendation is using lowest possible ODR and High Resolution Mode as shown in the AN4075 (page 7).
Best regards,
Tomas
ok I have solved the print problem; it was just a bad use of the class module; I just have the reg count problem, can someone explain it to me?
Hi Luigi,
As I do not fully understand what you are asking, I would refer to the AN4070 where you may find useful information related to the embedded motion detection function. If you need to know anything specific, please elaborate it a bit more.
Best regards,
Tomas
Hi Tomas,
Yes I have already read the AN4070 note,
so, my problem was to how to calculate correctly the value to write into the FF_MT_THS register (0x17), and it is just "Threshold/0.063" ;
and how to calculate correctly the value to write into the FF_MT_COUNT register (0x18), and it is just "DebounceTime/TimeStep".
Forget about them.
Now I have another problem:
I'm trying to doing the Aut-Calibration Procedure of the device.
yes, I have already read the AN4069 note :smileyhappy:
On page 6 of the note there is an example using a flow chart.
I didn't understand the 3th box:
Have I to read, (and so print?) the acceleration on X,Y, and Z using firstly the register OUT_X_MSB?
After that have I to read the acceleration on X,Y, and Z using the register OUT_X_LSB?
After that have I to read the acceleration on X,Y, and Z using the register OUT_Y_MSB? etc?
I've tried to do as I mentioned and my Acceleration values are these:
first line X,Y,Z using OUT_X_MSB
second X,Y,Z using OUT_X_LSB
third X,Y,Z using OUT_Y_MSB
fourth X,Y,Z using OUT_Y_LSB
etc.
Are these the values that I need to use in the next step, for the 2's complement?
Thank you.
Hi Luigi,
Sorry for my late response. I would recommend you to take a look at my simple example code for the MMA8451Q where I illustrate offset calibration based on the AN4069.
You should use something like this:
I2C_ReadMultiRegisters(MMA845x_I2C_ADDRESS, OUT_X_MSB_REG, 6, AccData); // Read data output registers 0x01-0x06
Xout_14_bit = ((short) (AccData[0]<<8 | AccData[1])) >> 2; // Compute 14-bit X-axis output value
Yout_14_bit = ((short) (AccData[2]<<8 | AccData[3])) >> 2; // Compute 14-bit Y-axis output value
Zout_14_bit = ((short) (AccData[4]<<8 | AccData[5])) >> 2; // Compute 14-bit Z-axis output value
Xoffset = Xout_14_bit / 8 * (-1); // Compute X-axis offset correction value
Yoffset = Yout_14_bit / 8 * (-1); // Compute Y-axis offset correction value
Zoffset = (Zout_14_bit - SENSITIVITY_2G) / 8 * (-1); // Compute Z-axis offset correction value
I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG1, 0x00); // Standby mode to allow writing to the offset registers
I2C_WriteRegister(MMA845x_I2C_ADDRESS, OFF_X_REG, Xoffset);
I2C_WriteRegister(MMA845x_I2C_ADDRESS, OFF_Y_REG, Yoffset);
I2C_WriteRegister(MMA845x_I2C_ADDRESS, OFF_Z_REG, Zoffset);
Hope it helps!
Best regards,
Tomas
Yes, I was just following your metal bare example but I still have some problem.
Firstly: I'm in 14 bit, ODR 800, 8g mode.
Here:
Xout_14_bit = ((short) (AccData[0]<<8 | AccData[1])) >> 2; // Compute 14-bit X-axis output value
Yout_14_bit = ((short) (AccData[2]<<8 | AccData[3])) >> 2; // Compute 14-bit Y-axis output value
Zout_14_bit = ((short) (AccData[4]<<8 | AccData[5])) >> 2; // Compute 14-bit Z-axis output value
What are you doing with this shifting?
Is this equivalent to a 2's complement for XYZ no?
And are they approximated as integers no? ("short" operator)
Now I've calculated the Offset like this:
Xoffset = Xout_14_bit / 2 * (-1); // Compute X-axis offset correction value
Yoffset = Yout_14_bit / 2 * (-1); // Compute Y-axis offset correction value
Zoffset = (Zout_14_bit - 1024) / 2 * (-1); // Compute Z-axis offset correction value with 8g sensitivity
It looks correct to me..
After that I convert them as hexadecimal (ok?) and I put them into the Offset registers:
I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG1, 0x00); // Standby mode to allow writing to the offset registers
I2C_WriteRegister(MMA845x_I2C_ADDRESS, OFF_X_REG, Xoffset);
I2C_WriteRegister(MMA845x_I2C_ADDRESS, OFF_Y_REG, Yoffset);
I2C_WriteRegister(MMA845x_I2C_ADDRESS, OFF_Z_REG, Zoffset);
I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG1, 0x01); // Active mode
And it doesn't work properly anyway :/
The y and z acceleration doesn't change enough, and X acceleration doesn't change at all.
NB my stationary target is:
X=0g
Y=0g
Z=1g
Obvious my device is properly oriented.
I'm sorry if I'm annoying you too much, I'm a bit noob.
Thank you and merry Christmas.