Разбор пакета данных, полученных от последовательного порта - PullRequest
0 голосов
/ 04 июня 2018

Я получаю ответ от последовательного порта через приведенный ниже код.

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SerialPortHexCommunication
{
public class Program
{
    static void Main(string[] args)
    {
        SerialPort port = new SerialPort();
        port.PortName = "COM5";
        port.Parity = Parity.None;
        port.BaudRate = 9600;
        port.DataBits = 8;
        port.StopBits = StopBits.One;

        if (port.IsOpen)
        {
            port.Close();
            port.Dispose();
        }
         port.Open();

        byte[] bytesToSend = new byte[6] { 0xD0, 0xF2, 0xFF, 0x00, 0x06, 0xC7 };

        port.Write(bytesToSend, 0, bytesToSend.Length);
        port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        Console.ReadKey();
        port.Close();
        port.Dispose();

    }

    private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        Console.WriteLine("Data receive at time "+ DateTime.Now.TimeOfDay);
        SerialPort port = (SerialPort)sender;

        int bytes = port.BytesToRead;
        byte[] buffer = new byte[bytes];

        if (port.BytesToRead > 1)
        {
            port.Read(buffer, 0, bytes);
        }

        foreach (byte item in buffer)
        {
            Console.WriteLine(item);
        }
    }
}
}

Выходные данные в основном представляют собой dec-представление байтов, и оборудование, подключенное к последовательному порту, отправляет его в этих форматах E0, F2, идентификатор устройства, длина 2 байта, текущая дата, текущее время (сохраняя текущую дату и текущее время более чем в 2 байтах путем сдвига вправо и некоторых других данных)

Я получаю данные порциями, иногда по 4 байта,иногда 8 байтов.Что я хочу сделать, это 1. Я хочу сначала проверить, что я получил в этом пакете данных, как заголовок 2. Затем, когда я получил следующий блок данных, я не хочу проверять заголовок, но для следующей информации, такой как дата и время и так далеена ..

В основном я хочу проанализировать входящий пакет.

Может кто-нибудь, пожалуйста, приведите небольшой пример. Это будет очень полезно.

Спасибо.

1 Ответ

0 голосов
/ 06 июня 2018

Я использую StringBuilder для создания своих строк.В вашем случае вы работаете с байтами, возможно, вы можете использовать глобальный массив byte[].Ниже приведен пример, где <LF> означает, что я получил все сообщение.Я добавляю символы в свою строку, пока не узнаю, что у меня есть все сообщение.Я быстро очищаю буфер, потому что ваша следующая строка может появиться во время оценки.

StringBuilder sb = new StringBuilder();
char LF = (char)10;

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    string Data = serialPort1.ReadExisting();

    foreach (char c in Data)
    {
        if (c == LF)
        {
            sb.Append(c);

            CurrentLine = sb.ToString();
            sb.Clear();

            //do something with your response 'CurrentLine'
            Eval_String(CurrentLine);
        }
        else
        {
            sb.Append(c);
        }
    }
}

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

public void Eval_String(string s)
{
    string[] eachParam;
    eachParam = s.Split(',');

    if (eachParam.Length == 5)
    {
        //do something
        Console.WriteLine(eachParam[2]);
    }
}
...