我正在使用加速度计并读取 FIFO 数据。使用 C/C++、用于 esp32 的 Platformio Arduino 框架编写代码。我创建了一些函数来访问所有 3 个轴的 FIFO 数据:
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);
一切似乎都正常工作,直到 Read_FIFO_packet_16_IIM 函数,X 轴数据损坏或丢失,每次调用此函数时我都会得到随机固定值(它应该在 0 左右),但 Y 和 Z 轴返回正确的数据(Y 大约 0 和Z 大约 1)。我的猜测是有些东西与地址混淆了,但为什么做同样的事情适用于 2 轴?
更新: 似乎最后一个 X 缓冲区值(128 个元素)已正确返回并打印出 -0.02 左右(这似乎是正确的值)。
好吧,所以问题出在时间戳上,我不小心发送了
uint16_t
变量而不是数组,这导致时间戳数据被写入 X 轴数据上,因为它们的地址彼此靠近(我一个接一个地声明它们) ,我设法通过编写常量而不是data[]
来捕捉到这一点:
*X_data = 1 //data[0];
*Y_data = 2 //data[1];
*Z_data = 3 //data[2];
我在 X_data 中获得了递增数据,并且该系统中只有一个递增变量,因此当我发现谁更改了值时,很容易找到它更改值的原因。