C#读取多个COM端口的数据

C#读取多个COM端口的数据,c#,serial-port,C#,Serial Port,背景:我有一个项目,需要同时读取多个COM端口。连接到COM端口的是传感器,这些传感器一直在转储数据。我需要从每个传感器收集这些数据。同时连接的传感器数量最多可达5个 这是当前代码我必须读出一个传感器 public static SerialPort serialPort; public static bool PortBusy { get; set; } public static void OpenCOM(string COMPort, in

背景:我有一个项目,需要同时读取多个COM端口。连接到COM端口的是传感器,这些传感器一直在转储数据。我需要从每个传感器收集这些数据。同时连接的传感器数量最多可达5个

这是当前代码我必须读出一个传感器

public static SerialPort serialPort;
        public static bool PortBusy { get; set; }
        
        public static void OpenCOM(string COMPort, int Baudrate)
        {
            if (serialPort == null || !serialPort.IsOpen)
            {                               
                    serialPort = new SerialPort
                    {
                        PortName = COMPort,
                        BaudRate = Baudrate,
                        Parity = Parity.None,
                        StopBits = StopBits.One,
                        DataBits = 8,
                        Handshake = Handshake.None
                    };
                    serialPort.Open();
                    serialPort.WriteLine("N \r");              
            }

        }
        public static double ReadConcentration()
        {
            string[] usableData = FilterData("N");
            string correctData = usableData[1];

            double _Value = Convert.ToDouble(correctData);
            ClearBuffer();
            return _Value;
        }

        public static string[] FilterData(string _filterLetter)
        {
            string inComingData = serialPort.ReadLine();
            int charLoc = 0;
            int serialCharLoc = inComingData.IndexOf("{_filterLetter}");

            while (!(inComingData.Contains("{_filterLetter}")) && !(charLoc == serialCharLoc))
            {
                inComingData = serialPort.ReadLine();
            }
            string[] _usableData = inComingData.Split(' ');
            return _usableData;
        }

        public static void ClearBuffer()
        {
            serialPort.WriteLine("N \n\r");
            serialPort.DiscardInBuffer();
            serialPort.DiscardOutBuffer();
        }


如何修改代码以便能够读取多个传感器。并了解哪个传感器发送什么数据?

您没有显示全部代码:必须在某个地方创建您的
serialPort
实例。我只是假设,还有一个名为
InitializePort()
的方法,在调用任何其他方法之前先调用它。可能是这样的:

public static class SerialPortHandling
{
    private static SerialPort serialPort;

    public static void InitializePort(string portName)
    {
       serialPort = new SerialPort(portName);
       serialPort.Open();
    }


    public static double ReadConcentration()
    {
        // as in your post
    }

    public static string[] FilterData(string _filterLetter)
    {
       // as in your post
    }

    public static void ClearBuffer()
    {
        // as in your post
    }
}
public static class SerialPortHandling
    {
        private static List<SerialPort> serialPort = new List<SerialPort>();
    
        public static void InitializePort(string[] portNames)
        {
           foreach(string portName in PortNames)
           {
                 SerialPort port = new SerialPort(portName));
                 port.Open();
                 serialPorts.Add(port);
           }
        }

        public static double ReadConcentration(string portName)
        {
            string[] usableData = FilterData(portName, "N");
            string correctData = usableData[1];

            double _Value = Convert.ToDouble(correctData);
            ClearBuffer(portName);
            return _Value;
        }

        public static string[] FilterData(string portName, string _filterLetter)
        {
            SerialPort serialPort = serialPorts.FirstOrDefault(p => p.PortName == portName);
            if(serialPort == null)
            {
                throw new ArgumentException($"{portName} is not known");
            }
            string inComingData = serialPort.ReadLine();
            int charLoc = 0;
            int serialCharLoc = inComingData.IndexOf("{_filterLetter}");

            while (!(inComingData.Contains("{_filterLetter}")) && !(charLoc == serialCharLoc))
            {
                inComingData = serialPort.ReadLine();
            }
            string[] _usableData = inComingData.Split(' ');
            return _usableData;
        }

        public static void ClearBuffer(string portName)
        {
            SerialPort serialPort = serialPorts.FirstOrDefault(p => p.PortName == portName);
            if(serialPort == null)
            {
                throw new ArgumentException($"{portName} is not known");
            }
            serialPort.WriteLine("N \n\r");
            serialPort.DiscardInBuffer();
            serialPort.DiscardOutBuffer();
        }
}
如果要使用多个端口,可以将
serialPort
变量替换为端口列表。您的方法如
ReadConcentration()
。。。所有这些都需要一个进一步的参数,在这里您给出了端口的名称。这样,这些方法就可以从列表中选择正确的端口。您的类可能如下所示:

public static class SerialPortHandling
{
    private static SerialPort serialPort;

    public static void InitializePort(string portName)
    {
       serialPort = new SerialPort(portName);
       serialPort.Open();
    }


    public static double ReadConcentration()
    {
        // as in your post
    }

    public static string[] FilterData(string _filterLetter)
    {
       // as in your post
    }

    public static void ClearBuffer()
    {
        // as in your post
    }
}
public static class SerialPortHandling
    {
        private static List<SerialPort> serialPort = new List<SerialPort>();
    
        public static void InitializePort(string[] portNames)
        {
           foreach(string portName in PortNames)
           {
                 SerialPort port = new SerialPort(portName));
                 port.Open();
                 serialPorts.Add(port);
           }
        }

        public static double ReadConcentration(string portName)
        {
            string[] usableData = FilterData(portName, "N");
            string correctData = usableData[1];

            double _Value = Convert.ToDouble(correctData);
            ClearBuffer(portName);
            return _Value;
        }

        public static string[] FilterData(string portName, string _filterLetter)
        {
            SerialPort serialPort = serialPorts.FirstOrDefault(p => p.PortName == portName);
            if(serialPort == null)
            {
                throw new ArgumentException($"{portName} is not known");
            }
            string inComingData = serialPort.ReadLine();
            int charLoc = 0;
            int serialCharLoc = inComingData.IndexOf("{_filterLetter}");

            while (!(inComingData.Contains("{_filterLetter}")) && !(charLoc == serialCharLoc))
            {
                inComingData = serialPort.ReadLine();
            }
            string[] _usableData = inComingData.Split(' ');
            return _usableData;
        }

        public static void ClearBuffer(string portName)
        {
            SerialPort serialPort = serialPorts.FirstOrDefault(p => p.PortName == portName);
            if(serialPort == null)
            {
                throw new ArgumentException($"{portName} is not known");
            }
            serialPort.WriteLine("N \n\r");
            serialPort.DiscardInBuffer();
            serialPort.DiscardOutBuffer();
        }
}
C#中的串行端口类在新数据进入时有一个事件处理程序。您将附加到该方法的第一个参数是
sender
,它表示接收该数据的串行端口。通过将此参数强制转换为
SerialPort
,您可以检查哪个端口发送了数据,并对其执行任意操作


请注意,根据串行端口配置,您还可以获得部分消息,并且您必须组合来自多个
DataReceived
事件的数据才能获得完整消息,但这在很大程度上取决于串行通信的配置方式以及源如何发送数据。

只要使用几个
SerialPort
实例,在所有这些实例都打开的情况下,如何过滤传入数据或使每个com端口都有缓冲区?是的。更多细节请参见我的答案。谢谢!我想这会让我开始的!我看到您正在使用serialPorts.Add,这是否意味着所有端口都同时打开,并在需要时读取传入数据。还是每次都在打开和关闭端口?@Zjwamerjong:在尝试实现此代码后,我遇到了一个问题,您开始使用
serialports.add()
。这里使用术语serialportS。然而,当使用它时,如果没有S,我不会出错,我是否会使用S,我会出错。这段代码也是如此:
SerialPort SerialPort=serialPorts.FirstOrDefault(p=>p.PortName==PortName)这里我也得到了一个serialPorts错误,它说它不存在。我该如何解决这个问题?