I am working with the FIFO on the MMA8451Q and have spent days with the data sheet and FIFO app note (AN4073) and the Motion app note (AN4070). My goal is to use the FIFO in trigger mode, triggering on motion in excess of 1g on either x-axis or y-axis, with the FIFO capturing two events pre-trigger and 30 events post trigger. I have the data_rate at 100hz, Lnoise off, F_Read off (using 14-bit data), range=8g.
I have first implemented the Power Minimization Example: Data Logger Collecting example in section 5.1 of AN4073 to make sure I could sort out the basics of the FIFO first.
While I have both that example, and the motion trigger code working, in both cases the data coming back from the FIFO is bit odd. I will explain what I mean by that.
In either case, the first 21 events returned give correct values (when the sensor is not moving, the g values are 0 in the x and y axes). But the values for the remaining 11 values are all over the place. If there is no motion, the values can be as high as 2g and with a triggering motion (in the latter example), these values returned go all the way up to 8g (the actual movement is no where near that high).
The best I can figure is that I am not going about reading the FIFO correctly. I am using an ESP32-S3 which clocks I2C at 400Khz by default and have adapted the Adafruit MMA8451 library as a starting point (it does not have anything in the library with regards to using the FIFO).
Here is a minimal code sample of how I am reading the FIFO:
0 255 248 0 0 255 192
1 0 0 0 16 255 212
2 255 252 255 248 255 208
3 255 240 255 244 255 244
4 0 16 255 228 0 4
5 255 240 255 240 255 216
6 255 248 255 240 0 0
7 255 252 0 20 0 40
8 0 4 0 4 255 236
9 255 252 255 252 0 12
10 0 24 0 0 255 248
11 0 12 255 240 0 64
12 255 228 255 252 255 252
13 255 248 0 12 255 240
14 0 0 0 40 255 228
15 255 252 255 236 255 208
16 255 236 255 244 0 40
17 0 28 0 20 0 20
18 0 16 0 4 255 216
19 0 8 255 224 0 36
20 255 244 0 20 255 208
21 0 4 14 255 232 0
22 8 0 72 255 252 255
23 228 255 232 255 252 0
24 32 0 8 255 200 255
25 224 0 32 0 12 255
26 212 255 244 255 252 255
27 248 0 16 0 0 255
28 240 0 44 0 12 0
29 16 255 200 255 220 0
30 8 0 44 255 220 255
31 248 0 16 255 228 0
If I then convert this to g values for X ,Y, and Z, I see the following for that same data:
0 -0.00, 0.00, -0.01
1 0.00, 0.00, -0.01
2 -0.00, -0.00, -0.01
3 -0.00, -0.00, -0.00
4 0.00, -0.00, 0.00
5 -0.00, -0.00, -0.00
6 -0.00, -0.00, 0.00
7 -0.00, 0.00, 0.00
8 0.00, 0.00, -0.00
9 -0.00, -0.00, 0.00
10 0.00, 0.00, -0.00
11 0.00, -0.00, 0.01
12 -0.00, -0.00, -0.00
13 -0.00, 0.00, -0.00
14 0.00, 0.00, -0.00
15 -0.00, -0.00, -0.01
16 -0.00, -0.00, 0.00
17 0.00, 0.00, 0.00
18 0.00, 0.00, -0.00
19 0.00, -0.00, 0.00
20 -0.00, 0.00, -0.01
21 0.00, 0.47, -0.75
22 0.25, 2.28, -0.09
23 -0.84, -0.72, -0.12
24 1.00, 0.28, -1.72
25 -1.00, 1.00, 0.41
26 -1.34, -0.34, -0.09
27 -0.25, 0.50, 0.03
28 -0.50, 1.38, 0.38
29 0.53, -1.72, -1.12
30 0.25, 1.41, -1.09
31 -0.25, 0.53, -0.88
Now here, we see zero g on all three axes (whereas we should see ~1g on the z-axis) until we get to the 21st event and then the data goes all over the place.
I can only conclude that the method I am using to read the FIFO is incorrect. Can anyone see the error in my method and share some pointers with me?
Thank you!
已解决! 转到解答。
The underlying problem here is that the ESP32 I2C buffer size is 128 bytes. It needs to be at lease 192 bytes to accommodate the full buffer when using 14-bit data.
Placing
build_flags = -DI2C_BUFFER_LENGTH=255
in my platformio.ini does the trick of setting the buffer to a larger (logical) size.
The underlying problem here is that the ESP32 I2C buffer size is 128 bytes. It needs to be at lease 192 bytes to accommodate the full buffer when using 14-bit data.
Placing
build_flags = -DI2C_BUFFER_LENGTH=255
in my platformio.ini does the trick of setting the buffer to a larger (logical) size.
@ JozefKozon Thank you again. I have recreated that code and at this point am convinced that the problem is with my burst read. Here is the data I am collecting using the register setting that your colleague suggested in his message. The data below is the raw data coming from the FIFO read. The sensor is motionless during this.
@JozefKozon, thank you for your kind and prompt response.
I do not believe that calibration is the issue and I will tell you why... If I just capture x, y, and z values and convert them to g values in a tight loop, not using the FIFO, etc., all the values make perfect sense. When still, the z values are very close to 1.00g and the x, y close to 0.00g. When I move the sensor, the acceleration values all make sense.
This is why I believe the problem is in the way I am transferring the FIFO buffer to the processor.
Thinking in terms of esp32 processors, do you see an issue with my method of transferring the FIFO data from its register (0x01) to the array FIFObuffer[192]?
Dear Pete,
my colleague Tomas has created an FIFO example code for FXLS8471Q. Please check this link. You can use the code with slight adjustments in the MMA8451Q.
For the SW, the MMA8451Q and FXLS8471Q are compatible, except for A_VECM and A_FFMT registers. So if the customer does not use the vector-magnitude function and independent threshold values for freefall/motion detection, there is no need to change a firmware.
There is an AN4073 describing FIFO in the MMA8451Q. Please check it here.
With Best Regards,
Jozef
@ JozefKozon Thank you again. I have recreated that code and at this point am convinced that the problem is with my burst read. Here is the data I am collecting using the register setting that your colleague suggested in his message. The first column is the sample number, the next three columns are the g values for x, y, and z respectively. The sensor is motionless during this.
Sorry... there is a part missing from above and the ability to edit the post timed out...
0 0 148 1 100 16 28
1 0 148 1 96 16 44
2 0 152 1 100 16 24
3 0 144 1 96 16 40
4 0 144 1 108 16 44
5 0 144 1 96 16 40
6 0 148 1 100 16 28
7 0 152 1 100 16 40
8 0 148 1 108 16 52
9 0 148 1 104 16 48
10 0 140 1 108 16 32
11 0 144 1 100 16 28
12 0 144 1 108 16 44
13 0 148 1 100 16 32
14 0 152 1 104 16 44
15 0 140 1 92 16 32
16 0 148 1 96 16 36
17 0 140 1 104 16 32
18 0 144 1 96 16 32
19 0 144 1 100 16 32
20 0 140 1 100 16 36
21 0 144 11 0 152 1
22 100 16 28 0 156 1
23 104 16 40 0 152 1
24 104 16 28 0 148 1
25 104 16 44 0 152 1
26 100 16 32 0 152 1
27 96 16 24 0 144 1
28 104 16 44 0 152 1
29 104 16 32 0 144 1
30 104 16 40 0 152 1
31 104 16 28 128 128 128
This translates to the following g values.
0 0.04, 0.09, 1.01
1 0.04, 0.09, 1.01
2 0.04, 0.09, 1.01
3 0.04, 0.09, 1.01
4 0.04, 0.09, 1.01
5 0.04, 0.09, 1.01
6 0.04, 0.09, 1.01
7 0.04, 0.09, 1.01
8 0.04, 0.09, 1.01
9 0.04, 0.09, 1.01
10 0.03, 0.09, 1.01
11 0.04, 0.09, 1.01
12 0.04, 0.09, 1.01
13 0.04, 0.09, 1.01
14 0.04, 0.09, 1.01
15 0.03, 0.08, 1.01
16 0.04, 0.09, 1.01
17 0.03, 0.09, 1.01
18 0.04, 0.09, 1.01
19 0.04, 0.09, 1.01
20 0.03, 0.09, 1.01
21 0.04, 0.69, -6.50
22 6.25, 1.75, -6.25
23 6.50, 2.50, -6.50
24 6.50, 1.75, -6.75
25 6.50, 2.75, -6.50
26 6.25, 2.00, -6.50
27 6.00, 1.50, -7.00
28 6.50, 2.75, -6.50
29 6.50, 2.00, -7.00
30 6.50, 2.50, -6.50
31 6.50, 1.78, -7.97