Как захватить и сохранить данные датчика из Arduino в C ++ - PullRequest
0 голосов
/ 04 июня 2019

Я пишу код для захвата последовательных чтений с Arduino на C ++

Есть ли способ захватывать показания построчно и затем сохранять их в массив? Я прочитал еще один пост , похожий на мой, но я все еще не могу его применить.

Любая помощь очень ценится, спасибо.

Настройка среды:

  • Arduino UNO
  • ADXL 335 акселерометр
  • Ubuntu 16.04
  • C ++

[Обновлено] прикладное решение от Барта

Cpp файл

Причина, по которой я добавил «цикл for с печатью и разрывом», заключается в анализе содержимого массива.

#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;
}

Ино файл

Выборка данных с акселерометра

#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);
}

Результаты

Запуск кода три раза Нажмите здесь

Идеальные выходы должны быть

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

но сейчас некоторые выходы имеют значения внутри "повреждены" (пожалуйста, см. четвертую строку сверху).

Даже если для определения правильного набора данных используются начальный и конечный маркеры, данные в наборе все еще неверны. Я подозреваю, что проблема заключается в массиве char из C ++, потому что он не синхронизирован с Arduino. В противном случае мне нужно отправить Bytes из Arduino (не совсем уверен, как)

1 Ответ

0 голосов
/ 04 июня 2019

При работе с двумя программами, работающими на разных процессорах, они никогда не начнут отправлять / получать одновременно. Вероятно, вы видите не то, что результаты объединены неправильно, скорее, программа чтения запустилась и остановилась на полпути между данными.

При отправке данных по линии лучше всего:

На Ардуино:

  1. Первый кадр данных.
  2. Отправить кадр.

В Linux:

  1. Чтение данных в буфере.
  2. Поиск в буфере полного кадра и дефрагментации.

1. Обрамление данных

Под формированием данных я имею в виду, что вам нужна структура, которую вы можете распознать и проверить на принимающей стороне. Например, вы можете добавить символы STX и ETX в качестве управляющих символов вокруг ваших данных. Когда длина ваших данных меняется, это также необходимо отправить.

В следующем примере мы берем, что массив данных никогда не длиннее 255 байтов. Это означает, что вы можете хранить длину в одном байте. Ниже вы видите псевдокод того, как может выглядеть кадр:

STX LENGTH DATA_ARRAY ETX

Таким образом, общая длина байтов, которые будут отправлены, равна длине данных плюс три.

2. Отправка

Далее вы используете не println, а Serial.write (buf, len).

3. Прием

На принимающей стороне у вас есть буфер, в который будут добавлены все полученные данные.

4. Deframing Далее каждый раз, когда добавляются новые данные, ищите символ 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), см. здесь

...