.NET Core跨平台串口通讯使用SerialPortStream基础类库问题解决

串口通讯在很多行业应用中都有着重要的地位,而串口通讯的跨平台解决方案在.NET Core 3.0之后,就有了更好的支持。本文将介绍如何使用SerialPortStream基础类库进行.NET Core跨平台串口通讯,并解决其中的常见问题。

安装SerialPortStream

在使用SerialPortStream之前,需要通过NuGet安装它。可以在Visual Studio中的NuGet包管理器中搜索SerialPortStream,或者使用以下命令在命令行中安装:

Install-Package SerialPortStream

打开串口并发送数据

使用SerialPortStream打开串口非常简单,可以按照以下代码来实现:

using System.IO.Ports;
using RJCP.IO.Ports;

SerialPortStream port = new SerialPortStream("COM1", 115200);
port.DataReceived += DataReceivedHandler;
port.Open();

这个代码片段的作用是打开COM1串口,并监听串口事件。可以通过添加DataReceived事件处理程序来处理收到的数据。

要向串口发送数据,可以使用以下代码:

byte[] buffer = new byte[] { 0x01, 0x02, 0x03 };
port.Write(buffer, 0, buffer.Length);

这个代码片段会向串口写入一个字节数组。

解决读取数据时发生的问题

在使用SerialPortStream读取数据时,可能会遇到数据不完整的问题。这是由于串口数据的异步性质引起的。解决这个问题的方法是使用缓冲区。可以使用以下代码:

private List<byte> buffer = new List<byte>();

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPortStream port = (SerialPortStream)sender;
    int bytesToRead = port.BytesToRead;
    byte[] readBuffer = new byte[bytesToRead];
    port.Read(readBuffer, 0, bytesToRead);
    buffer.AddRange(readBuffer);
    ProcessData();
}

private void ProcessData()
{
    int messageStartIndex = buffer.IndexOf(0x01);
    int messageEndIndex = buffer.IndexOf(0x04);
    while (messageStartIndex >= 0 && messageEndIndex >= 0 && messageEndIndex > messageStartIndex)
    {
        byte[] message = buffer.GetRange(messageStartIndex, messageEndIndex - messageStartIndex + 1).ToArray();
        buffer.RemoveRange(0, messageEndIndex + 1);
        // 处理消息
        messageStartIndex = buffer.IndexOf(0x01);
        messageEndIndex = buffer.IndexOf(0x04);
    }
}

这个代码片段使用了一个buffer列表来缓存读取的数据,并在DataReceived事件处理程序中对读取的数据进行处理。ProcessData方法按照起始位和结束位来分离出完整的消息,并将处理过的数据从buffer中删除。

Python技术站热门推荐:

PDF电子发票识别软件,一键识别电子发票并导入到Excel中!

10大顶级数据挖掘软件!

人工智能的十大作用!

解决写入数据时发生的问题

在使用SerialPortStream写入数据时,可能会遇到数据不完整的问题。这是由于串口的写入速度可能比应用程序处理数据的速度快。解决这个问题的方法是使用写入缓冲区。使用以下代码:

private void WriteData(byte[] data)
{
    int offset = 0;
    while (offset < data.Length)
    {
        int bytesToWrite = Math.Min(data.Length - offset, port.WriteBufferSize);
        port.Write(data, offset, bytesToWrite);
        offset += bytesToWrite;
        port.BaseStream.Flush();
        Thread.Sleep(10); // 等待一段时间,避免写入速度过快
    }
}

这个代码片段将要写入的数据data分段进行写入,并在写入每一段数据后调用Flush方法,以确保数据被写入到串口。

扩展阅读

SerialPortStream类库的文档可以在它的GitHub仓库中找到。如果你想进一步了解.NET Core串口通讯,可读取官方文档。

示例说明

下面是一个使用SerialPortStream读取串口数据的示例代码,它会读取串口数据,并将数据打印出来:

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using RJCP.IO.Ports;

class Program
{
    static SerialPortStream port;
    static List<byte> buffer = new List<byte>();

    static void Main(string[] args)
    {
        port = new SerialPortStream("COM1", 115200);
        port.DataReceived += DataReceivedHandler;
        port.Open();
        Console.ReadKey();
        port.Close();
    }

    static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPortStream port = (SerialPortStream)sender;
        int bytesToRead = port.BytesToRead;
        byte[] readBuffer = new byte[bytesToRead];
        port.Read(readBuffer, 0, bytesToRead);
        buffer.AddRange(readBuffer);
        ProcessData();
    }

    static void ProcessData()
    {
        int messageStartIndex = buffer.IndexOf(0x01);
        int messageEndIndex = buffer.IndexOf(0x04);
        while (messageStartIndex >= 0 && messageEndIndex >= 0 && messageEndIndex > messageStartIndex)
        {
            byte[] message = buffer.GetRange(messageStartIndex, messageEndIndex - messageStartIndex + 1).ToArray();
            buffer.RemoveRange(0, messageEndIndex + 1);
            Console.WriteLine(BitConverter.ToString(message));
            messageStartIndex = buffer.IndexOf(0x01);
            messageEndIndex = buffer.IndexOf(0x04);
        }
    }
}

下面是一个向串口发送数据的示例代码,它会周期性地向串口发送数据:

using System;
using System.IO.Ports;
using RJCP.IO.Ports;

class Program
{
    static SerialPortStream port;

    static void Main(string[] args)
    {
        port = new SerialPortStream("COM1", 115200);
        port.Open();
        while (true)
        {
            byte[] data = new byte[] { 0x01, 0x02, 0x03 };
            WriteData(data);
            Thread.Sleep(1000);
        }
    }

    static void WriteData(byte[] data)
    {
        int offset = 0;
        while (offset < data.Length)
        {
            int bytesToWrite = Math.Min(data.Length - offset, port.WriteBufferSize);
            port.Write(data, offset, bytesToWrite);
            offset += bytesToWrite;
            port.BaseStream.Flush();
            Thread.Sleep(10);
        }
    }
}
Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐