Как я могу отделить каждую вторую или каждую третью строку от потока строк, поступающих через COM-порт в режиме реального времени? - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть поток строк, поступающих через последовательный порт непрерывно с фиксированной скоростью передачи.И мне нужно отделять определенную строку каждый раз, когда она получена, разбить ее на полезные части и распечатать эти части в интерфейсе Winform.Приветствуется любая помощь и / или пример

Я получаю данные GPS и подключил их к ПК через UART к последовательному порту.Настройка последовательного порта с WinForms и получение данных не проблема.Мне нужна помощь в установке фильтров для синтеза необходимых сообщений и их обработке.

   ////////////// This code is only for reference to the GUI ////////////
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using System.Windows.Forms;
  using System.IO;
  using System.IO.Ports;


   namespace WindowsFormsApplication1
   {
    public partial class Form1 : Form
     {
        public Form1()
         {
            InitializeComponent();
          }
            private void Clear_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
        }
        private void Start_Click(object sender, EventArgs e)
        {
            serialPort1.Open();   
         }
        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            richTextBox1.ScrollToCaret();
        }
        private void Read_Click(object sender, EventArgs e)
        {   
         string data = serialPort1.ReadExisting(); //reads the whole 
                                             readbuffer

            if (data.Length >= 10)
               {
                    richTextBox1.Text = data;
                   }   
              }
                  private void Stop_Click(object sender, EventArgs e)
              {
                serialPort1.Close();
               }
           } 
         }

Например: если вы видите данные GPS на изображении

(link: https://www.google.com/imgres?imgurl=https%3A%2F%2Fidyl.io%2Fwp-content%2Fuploads%2F2017%2F05%2Fraw-gps-data-8.png&imgrefurl=https%3A%2F%2Fidyl.io%2Farduino%2Fhow-to%2Finterface-gps-module-arduino%2F&docid=zNdHsCmZc93QIM&tbnid=P0_E1tvN1Ur0HM%3A&vet=10ahUKEwjh9NudvqTgAhVL4eAKHYtyDHYQMwhbKA0wDQ..i&w=597&h=496&bih=938&biw=1920&q=gps%20data&ved=0ahUKEwjh9NudvqTgAhVL4eAKHYtyDHYQMwhbKA0wDQ&iact=mrc&uact=8#h=496&imgdii=P0_E1tvN1Ur0HM:&vet=10ahUKEwjh9NudvqTgAhVL4eAKHYtyDHYQMwhbKA0wDQ..i&w=597) 

, вы увидите, чторазные сообщения приходят в циклическом порядке.Я заинтересован в каждом сообщении, которое начинается с "$ GPGGA".Я хочу читать только это сообщение каждый раз, когда оно происходит, разбить его на полезные части, распечатать их, а затем вернуться, чтобы получить следующее сообщение, которое начинается с "$ GPGGA".

Примечание. Если прием плохой, gps пропускает позиции в сообщении, которые зарезервированы для фактических показаний, поэтому размер строки уменьшается.

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Я чувствую, что этот вопрос часто возникает.Вы уже выполнили сложную часть - отправку / получение данных.Теперь вам просто нужно разобрать его.Как видно из примера изображения, все разделено запятыми, и каждая строка заканчивается переводом строки возврата каретки.Смотрите мой ответ на this , вы должны иметь возможность построить строку для каждой строки, затем разделить ее на запятые и получить поле, которое вы ищете.

0 голосов
/ 05 февраля 2019

Вы можете сделать это с помощью регулярного выражения или путем разделения полученной строки, используя '$' - поскольку каждая строка начинается с этого символа.

// Holds the partial/unprocessed data we've read from the serial port.
private string _serialRxString = string.Empty;

private void Start_Click(object sender, EventArgs e)
{
  serialRxString = string.Empty;
  serialPort1.Open();
}

private void Read_Click(object sender, EventArgs e)
{
  // Add the new data to what we have.
  _serialRxString += serialPort1.ReadExisting();

  // Each line starts with a '$'.
  string[] lines = _serialRxString.Split(
    new char[] { '$' },
    StringSplitOptions.None);

  // Don't process the last one yet, it might not be complete.
  for (int i = 0; i < lines.Length - 1; i++)
  {
    // Check if it's the line we're looking for.
    if (lines[i].StartsWith("GPGGA"))
    {
      string[] values = lines[i].Split(new char[] { ',' });

      // Do what you want with the values from the $GPGGA line.

    }
  }

  // Keep the last line, since it might not be complete yet.
  _serialRxString = lines.Last();
}

Вы также можете захотеть подписаться на последовательный портданные получили событие.Таким образом, любые данные, полученные через последовательный порт, будут автоматически обрабатываться без нажатия кнопки чтения.Вы можете сделать это либо через конструктор, либо через конструктор формы.Тогда событие получения данных будет таким же, как в приведенной выше функции Read_Click.

Чтобы подписаться на событие DataReceived в конструкторе:

Subscribing in the designer

Или в конструкторе:

public Form1()
{
  InitializeComponent();

  serialPort1.DataReceived += serialPort1_DataReceived;
}

Событие получения данных тогда будет:

private void serialPort1_DataReceived(
  object sender,
  SerialDataReceivedEventArgs e)
{
  // Add the new data to what we have.
  _serialRxString += serialPort1.ReadExisting();

  // Each line starts with a '$'.
  string[] lines = _serialRxString.Split(
    new char[] { '$' },
    StringSplitOptions.None);

  // Don't process the last one yet, it might not be complete.
  for (int i = 0; i < lines.Length - 1; i++)
  {
    // Check if it's the line we're looking for.
    if (lines[i].StartsWith("GPGGA"))
    {
      string[] values = lines[i].Split(new char[] { ',' });

      // Do what you want with the values from the $GPGGA line.

    }
  }

  // Keep the last line, since it might not be complete yet.
  _serialRxString = lines.Last();
}

Затем, когда что-либо будет получено по последовательному порту, эта функцияавтоматически вызывается.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...