Хранение данных в режиме реального времени из последовательного порта в CSV-файл, используя C# - PullRequest
0 голосов
/ 11 апреля 2020

Я сейчас работаю над проектом, который требует сбора данных. Проект представляет собой симуляцию, выполненную на Unity, и сегмент, который я пытаюсь разработать, использует последовательный порт и Arduino. Arduino распечатывает 5 из этих строк, эти строки являются выходами IMU, поэтому они постоянно меняются.

12343,123.4,122.4,45.7,62.2,43.5,76.9,89.2,43.1,42.2,65.1

при вводе «s», а затем автоматически приостанавливается. Строки имеют тип

Пока что я написал этот код, который представляет собой скрипт C# для чтения из последовательного порта и сохранения значений в списке.


using UnityEngine;
using System.Collections;
using System.IO.Ports;

public class Communication : MonoBehaviour
{

    SerialPort stream = new SerialPort("COM5", 115200);
    public string receivedstring;
    public GameObject carrito;
    public Vector3 rot;
    public Vector3 rot2;
    public string[] data;
    public string[] data_received;


    void Start()
    {
        stream.ReadTimeout = 500;
        stream.WriteTimeout = 5000;
        stream.Open(); 
        stream.Write("s");
    }

    void Update()
    {
        receivedstring = stream.ReadLine(); 
        stream.BaseStream.Flush(); 

        string[] data = receivedstring.Split(','); 
        if (data[0] != "" && data[1] != "" && data[2] != "" && data[3] != "" && data[4] != "" && data[5] != "" && data[6] != "" && data[7] != "" && data[8] != "" && data[9] != "" && data[10] != "")  
        {
            data_received [0] = data[0];
            data_received[1] = data[1];
            data_received[2] = data[2];
            data_received[3] = data[3];
            data_received[4] = data[4];
            data_received[5] = data[5];
            data_received[6] = data[6];
            data_received[7] = data[7];
            data_received[8] = data[8];
            data_received[9] = data[9];
            data_received[10] = data[10];




            stream.BaseStream.Flush(); 
        }
    }


}


Код разделяет значение из входящей строки и сохраняет его в data_received . Я хочу иметь возможность сохранять 5 строк data_recovered в новый файл csv каждый раз, когда команда s передается на последовательный порт. на протяжении всего проекта последовательный порт не может закрыться, поэтому он будет на паузе («x»), пока я не захочу возобновить его потоковую передачу, нажав S. В течение проекта может быть несколько раз, когда сценарий Unity требует данные от последовательного порта, поэтому каждый раз нужно создавать новый файл .csv.

Это вывод, который я пытаюсь получить enter image description here

enter image description here

1 Ответ

0 голосов
/ 11 апреля 2020

Прежде всего, вы можете просто обернуть это целое выражение if, которое не является динамическим c, и вам придется обновить код, если будет 12,13,14-й элемент и т. Д. c ....

 if (data[0] != "" && data[1] != "" && data[2] != "" && data[3] != "" && data[4] != "" && data[5] != "" && data[6] != "" && data[7] != "" && data[8] != "" && data[9] != "" && data[10] != "")  

в это:

var data = receivedstring.Split(',').ToList(); // notice I grab this as a list, not string array
if (data.All(x => !string.IsNullOrEmpty(x)))

Кроме того, вместо того, чтобы присваивать индексы один за другим, вы можете просто через l oop в своем коде. Поэтому вместо

data_received [0] = data[0];
data_received[1] = data[1];
data_received[2] = data[2];
data_received[3] = data[3];
data_received[4] = data[4];
...
...
...

Вы можете просто сделать следующее:

 for (var i = 0; i < data.Count; i++)
  {
     data_received[i] = data[i];
  }

Исходя из вашего вопроса, если я не ошибся, вы можете сделать что-то вроде ниже:

private void Update() {
      receivedstring = stream.ReadLine();
      stream.BaseStream.Flush();
      int lineLimit = 5; // if you dont want to limit this, just use data.ToList().Count in for loop so it writes all of them

      // WHATEVER IS YOUR COMMAND AND NOT SURE HOW YOU GET THIS BUT ASSUME IT CAME AS X
      // JUST ASSIGN THIS TO YOUR COMMAND I CANT SEE THE WAY YOU PULL IT IN YOUR CODE
      string command = "X"; // hardcoded for the sake of example
      var data = receivedstring.Split(',').ToList();
      if (data.All(x => !string.IsNullOrEmpty(x))) {
       for (var i = 0; i < lineLimit; i++) {
        data_received[i] = data[i];
       }

       WriteToCsv(command, "YOUR_CSV_FILE_PATH_LIKE_C:\test\",data); // Write to csv here...

       stream.BaseStream.Flush();
      }
     }

     public void WriteToCsv(string command, string csvFilePath, List < string > dataToWriteToCsv) {
      var csv = new StringBuilder();
      var fullPath = $ "{csvFilePath}{command}.csv"; // create your full path with file name.

      // add your data line by line
      foreach(var data in dataToWriteToCsv) {
       csv.AppendLine(data);
      }

      // write to csv
      File.WriteAllText(fullPath, csv.ToString());
     }
...