This should be pretty simple... write to the appropriate register and then conduct the 192 reads.
Code: Select all
#define use14bit true
#define MMA8451_FIFO_REG 0x01
#uint8_t FIFObuffer[192];
bool PD_MMA8451::getFIFO(bool use14bit)
{
uint8_t targetRegister[1] = {MMA8451_FIFO_REG};
return (i2c_dev->write_then_read(targetRegister, 1, FIFObuffer, use14bit ? 192 : 96));
}
The 192 bytes are organized as 32 sets of 6 bytes. The 6 bytes are 2 bytes for each axis: x, y, and z. The two bytes are then converted to a 14-bit twos-complement value and that value is then converted to a g value.
What I am seeing is that the first 21 sets of six bytes is correct and then the remaining 11 sets are non-sensical.
Below is the raw data followed by the data converted to g values. With the sensor motionless, the converted x and y values should be near zero and the z values should be near 1.00. That is what we see for the first 21 events and then corrupted data for the remaining 11. The first column contains the sample number.
I have tried various I2C frequencies from 400KHz down to 50KHz and nothing changes (except the elapsed time).
I have tried this with and without pull-up resistors and nothing changes.
Code: Select all
Elasped Time 4604 microseconds
0 0 80 255 152 16 48
1 0 80 255 152 16 52
2 0 84 255 152 16 48
3 0 80 255 152 16 48
4 0 72 255 152 16 52
5 0 80 255 160 16 48
6 0 80 255 156 16 28
7 0 84 255 152 16 56
8 0 80 255 156 16 44
9 0 80 255 152 16 44
10 0 84 255 156 16 48
11 0 84 255 152 16 48
12 0 80 255 148 16 48
13 0 80 255 156 16 56
14 0 80 255 148 16 44
15 0 76 255 148 16 48
16 0 80 255 156 16 40
17 0 80 255 152 16 48
18 0 72 255 152 16 60
19 0 80 255 156 16 56
20 0 76 255 152 16 48
21 0 80 11 0 84 255
22 160 16 36 0 72 255
23 152 16 40 0 80 255
24 156 16 48 0 84 255
25 152 16 52 0 80 255
26 148 16 40 0 84 255
27 156 16 40 0 80 255
28 152 16 44 0 80 255
29 152 16 48 0 84 255
30 156 16 44 0 80 255
31 156 16 48 128 128 128
0 0.02, -0.03, 1.01
1 0.02, -0.03, 1.01
2 0.02, -0.03, 1.01
3 0.02, -0.03, 1.01
4 0.02, -0.03, 1.01
5 0.02, -0.02, 1.01
6 0.02, -0.02, 1.01
7 0.02, -0.03, 1.01
8 0.02, -0.02, 1.01
9 0.02, -0.03, 1.01
10 0.02, -0.02, 1.01
11 0.02, -0.03, 1.01
12 0.02, -0.03, 1.01
13 0.02, -0.02, 1.01
14 0.02, -0.03, 1.01
15 0.02, -0.03, 1.01
16 0.02, -0.02, 1.01
17 0.02, -0.03, 1.01
18 0.02, -0.03, 1.01
19 0.02, -0.02, 1.01
20 0.02, -0.03, 1.01
21 0.02, 0.69, 5.31
22 -6.00, 2.25, 4.56
23 -6.50, 2.50, 5.06
24 -6.25, 3.00, 5.31
25 -6.50, 3.25, 5.06
26 -6.75, 2.50, 5.31
27 -6.25, 2.50, 5.06
28 -6.50, 2.75, 5.06
29 -6.50, 3.00, 5.31
30 -6.25, 2.75, 5.06
31 -6.25, 3.03, -7.97
Code: Select all
write(write_buffer, write_len, stop);
// and then this...
size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
Code: Select all
bool Adafruit_I2CDevice::write_then_read(const uint8_t *write_buffer,
size_t write_len, uint8_t *read_buffer,
size_t read_len, bool stop) {
if (!write(write_buffer, write_len, stop)) {
return false;
}
return read(read_buffer, read_len);
}
bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) {
size_t pos = 0;
while (pos < len) {
size_t read_len =
((len - pos) > maxBufferSize()) ? maxBufferSize() : (len - pos);
bool read_stop = (pos < (len - read_len)) ? false : stop;
if (!_read(buffer + pos, read_len, read_stop))
return false;
pos += read_len;
}
return true;
}
bool Adafruit_I2CDevice::_read(uint8_t *buffer, size_t len, bool stop) {
size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
if (recv != len) {
// Not enough data available to fulfill our obligation!
return false;
}
for (uint16_t i = 0; i < len; i++) {
buffer[i] = _wire->read();
}
return true;
}
Any help is greatly appreciated! THANK YOU