传递缓冲区指针以读取加速度计数据可获得 2 个正确读数(满分 3 个)

passing buffer pointers to read accelerometer data results in 2 out of 3 correct readings

提问人:Dominykas 提问时间:8/8/2023 最后编辑:Dominykas 更新时间:8/10/2023 访问量:93

问:

我正在使用加速度计并读取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 指针 缓冲区 内存地址

评论

2赞 Some programmer dude 8/8/2023
请注意,没有“C/C++”语言。你要么用 C 编程,要么用 C++ 编程。如果你正在开发Arduino,你正在编写C++。
1赞 Some programmer dude 8/8/2023
在另一个不相关的说明中,不要使用普通的 .它完全相同,但一目了然(而且写起来更少)。*(payload + 1)payload[1]
1赞 Fe2O3 8/8/2023
也许无关:使用 a 的大小作为要擦除的字节数......由于函数不知道数组的大小,因此存在问题......memset(X_data_buff, 0, sizeof(X_data_buff));ptr
0赞 Fe2O3 8/8/2023
如果是 128,则使用该令牌而不是幻数......FIFO_len
0赞 Dominykas 8/8/2023
它用于项目中,出于简单原因,我在这里使用了幻数。

答:

0赞 Dominykas 8/10/2023 #1

好的,所以问题出在时间戳上,我不小心发送了变量而不是数组,这导致时间戳数据被写入 X 轴数据,因为它们的地址彼此靠近(我一个接一个地声明它们),我设法通过编写常量而不是:uint16_tdata[]

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

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