传递缓冲区指针来读取加速度计数据会导致 3 个正确读数中的 2 个

问题描述 投票:0回答:1

我正在使用加速度计并读取 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, &timestamp, 128);
Print_FIFO_Content_IIM(x_data, y_data, z_data, &timestamp, 128);

一切似乎都正常工作,直到 Read_FIFO_packet_16_IIM 函数,X 轴数据损坏或丢失,每次调用此函数时我都会得到随机固定值(它应该在 0 左右),但 Y 和 Z 轴返回正确的数据(Y 大约 0 和Z 大约 1)。我的猜测是有些东西与地址混淆了,但为什么做同样的事情适用于 2 轴?

更新: 似乎最后一个 X 缓冲区值(128 个元素)已正确返回并打印出 -0.02 左右(这似乎是正确的值)。

c++ c pointers buffer memory-address
1个回答
0
投票

好吧,所以问题出在时间戳上,我不小心发送了

uint16_t
变量而不是数组,这导致时间戳数据被写入 X 轴数据上,因为它们的地址彼此靠近(我一个接一个地声明它们) ,我设法通过编写常量而不是
data[]
来捕捉到这一点:

*X_data = 1 //data[0]; 
*Y_data = 2 //data[1];
*Z_data = 3 //data[2];

我在 X_data 中获得了递增数据,并且该系统中只有一个递增变量,因此当我发现谁更改了值时,很容易找到它更改值的原因。

© www.soinside.com 2019 - 2024. All rights reserved.