如何从 Arduino 捕获传感器数据并将其存储到 C++ 中

How to capture and store sensor data from Arduino into C++

我正在编写代码以捕获从 Arduino 到 C++ 的串行读数

有没有办法逐行捕获读数,然后将其存储到数组中?我已经阅读了另一个与我的相似的post,但我仍然无法应用它。

非常感谢任何帮助,谢谢。

环境设置:

[更新] 应用了 Bart

的解决方案

Cpp 文件

之所以加上“for-loop with print and break”是为了分析数组内容。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <unistd.h>

using namespace std;

char serialPortFilename[] = "/dev/ttyACM0";

int main()
{
    char readBuffer[1024];

    FILE *serPort = fopen(serialPortFilename, "r");

    if (serPort == NULL)
    {
        printf("ERROR");    
        return 0;
    }   

    while(1)
    {                           
        usleep(1000); //sync up Linux and Arduino       
        
        memset(readBuffer, 0, 1024);
        fread(readBuffer, sizeof(char),1024,serPort);       
    
        for(int i=0; i<1024; i++){
            printf("%c",readBuffer[i]);     
        }
        break;
    }
    
    return 0;
}

Ino 文件

正在从加速度计获取数据

#include <stdio.h>

const int xPin = A0;
const int yPin = A1;
const int zPin = A2;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int x = 0, y = 0, z = 0;
  
  x = analogRead(xPin);
  y = analogRead(yPin);
  z = analogRead(zPin);
  
  char buffer[16];
  int n;
  n = sprintf(buffer,"<%d,%d,%d>",x,y,z);
  
  Serial.write(buffer);
}

结果

运行三遍代码 Click Here

理想的输出应该是

<a,b,c><a,b,c><a,b,c>...

但现在,一些输出的值在“损坏”内(请 see 从顶部算起第四行)。

即使使用开始和结束标记来确定一个正确的数据集,该集中的数据仍然是错误的。我怀疑问题出在 C++ 的 char 数组上,因为它与 Arduino 不同步。否则我需要从 Arduino 发送字节(不太确定如何)

在不同处理器上处理两个程序 运行 时,它们永远不会同时启动 sending/receiving。您可能看到的不是结果合并错误,更有可能是读取程序在数据中途启动和停止。

通过线路发送数据时,您最好:

关于 Arduino:

  1. 第一帧数据。
  2. 发送帧。

在 Linux 上:

  1. 读入缓冲区中的数据。
  2. 在缓冲区中搜索完整的帧并解帧。

1.框架数据

关于构建数据,我的意思是您需要一个可以在接收端识别和验证的结构。例如,您可以在数据周围添加字符 STX 和 ETX 作为 control characters。当您的数据长度不同时,也需要发送它。

在下面的示例中,我们假设数据数组的长度永远不会超过 255 个字节。这意味着您可以将长度存储在一个字节中。下面你会看到一个框架的伪代码:

STX LENGTH DATA_ARRAY ETX

因此,要发送的字节的总长度是数据的长度加三。

2。发送中

接下来您不使用 println,而是使用 Serial.write(buf, len)。

3。接收

在接收方,您有一个缓冲区,其中将附加所有接收到的数据。

4.拆帧 接下来每次添加新数据时搜索 STX 字符,假设下一个字符是长度。使用长度 +1 你应该找到一个 ETX。如果是这样,您就找到了一个有效的框架,您可以使用这些数据。接下来将其从缓冲区中删除。

for(uint32_t i = 0; i < (buffer.size() - 2); ++i)
{
  if(STX == buffer[i])
  {
    uint8_t length = buffer[i+2];
    if(buffer.size() > (i + length + 3) && (ETX == buffer[i + length + 2]))  
    {
      // Do something with the data.

      // Clear the buffer from every thing before i + length + 3
      buffer.clear(0, i + length + 3);

      // Break the loop as by clearing the data the current index becomes invalid.
      break; 
    }
  }
}

有关使用循环冗余校验 (CRC) 的示例,请参阅 here