I am working with accelerometers and reading FIFO data. Writing code in C/C++, Platformio Arduino framework for esp32. I created some functions to access FIFO data of all 3 axis:
void Get_FIFO_data_16(SPIClass *dev, uint8_t *header, int16_t *payload, uint16_t *timestamp) {
const uint8_t packet_length = 16; //bytes
uint8_t packet[packet_length] = {0};
ReadRegBytes(dev, FIFO_DATA, packet, packet_length);
*header = packet[0]; //header
*payload = packet[1]<<8 | packet[2]; //acc X data
//Serial.println(*payload);
*(payload + 1) = packet[3]<<8 | packet[4]; //acc Y data
//Serial.println(*(payload + 1));
*(payload + 2) = packet[5]<<8 | packet[6]; //acc Z data
*timestamp = packet[14]<<8 | packet[15];
}
void Read_FIFO16_packet(int16_t* X_data, int16_t* Y_data, int16_t* Z_data, uint16_t *timestamp) {
uint8_t header = 0;
int16_t data[3] = {0};
uint16_t TimeStamp = 0;
iim_acc_obj.Get_FIFO_data_16(spi_device, &header, data, &TimeStamp);
/*Header*/
/********/
*X_data = data[0]; //X_data is still correct
*Y_data = data[1];
*Z_data = data[2];
*timestamp = TimeStamp;
}
void Read_FIFO_packet_16_IIM (int16_t *X_buffer, int16_t *Y_buffer, int16_t *Z_buffer, uint16_t *timestamp, uint16_t elements_to_read) {
if (iim_acc_obj.Check_Who_am_I(spi_device) == true) {
for (int i = 0; i < elements_to_read; i++) {
Read_FIFO16_packet(X_buffer + i, Y_buffer + i, Z_buffer + i, timestamp + i);
//Serial.println(*(X_buffer + i)/ 4095.00); //reading like this prints correct value
}
} else Serial.print("SPI Coms failed !");
}
void Print_FIFO_Content_IIM(int16_t *X_data_buff, int16_t *Y_data_buff, int16_t *Z_data_buff, uint16_t *timestamp, uint32_t FIFO_len) {
Serial.println("Timestamp X data Y data Z data");
int i = 0;
for (uint32_t i = 0; i < FIFO_len; i++) {
Serial.print(*(X_data_buff + i) / 4095.00); //wrong data
Serial.print(" ");
Serial.print(*(Y_data_buff + i) / 4095.00); //correct data
Serial.print(" ");
Serial.print(*(Z_data_buff + i) / 4095.00); //correct data
Serial.print("\n\r");
}
memset(X_data_buff, 0, sizeof(X_data_buff)); //reset buffer
memset(Y_data_buff, 0, sizeof(Y_data_buff)); //reset buffer
memset(Z_data_buff, 0, sizeof(Z_data_buff)); //reset buffer
}
///main.c///
int16_t x_data[128] = {0};
int16_t y_data[128] = {0};
int16_t z_data[128] = {0};
...
...
Read_FIFO_packet_16_IIM(x_data, y_data, z_data, ×tamp, 128);
Print_FIFO_Content_IIM(x_data, y_data, z_data, ×tamp, 128);
Everything seem to work correctly until Read_FIFO_packet_16_IIM func, X axis data gets corrupted or lost and I get random fixed value every time I call this funcion (It should be around 0), but Y and Z axis return correct data (Y around 0 and Z around 1). My guess is that something gets mixed up with addresses, but why doing same thing works for 2 axis ?
Update: It seems that the last X buffer value (128 element) is returned correctly and prints out around -0.02 (which seems correct value).
Okay, so the problem was with timestamp, I was accidently sending uint16_t
variable instead of array and this caused timestamp data to be written on X axis data, because their addresses are near each other (I declare them one after the other), I managed to catch this by writing constants instead of data[]
:
*X_data = 1 //data[0];
*Y_data = 2 //data[1];
*Z_data = 3 //data[2];
And I got incrementing data in X_data and there is only one incrementing variable in this system, so when I found out who changed the values it was quite easy to find why it changes the values.